summaryrefslogtreecommitdiff
path: root/vendor/k8s.io/client-go/rest
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/k8s.io/client-go/rest')
-rw-r--r--vendor/k8s.io/client-go/rest/OWNERS2
-rw-r--r--vendor/k8s.io/client-go/rest/config.go149
-rw-r--r--vendor/k8s.io/client-go/rest/plugin.go4
-rw-r--r--vendor/k8s.io/client-go/rest/request.go153
-rw-r--r--vendor/k8s.io/client-go/rest/transport.go73
-rw-r--r--vendor/k8s.io/client-go/rest/urlbackoff.go8
-rw-r--r--vendor/k8s.io/client-go/rest/watch/decoder.go2
-rw-r--r--vendor/k8s.io/client-go/rest/zz_generated.deepcopy.go2
8 files changed, 281 insertions, 112 deletions
diff --git a/vendor/k8s.io/client-go/rest/OWNERS b/vendor/k8s.io/client-go/rest/OWNERS
index 8d97da007..49dabc61b 100644
--- a/vendor/k8s.io/client-go/rest/OWNERS
+++ b/vendor/k8s.io/client-go/rest/OWNERS
@@ -1,3 +1,5 @@
+# See the OWNERS docs at https://go.k8s.io/owners
+
reviewers:
- thockin
- smarterclayton
diff --git a/vendor/k8s.io/client-go/rest/config.go b/vendor/k8s.io/client-go/rest/config.go
index 72a78bc0a..c75825ec5 100644
--- a/vendor/k8s.io/client-go/rest/config.go
+++ b/vendor/k8s.io/client-go/rest/config.go
@@ -17,6 +17,8 @@ limitations under the License.
package rest
import (
+ "context"
+ "errors"
"fmt"
"io/ioutil"
"net"
@@ -27,16 +29,15 @@ import (
"strings"
"time"
- "github.com/golang/glog"
-
- "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/client-go/pkg/version"
clientcmdapi "k8s.io/client-go/tools/clientcmd/api"
+ "k8s.io/client-go/transport"
certutil "k8s.io/client-go/util/cert"
"k8s.io/client-go/util/flowcontrol"
+ "k8s.io/klog"
)
const (
@@ -44,6 +45,8 @@ const (
DefaultBurst int = 10
)
+var ErrNotInCluster = errors.New("unable to load in-cluster configuration, KUBERNETES_SERVICE_HOST and KUBERNETES_SERVICE_PORT must be defined")
+
// Config holds the common attributes that can be passed to a Kubernetes client on
// initialization.
type Config struct {
@@ -68,6 +71,11 @@ type Config struct {
// TODO: demonstrate an OAuth2 compatible client.
BearerToken string
+ // Path to a file containing a BearerToken.
+ // If set, the contents are periodically read.
+ // The last successfully read value takes precedence over BearerToken.
+ BearerTokenFile string
+
// Impersonate is the configuration that RESTClient will use for impersonation.
Impersonate ImpersonationConfig
@@ -88,13 +96,16 @@ type Config struct {
// Transport may be used for custom HTTP behavior. This attribute may not
// be specified with the TLS client certificate options. Use WrapTransport
- // for most client level operations.
+ // to provide additional per-server middleware behavior.
Transport http.RoundTripper
// WrapTransport will be invoked for custom HTTP behavior after the underlying
// transport is initialized (either the transport created from TLSClientConfig,
// Transport, or http.DefaultTransport). The config may layer other RoundTrippers
// on top of the returned RoundTripper.
- WrapTransport func(rt http.RoundTripper) http.RoundTripper
+ //
+ // A future release will change this field to an array. Use config.Wrap()
+ // instead of setting this value directly.
+ WrapTransport transport.WrapperFunc
// QPS indicates the maximum QPS to the master from this client.
// If it's zero, the created RESTClient will use DefaultQPS: 5
@@ -111,13 +122,54 @@ type Config struct {
Timeout time.Duration
// Dial specifies the dial function for creating unencrypted TCP connections.
- Dial func(network, addr string) (net.Conn, error)
+ Dial func(ctx context.Context, network, address string) (net.Conn, error)
// Version forces a specific version to be used (if registered)
// Do we need this?
// Version string
}
+var _ fmt.Stringer = new(Config)
+var _ fmt.GoStringer = new(Config)
+
+type sanitizedConfig *Config
+
+type sanitizedAuthConfigPersister struct{ AuthProviderConfigPersister }
+
+func (sanitizedAuthConfigPersister) GoString() string {
+ return "rest.AuthProviderConfigPersister(--- REDACTED ---)"
+}
+func (sanitizedAuthConfigPersister) String() string {
+ return "rest.AuthProviderConfigPersister(--- REDACTED ---)"
+}
+
+// GoString implements fmt.GoStringer and sanitizes sensitive fields of Config
+// to prevent accidental leaking via logs.
+func (c *Config) GoString() string {
+ return c.String()
+}
+
+// String implements fmt.Stringer and sanitizes sensitive fields of Config to
+// prevent accidental leaking via logs.
+func (c *Config) String() string {
+ if c == nil {
+ return "<nil>"
+ }
+ cc := sanitizedConfig(CopyConfig(c))
+ // Explicitly mark non-empty credential fields as redacted.
+ if cc.Password != "" {
+ cc.Password = "--- REDACTED ---"
+ }
+ if cc.BearerToken != "" {
+ cc.BearerToken = "--- REDACTED ---"
+ }
+ if cc.AuthConfigPersister != nil {
+ cc.AuthConfigPersister = sanitizedAuthConfigPersister{cc.AuthConfigPersister}
+ }
+
+ return fmt.Sprintf("%#v", cc)
+}
+
// ImpersonationConfig has all the available impersonation options
type ImpersonationConfig struct {
// UserName is the username to impersonate on each request.
@@ -157,6 +209,40 @@ type TLSClientConfig struct {
CAData []byte
}
+var _ fmt.Stringer = TLSClientConfig{}
+var _ fmt.GoStringer = TLSClientConfig{}
+
+type sanitizedTLSClientConfig TLSClientConfig
+
+// GoString implements fmt.GoStringer and sanitizes sensitive fields of
+// TLSClientConfig to prevent accidental leaking via logs.
+func (c TLSClientConfig) GoString() string {
+ return c.String()
+}
+
+// String implements fmt.Stringer and sanitizes sensitive fields of
+// TLSClientConfig to prevent accidental leaking via logs.
+func (c TLSClientConfig) String() string {
+ cc := sanitizedTLSClientConfig{
+ Insecure: c.Insecure,
+ ServerName: c.ServerName,
+ CertFile: c.CertFile,
+ KeyFile: c.KeyFile,
+ CAFile: c.CAFile,
+ CertData: c.CertData,
+ KeyData: c.KeyData,
+ CAData: c.CAData,
+ }
+ // Explicitly mark non-empty credential fields as redacted.
+ if len(cc.CertData) != 0 {
+ cc.CertData = []byte("--- TRUNCATED ---")
+ }
+ if len(cc.KeyData) != 0 {
+ cc.KeyData = []byte("--- REDACTED ---")
+ }
+ return fmt.Sprintf("%#v", cc)
+}
+
type ContentConfig struct {
// AcceptContentTypes specifies the types the client will accept and is optional.
// If not set, ContentType will be used to define the Accept header
@@ -220,7 +306,7 @@ func RESTClientFor(config *Config) (*RESTClient, error) {
// the config.Version to be empty.
func UnversionedRESTClientFor(config *Config) (*RESTClient, error) {
if config.NegotiatedSerializer == nil {
- return nil, fmt.Errorf("NeogitatedSerializer is required when initializing a RESTClient")
+ return nil, fmt.Errorf("NegotiatedSerializer is required when initializing a RESTClient")
}
baseURL, versionedAPIPath, err := defaultServerUrlFor(config)
@@ -308,22 +394,27 @@ func DefaultKubernetesUserAgent() string {
// InClusterConfig returns a config object which uses the service account
// kubernetes gives to pods. It's intended for clients that expect to be
-// running inside a pod running on kubernetes. It will return an error if
-// called from a process not running in a kubernetes environment.
+// running inside a pod running on kubernetes. It will return ErrNotInCluster
+// if called from a process not running in a kubernetes environment.
func InClusterConfig() (*Config, error) {
+ const (
+ tokenFile = "/var/run/secrets/kubernetes.io/serviceaccount/token"
+ rootCAFile = "/var/run/secrets/kubernetes.io/serviceaccount/ca.crt"
+ )
host, port := os.Getenv("KUBERNETES_SERVICE_HOST"), os.Getenv("KUBERNETES_SERVICE_PORT")
if len(host) == 0 || len(port) == 0 {
- return nil, fmt.Errorf("unable to load in-cluster configuration, KUBERNETES_SERVICE_HOST and KUBERNETES_SERVICE_PORT must be defined")
+ return nil, ErrNotInCluster
}
- token, err := ioutil.ReadFile("/var/run/secrets/kubernetes.io/serviceaccount/" + v1.ServiceAccountTokenKey)
+ token, err := ioutil.ReadFile(tokenFile)
if err != nil {
return nil, err
}
+
tlsClientConfig := TLSClientConfig{}
- rootCAFile := "/var/run/secrets/kubernetes.io/serviceaccount/" + v1.ServiceAccountRootCAKey
+
if _, err := certutil.NewPool(rootCAFile); err != nil {
- glog.Errorf("Expected to load root CA config from %s, but got err: %v", rootCAFile, err)
+ klog.Errorf("Expected to load root CA config from %s, but got err: %v", rootCAFile, err)
} else {
tlsClientConfig.CAFile = rootCAFile
}
@@ -331,8 +422,9 @@ func InClusterConfig() (*Config, error) {
return &Config{
// TODO: switch to using cluster DNS.
Host: "https://" + net.JoinHostPort(host, port),
- BearerToken: string(token),
TLSClientConfig: tlsClientConfig,
+ BearerToken: string(token),
+ BearerTokenFile: tokenFile,
}, nil
}
@@ -395,7 +487,7 @@ func AddUserAgent(config *Config, userAgent string) *Config {
return config
}
-// AnonymousClientConfig returns a copy of the given config with all user credentials (cert/key, bearer token, and username/password) removed
+// AnonymousClientConfig returns a copy of the given config with all user credentials (cert/key, bearer token, and username/password) and custom transports (WrapTransport, Transport) removed
func AnonymousClientConfig(config *Config) *Config {
// copy only known safe fields
return &Config{
@@ -408,26 +500,25 @@ func AnonymousClientConfig(config *Config) *Config {
CAFile: config.TLSClientConfig.CAFile,
CAData: config.TLSClientConfig.CAData,
},
- RateLimiter: config.RateLimiter,
- UserAgent: config.UserAgent,
- Transport: config.Transport,
- WrapTransport: config.WrapTransport,
- QPS: config.QPS,
- Burst: config.Burst,
- Timeout: config.Timeout,
- Dial: config.Dial,
+ RateLimiter: config.RateLimiter,
+ UserAgent: config.UserAgent,
+ QPS: config.QPS,
+ Burst: config.Burst,
+ Timeout: config.Timeout,
+ Dial: config.Dial,
}
}
// CopyConfig returns a copy of the given config
func CopyConfig(config *Config) *Config {
return &Config{
- Host: config.Host,
- APIPath: config.APIPath,
- ContentConfig: config.ContentConfig,
- Username: config.Username,
- Password: config.Password,
- BearerToken: config.BearerToken,
+ Host: config.Host,
+ APIPath: config.APIPath,
+ ContentConfig: config.ContentConfig,
+ Username: config.Username,
+ Password: config.Password,
+ BearerToken: config.BearerToken,
+ BearerTokenFile: config.BearerTokenFile,
Impersonate: ImpersonationConfig{
Groups: config.Impersonate.Groups,
Extra: config.Impersonate.Extra,
diff --git a/vendor/k8s.io/client-go/rest/plugin.go b/vendor/k8s.io/client-go/rest/plugin.go
index cf8fbabfd..83ef5ae32 100644
--- a/vendor/k8s.io/client-go/rest/plugin.go
+++ b/vendor/k8s.io/client-go/rest/plugin.go
@@ -21,7 +21,7 @@ import (
"net/http"
"sync"
- "github.com/golang/glog"
+ "k8s.io/klog"
clientcmdapi "k8s.io/client-go/tools/clientcmd/api"
)
@@ -57,7 +57,7 @@ func RegisterAuthProviderPlugin(name string, plugin Factory) error {
if _, found := plugins[name]; found {
return fmt.Errorf("Auth Provider Plugin %q was registered twice", name)
}
- glog.V(4).Infof("Registered Auth Provider Plugin %q", name)
+ klog.V(4).Infof("Registered Auth Provider Plugin %q", name)
plugins[name] = plugin
return nil
}
diff --git a/vendor/k8s.io/client-go/rest/request.go b/vendor/k8s.io/client-go/rest/request.go
index 6ca9e0197..0570615fc 100644
--- a/vendor/k8s.io/client-go/rest/request.go
+++ b/vendor/k8s.io/client-go/rest/request.go
@@ -32,7 +32,6 @@ import (
"strings"
"time"
- "github.com/golang/glog"
"golang.org/x/net/http2"
"k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -44,6 +43,7 @@ import (
restclientwatch "k8s.io/client-go/rest/watch"
"k8s.io/client-go/tools/metrics"
"k8s.io/client-go/util/flowcontrol"
+ "k8s.io/klog"
)
var (
@@ -114,7 +114,7 @@ type Request struct {
// NewRequest creates a new request helper object for accessing runtime.Objects on a server.
func NewRequest(client HTTPClient, verb string, baseURL *url.URL, versionedAPIPath string, content ContentConfig, serializers Serializers, backoff BackoffManager, throttle flowcontrol.RateLimiter, timeout time.Duration) *Request {
if backoff == nil {
- glog.V(2).Infof("Not implementing request backoff strategy.")
+ klog.V(2).Infof("Not implementing request backoff strategy.")
backoff = &NoBackoff{}
}
@@ -198,7 +198,7 @@ func (r *Request) Throttle(limiter flowcontrol.RateLimiter) *Request {
return r
}
-// SubResource sets a sub-resource path which can be multiple segments segment after the resource
+// SubResource sets a sub-resource path which can be multiple segments after the resource
// name but before the suffix.
func (r *Request) SubResource(subresources ...string) *Request {
if r.err != nil {
@@ -317,10 +317,14 @@ func (r *Request) Param(paramName, s string) *Request {
// VersionedParams will not write query parameters that have omitempty set and are empty. If a
// parameter has already been set it is appended to (Params and VersionedParams are additive).
func (r *Request) VersionedParams(obj runtime.Object, codec runtime.ParameterCodec) *Request {
+ return r.SpecificallyVersionedParams(obj, codec, *r.content.GroupVersion)
+}
+
+func (r *Request) SpecificallyVersionedParams(obj runtime.Object, codec runtime.ParameterCodec, version schema.GroupVersion) *Request {
if r.err != nil {
return r
}
- params, err := codec.EncodeParameters(obj, *r.content.GroupVersion)
+ params, err := codec.EncodeParameters(obj, version)
if err != nil {
r.err = err
return r
@@ -353,8 +357,8 @@ func (r *Request) SetHeader(key string, values ...string) *Request {
return r
}
-// Timeout makes the request use the given duration as a timeout. Sets the "timeout"
-// parameter.
+// Timeout makes the request use the given duration as an overall timeout for the
+// request. Additionally, if set passes the value as "timeout" parameter in URL.
func (r *Request) Timeout(d time.Duration) *Request {
if r.err != nil {
return r
@@ -451,17 +455,9 @@ func (r *Request) URL() *url.URL {
// finalURLTemplate is similar to URL(), but will make all specific parameter values equal
// - instead of name or namespace, "{name}" and "{namespace}" will be used, and all query
-// parameters will be reset. This creates a copy of the request so as not to change the
-// underlying object. This means some useful request info (like the types of field
-// selectors in use) will be lost.
-// TODO: preserve field selector keys
+// parameters will be reset. This creates a copy of the url so as not to change the
+// underlying object.
func (r Request) finalURLTemplate() url.URL {
- if len(r.resourceName) != 0 {
- r.resourceName = "{name}"
- }
- if r.namespaceSet && len(r.namespace) != 0 {
- r.namespace = "{namespace}"
- }
newParams := url.Values{}
v := []string{"{value}"}
for k := range r.params {
@@ -469,6 +465,59 @@ func (r Request) finalURLTemplate() url.URL {
}
r.params = newParams
url := r.URL()
+ segments := strings.Split(r.URL().Path, "/")
+ groupIndex := 0
+ index := 0
+ if r.URL() != nil && r.baseURL != nil && strings.Contains(r.URL().Path, r.baseURL.Path) {
+ groupIndex += len(strings.Split(r.baseURL.Path, "/"))
+ }
+ if groupIndex >= len(segments) {
+ return *url
+ }
+
+ const CoreGroupPrefix = "api"
+ const NamedGroupPrefix = "apis"
+ isCoreGroup := segments[groupIndex] == CoreGroupPrefix
+ isNamedGroup := segments[groupIndex] == NamedGroupPrefix
+ if isCoreGroup {
+ // checking the case of core group with /api/v1/... format
+ index = groupIndex + 2
+ } else if isNamedGroup {
+ // checking the case of named group with /apis/apps/v1/... format
+ index = groupIndex + 3
+ } else {
+ // this should not happen that the only two possibilities are /api... and /apis..., just want to put an
+ // outlet here in case more API groups are added in future if ever possible:
+ // https://kubernetes.io/docs/concepts/overview/kubernetes-api/#api-groups
+ // if a wrong API groups name is encountered, return the {prefix} for url.Path
+ url.Path = "/{prefix}"
+ url.RawQuery = ""
+ return *url
+ }
+ //switch segLength := len(segments) - index; segLength {
+ switch {
+ // case len(segments) - index == 1:
+ // resource (with no name) do nothing
+ case len(segments)-index == 2:
+ // /$RESOURCE/$NAME: replace $NAME with {name}
+ segments[index+1] = "{name}"
+ case len(segments)-index == 3:
+ if segments[index+2] == "finalize" || segments[index+2] == "status" {
+ // /$RESOURCE/$NAME/$SUBRESOURCE: replace $NAME with {name}
+ segments[index+1] = "{name}"
+ } else {
+ // /namespace/$NAMESPACE/$RESOURCE: replace $NAMESPACE with {namespace}
+ segments[index+1] = "{namespace}"
+ }
+ case len(segments)-index >= 4:
+ segments[index+1] = "{namespace}"
+ // /namespace/$NAMESPACE/$RESOURCE/$NAME: replace $NAMESPACE with {namespace}, $NAME with {name}
+ if segments[index+3] != "finalize" && segments[index+3] != "status" {
+ // /$RESOURCE/$NAME/$SUBRESOURCE: replace $NAME with {name}
+ segments[index+3] = "{name}"
+ }
+ }
+ url.Path = path.Join(segments...)
return *url
}
@@ -478,13 +527,26 @@ func (r *Request) tryThrottle() {
r.throttle.Accept()
}
if latency := time.Since(now); latency > longThrottleLatency {
- glog.V(4).Infof("Throttling request took %v, request: %s:%s", latency, r.verb, r.URL().String())
+ klog.V(4).Infof("Throttling request took %v, request: %s:%s", latency, r.verb, r.URL().String())
}
}
// Watch attempts to begin watching the requested location.
// Returns a watch.Interface, or an error.
func (r *Request) Watch() (watch.Interface, error) {
+ return r.WatchWithSpecificDecoders(
+ func(body io.ReadCloser) streaming.Decoder {
+ framer := r.serializers.Framer.NewFrameReader(body)
+ return streaming.NewDecoder(framer, r.serializers.StreamingSerializer)
+ },
+ r.serializers.Decoder,
+ )
+}
+
+// WatchWithSpecificDecoders attempts to begin watching the requested location with a *different* decoder.
+// Turns out that you want one "standard" decoder for the watch event and one "personal" decoder for the content
+// Returns a watch.Interface, or an error.
+func (r *Request) WatchWithSpecificDecoders(wrapperDecoderFn func(io.ReadCloser) streaming.Decoder, embeddedDecoder runtime.Decoder) (watch.Interface, error) {
// We specifically don't want to rate limit watches, so we
// don't use r.throttle here.
if r.err != nil {
@@ -530,11 +592,15 @@ func (r *Request) Watch() (watch.Interface, error) {
if result := r.transformResponse(resp, req); result.err != nil {
return nil, result.err
}
- return nil, fmt.Errorf("for request '%+v', got status: %v", url, resp.StatusCode)
- }
- framer := r.serializers.Framer.NewFrameReader(resp.Body)
- decoder := streaming.NewDecoder(framer, r.serializers.StreamingSerializer)
- return watch.NewStreamWatcher(restclientwatch.NewDecoder(decoder, r.serializers.Decoder)), nil
+ return nil, fmt.Errorf("for request %s, got status: %v", url, resp.StatusCode)
+ }
+ wrapperDecoder := wrapperDecoderFn(resp.Body)
+ return watch.NewStreamWatcher(
+ restclientwatch.NewDecoder(wrapperDecoder, embeddedDecoder),
+ // use 500 to indicate that the cause of the error is unknown - other error codes
+ // are more specific to HTTP interactions, and set a reason
+ errors.NewClientErrorReporter(http.StatusInternalServerError, r.verb, "ClientWatchDecoding"),
+ ), nil
}
// updateURLMetrics is a convenience function for pushing metrics.
@@ -622,7 +688,7 @@ func (r *Request) request(fn func(*http.Request, *http.Response)) error {
}()
if r.err != nil {
- glog.V(4).Infof("Error in request: %v", r.err)
+ klog.V(4).Infof("Error in request: %v", r.err)
return r.err
}
@@ -640,7 +706,6 @@ func (r *Request) request(fn func(*http.Request, *http.Response)) error {
}
// Right now we make about ten retry attempts if we get a Retry-After response.
- // TODO: Change to a timeout based approach.
maxRetries := 10
retries := 0
for {
@@ -649,6 +714,14 @@ func (r *Request) request(fn func(*http.Request, *http.Response)) error {
if err != nil {
return err
}
+ if r.timeout > 0 {
+ if r.ctx == nil {
+ r.ctx = context.Background()
+ }
+ var cancelFn context.CancelFunc
+ r.ctx, cancelFn = context.WithTimeout(r.ctx, r.timeout)
+ defer cancelFn()
+ }
if r.ctx != nil {
req = req.WithContext(r.ctx)
}
@@ -702,13 +775,13 @@ func (r *Request) request(fn func(*http.Request, *http.Response)) error {
if seeker, ok := r.body.(io.Seeker); ok && r.body != nil {
_, err := seeker.Seek(0, 0)
if err != nil {
- glog.V(4).Infof("Could not retry request, can't Seek() back to beginning of body for %T", r.body)
+ klog.V(4).Infof("Could not retry request, can't Seek() back to beginning of body for %T", r.body)
fn(req, resp)
return true
}
}
- glog.V(4).Infof("Got a Retry-After %s response for attempt %d to %v", seconds, retries, url)
+ klog.V(4).Infof("Got a Retry-After %ds response for attempt %d to %v", seconds, retries, url)
r.backoffMgr.Sleep(time.Duration(seconds) * time.Second)
return false
}
@@ -776,14 +849,14 @@ func (r *Request) transformResponse(resp *http.Response, req *http.Request) Resu
// 2. Apiserver sends back the headers and then part of the body
// 3. Apiserver closes connection.
// 4. client-go should catch this and return an error.
- glog.V(2).Infof("Stream error %#v when reading response body, may be caused by closed connection.", err)
- streamErr := fmt.Errorf("Stream error %#v when reading response body, may be caused by closed connection. Please retry.", err)
+ klog.V(2).Infof("Stream error %#v when reading response body, may be caused by closed connection.", err)
+ streamErr := fmt.Errorf("Stream error when reading response body, may be caused by closed connection. Please retry. Original error: %v", err)
return Result{
err: streamErr,
}
default:
- glog.Errorf("Unexpected error when reading response body: %#v", err)
- unexpectedErr := fmt.Errorf("Unexpected error %#v when reading response body. Please retry.", err)
+ klog.Errorf("Unexpected error when reading response body: %v", err)
+ unexpectedErr := fmt.Errorf("Unexpected error when reading response body. Please retry. Original error: %v", err)
return Result{
err: unexpectedErr,
}
@@ -846,11 +919,11 @@ func (r *Request) transformResponse(resp *http.Response, req *http.Request) Resu
func truncateBody(body string) string {
max := 0
switch {
- case bool(glog.V(10)):
+ case bool(klog.V(10)):
return body
- case bool(glog.V(9)):
+ case bool(klog.V(9)):
max = 10240
- case bool(glog.V(8)):
+ case bool(klog.V(8)):
max = 1024
}
@@ -865,13 +938,13 @@ func truncateBody(body string) string {
// allocating a new string for the body output unless necessary. Uses a simple heuristic to determine
// whether the body is printable.
func glogBody(prefix string, body []byte) {
- if glog.V(8) {
+ if klog.V(8) {
if bytes.IndexFunc(body, func(r rune) bool {
return r < 0x0a
}) != -1 {
- glog.Infof("%s:\n%s", prefix, truncateBody(hex.Dump(body)))
+ klog.Infof("%s:\n%s", prefix, truncateBody(hex.Dump(body)))
} else {
- glog.Infof("%s: %s", prefix, truncateBody(string(body)))
+ klog.Infof("%s: %s", prefix, truncateBody(string(body)))
}
}
}
@@ -1032,7 +1105,8 @@ func (r Result) Into(obj runtime.Object) error {
return fmt.Errorf("serializer for %s doesn't exist", r.contentType)
}
if len(r.body) == 0 {
- return fmt.Errorf("0-length response")
+ return fmt.Errorf("0-length response with status code: %d and content type: %s",
+ r.statusCode, r.contentType)
}
out, _, err := r.decoder.Decode(r.body, nil, obj)
@@ -1073,7 +1147,7 @@ func (r Result) Error() error {
// to be backwards compatible with old servers that do not return a version, default to "v1"
out, _, err := r.decoder.Decode(r.body, &schema.GroupVersionKind{Version: "v1"}, nil)
if err != nil {
- glog.V(5).Infof("body was not decodable (unable to check for Status): %v", err)
+ klog.V(5).Infof("body was not decodable (unable to check for Status): %v", err)
return r.err
}
switch t := out.(type) {
@@ -1127,7 +1201,6 @@ func IsValidPathSegmentPrefix(name string) []string {
func ValidatePathSegmentName(name string, prefix bool) []string {
if prefix {
return IsValidPathSegmentPrefix(name)
- } else {
- return IsValidPathSegmentName(name)
}
+ return IsValidPathSegmentName(name)
}
diff --git a/vendor/k8s.io/client-go/rest/transport.go b/vendor/k8s.io/client-go/rest/transport.go
index b6a067632..de33ecbfc 100644
--- a/vendor/k8s.io/client-go/rest/transport.go
+++ b/vendor/k8s.io/client-go/rest/transport.go
@@ -18,6 +18,7 @@ package rest
import (
"crypto/tls"
+ "errors"
"net/http"
"k8s.io/client-go/plugin/pkg/client/auth/exec"
@@ -59,39 +60,10 @@ func HTTPWrappersForConfig(config *Config, rt http.RoundTripper) (http.RoundTrip
// TransportConfig converts a client config to an appropriate transport config.
func (c *Config) TransportConfig() (*transport.Config, error) {
- wt := c.WrapTransport
- if c.ExecProvider != nil {
- provider, err := exec.GetAuthenticator(c.ExecProvider)
- if err != nil {
- return nil, err
- }
- if wt != nil {
- previousWT := wt
- wt = func(rt http.RoundTripper) http.RoundTripper {
- return provider.WrapTransport(previousWT(rt))
- }
- } else {
- wt = provider.WrapTransport
- }
- }
- if c.AuthProvider != nil {
- provider, err := GetAuthProvider(c.Host, c.AuthProvider, c.AuthConfigPersister)
- if err != nil {
- return nil, err
- }
- if wt != nil {
- previousWT := wt
- wt = func(rt http.RoundTripper) http.RoundTripper {
- return provider.WrapTransport(previousWT(rt))
- }
- } else {
- wt = provider.WrapTransport
- }
- }
- return &transport.Config{
+ conf := &transport.Config{
UserAgent: c.UserAgent,
Transport: c.Transport,
- WrapTransport: wt,
+ WrapTransport: c.WrapTransport,
TLS: transport.TLSConfig{
Insecure: c.Insecure,
ServerName: c.ServerName,
@@ -102,14 +74,45 @@ func (c *Config) TransportConfig() (*transport.Config, error) {
KeyFile: c.KeyFile,
KeyData: c.KeyData,
},
- Username: c.Username,
- Password: c.Password,
- BearerToken: c.BearerToken,
+ Username: c.Username,
+ Password: c.Password,
+ BearerToken: c.BearerToken,
+ BearerTokenFile: c.BearerTokenFile,
Impersonate: transport.ImpersonationConfig{
UserName: c.Impersonate.UserName,
Groups: c.Impersonate.Groups,
Extra: c.Impersonate.Extra,
},
Dial: c.Dial,
- }, nil
+ }
+
+ if c.ExecProvider != nil && c.AuthProvider != nil {
+ return nil, errors.New("execProvider and authProvider cannot be used in combination")
+ }
+
+ if c.ExecProvider != nil {
+ provider, err := exec.GetAuthenticator(c.ExecProvider)
+ if err != nil {
+ return nil, err
+ }
+ if err := provider.UpdateTransportConfig(conf); err != nil {
+ return nil, err
+ }
+ }
+ if c.AuthProvider != nil {
+ provider, err := GetAuthProvider(c.Host, c.AuthProvider, c.AuthConfigPersister)
+ if err != nil {
+ return nil, err
+ }
+ conf.Wrap(provider.WrapTransport)
+ }
+ return conf, nil
+}
+
+// Wrap adds a transport middleware function that will give the caller
+// an opportunity to wrap the underlying http.RoundTripper prior to the
+// first API call being made. The provided function is invoked after any
+// existing transport wrappers are invoked.
+func (c *Config) Wrap(fn transport.WrapperFunc) {
+ c.WrapTransport = transport.Wrappers(c.WrapTransport, fn)
}
diff --git a/vendor/k8s.io/client-go/rest/urlbackoff.go b/vendor/k8s.io/client-go/rest/urlbackoff.go
index eff848abc..d00e42f86 100644
--- a/vendor/k8s.io/client-go/rest/urlbackoff.go
+++ b/vendor/k8s.io/client-go/rest/urlbackoff.go
@@ -20,9 +20,9 @@ import (
"net/url"
"time"
- "github.com/golang/glog"
"k8s.io/apimachinery/pkg/util/sets"
"k8s.io/client-go/util/flowcontrol"
+ "k8s.io/klog"
)
// Set of resp. Codes that we backoff for.
@@ -64,7 +64,7 @@ func (n *NoBackoff) Sleep(d time.Duration) {
// Disable makes the backoff trivial, i.e., sets it to zero. This might be used
// by tests which want to run 1000s of mock requests without slowing down.
func (b *URLBackoff) Disable() {
- glog.V(4).Infof("Disabling backoff strategy")
+ klog.V(4).Infof("Disabling backoff strategy")
b.Backoff = flowcontrol.NewBackOff(0*time.Second, 0*time.Second)
}
@@ -76,7 +76,7 @@ func (b *URLBackoff) baseUrlKey(rawurl *url.URL) string {
// in the future.
host, err := url.Parse(rawurl.String())
if err != nil {
- glog.V(4).Infof("Error extracting url: %v", rawurl)
+ klog.V(4).Infof("Error extracting url: %v", rawurl)
panic("bad url!")
}
return host.Host
@@ -89,7 +89,7 @@ func (b *URLBackoff) UpdateBackoff(actualUrl *url.URL, err error, responseCode i
b.Backoff.Next(b.baseUrlKey(actualUrl), b.Backoff.Clock.Now())
return
} else if responseCode >= 300 || err != nil {
- glog.V(4).Infof("Client is returning errors: code %v, error %v", responseCode, err)
+ klog.V(4).Infof("Client is returning errors: code %v, error %v", responseCode, err)
}
//If we got this far, there is no backoff required for this URL anymore.
diff --git a/vendor/k8s.io/client-go/rest/watch/decoder.go b/vendor/k8s.io/client-go/rest/watch/decoder.go
index 73bb63add..e95c020b2 100644
--- a/vendor/k8s.io/client-go/rest/watch/decoder.go
+++ b/vendor/k8s.io/client-go/rest/watch/decoder.go
@@ -54,7 +54,7 @@ func (d *Decoder) Decode() (watch.EventType, runtime.Object, error) {
return "", nil, fmt.Errorf("unable to decode to metav1.Event")
}
switch got.Type {
- case string(watch.Added), string(watch.Modified), string(watch.Deleted), string(watch.Error):
+ case string(watch.Added), string(watch.Modified), string(watch.Deleted), string(watch.Error), string(watch.Bookmark):
default:
return "", nil, fmt.Errorf("got invalid watch event type: %v", got.Type)
}
diff --git a/vendor/k8s.io/client-go/rest/zz_generated.deepcopy.go b/vendor/k8s.io/client-go/rest/zz_generated.deepcopy.go
index 67568bf0b..c1ab45f33 100644
--- a/vendor/k8s.io/client-go/rest/zz_generated.deepcopy.go
+++ b/vendor/k8s.io/client-go/rest/zz_generated.deepcopy.go
@@ -1,7 +1,7 @@
// +build !ignore_autogenerated
/*
-Copyright 2018 The Kubernetes Authors.
+Copyright The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.