vendor: update kubernetes v1.19.0-rc.4
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This commit is contained in:
16
vendor/k8s.io/client-go/README.md
generated
vendored
16
vendor/k8s.io/client-go/README.md
generated
vendored
@@ -82,12 +82,13 @@ We will backport bugfixes--but not new features--into older versions of
|
||||
|
||||
#### Compatibility matrix
|
||||
|
||||
| | Kubernetes 1.15 | Kubernetes 1.16 | Kubernetes 1.17 |
|
||||
|-------------------------------|-----------------|-----------------|-----------------|
|
||||
| `kubernetes-1.15.0` | ✓ | +- | +- |
|
||||
| `kubernetes-1.16.0` | +- | ✓ | +- |
|
||||
| `kubernetes-1.17.0`/`v0.17.0` | +- | +- | ✓ |
|
||||
| `HEAD` | +- | +- | +- |
|
||||
| | Kubernetes 1.15 | Kubernetes 1.16 | Kubernetes 1.17 | Kubernetes 1.18 |
|
||||
|-------------------------------|-----------------|-----------------|-----------------|-----------------|
|
||||
| `kubernetes-1.15.0` | ✓ | +- | +- | +- |
|
||||
| `kubernetes-1.16.0` | +- | ✓ | +- | +- |
|
||||
| `kubernetes-1.17.0`/`v0.17.0` | +- | +- | ✓ | +- |
|
||||
| `kubernetes-1.18.0`/`v0.18.0` | +- | +- | +- | ✓ |
|
||||
| `HEAD` | +- | +- | +- | +- |
|
||||
|
||||
Key:
|
||||
|
||||
@@ -119,10 +120,11 @@ between client-go versions.
|
||||
| `release-8.0` | Kubernetes main repo, 1.11 branch | =- |
|
||||
| `release-9.0` | Kubernetes main repo, 1.12 branch | =- |
|
||||
| `release-10.0` | Kubernetes main repo, 1.13 branch | =- |
|
||||
| `release-11.0` | Kubernetes main repo, 1.14 branch | ✓ |
|
||||
| `release-11.0` | Kubernetes main repo, 1.14 branch | =- |
|
||||
| `release-12.0` | Kubernetes main repo, 1.15 branch | ✓ |
|
||||
| `release-13.0` | Kubernetes main repo, 1.16 branch | ✓ |
|
||||
| `release-14.0` | Kubernetes main repo, 1.17 branch | ✓ |
|
||||
| `release-1.18` | Kubernetes main repo, 1.18 branch | ✓ |
|
||||
| client-go HEAD | Kubernetes main repo, master branch | ✓ |
|
||||
|
||||
Key:
|
||||
|
||||
22
vendor/k8s.io/client-go/go.mod
generated
vendored
22
vendor/k8s.io/client-go/go.mod
generated
vendored
@@ -2,14 +2,14 @@
|
||||
|
||||
module k8s.io/client-go
|
||||
|
||||
go 1.13
|
||||
go 1.15
|
||||
|
||||
require (
|
||||
cloud.google.com/go v0.51.0 // indirect
|
||||
github.com/Azure/go-autorest/autorest v0.9.6
|
||||
github.com/Azure/go-autorest/autorest/adal v0.8.2
|
||||
github.com/davecgh/go-spew v1.1.1
|
||||
github.com/evanphx/json-patch v4.2.0+incompatible
|
||||
github.com/evanphx/json-patch v0.0.0-20190815234213-e83c0a1c26c8
|
||||
github.com/gogo/protobuf v1.3.1
|
||||
github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7
|
||||
github.com/golang/protobuf v1.4.2
|
||||
@@ -22,20 +22,18 @@ require (
|
||||
github.com/peterbourgon/diskv v2.0.1+incompatible
|
||||
github.com/spf13/pflag v1.0.5
|
||||
github.com/stretchr/testify v1.4.0
|
||||
golang.org/x/crypto v0.0.0-20200220183623-bac4c82f6975
|
||||
golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9
|
||||
golang.org/x/net v0.0.0-20200707034311-ab3426394381
|
||||
golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6
|
||||
golang.org/x/time v0.0.0-20191024005414-555d28b269f0
|
||||
k8s.io/api v0.19.0-beta.2
|
||||
k8s.io/apimachinery v0.19.0-beta.2
|
||||
k8s.io/klog/v2 v2.1.0
|
||||
k8s.io/utils v0.0.0-20200414100711-2df71ebbae66
|
||||
k8s.io/api v0.19.0-rc.4
|
||||
k8s.io/apimachinery v0.19.0-rc.4
|
||||
k8s.io/klog/v2 v2.2.0
|
||||
k8s.io/utils v0.0.0-20200729134348-d5654de09c73
|
||||
sigs.k8s.io/yaml v1.2.0
|
||||
)
|
||||
|
||||
replace (
|
||||
golang.org/x/sys => golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a // pinned to release-branch.go1.13
|
||||
golang.org/x/tools => golang.org/x/tools v0.0.0-20190821162956-65e3620a7ae7 // pinned to release-branch.go1.13
|
||||
k8s.io/api => k8s.io/api v0.19.0-beta.2
|
||||
k8s.io/apimachinery => k8s.io/apimachinery v0.19.0-beta.2
|
||||
k8s.io/api => k8s.io/api v0.19.0-rc.4
|
||||
k8s.io/apimachinery => k8s.io/apimachinery v0.19.0-rc.4
|
||||
)
|
||||
|
||||
102
vendor/k8s.io/client-go/plugin/pkg/client/auth/exec/exec.go
generated
vendored
102
vendor/k8s.io/client-go/plugin/pkg/client/auth/exec/exec.go
generated
vendored
@@ -29,6 +29,7 @@ import (
|
||||
"os"
|
||||
"os/exec"
|
||||
"reflect"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
@@ -38,6 +39,7 @@ import (
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/apimachinery/pkg/runtime/serializer"
|
||||
"k8s.io/apimachinery/pkg/util/clock"
|
||||
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
|
||||
"k8s.io/client-go/pkg/apis/clientauthentication"
|
||||
"k8s.io/client-go/pkg/apis/clientauthentication/v1alpha1"
|
||||
@@ -51,6 +53,12 @@ import (
|
||||
|
||||
const execInfoEnv = "KUBERNETES_EXEC_INFO"
|
||||
const onRotateListWarningLength = 1000
|
||||
const installHintVerboseHelp = `
|
||||
|
||||
It looks like you are trying to use a client-go credential plugin that is not installed.
|
||||
|
||||
To learn more about this feature, consult the documentation available at:
|
||||
https://kubernetes.io/docs/reference/access-authn-authz/authentication/#client-go-credential-plugins`
|
||||
|
||||
var scheme = runtime.NewScheme()
|
||||
var codecs = serializer.NewCodecFactory(scheme)
|
||||
@@ -108,6 +116,44 @@ func (c *cache) put(s string, a *Authenticator) *Authenticator {
|
||||
return a
|
||||
}
|
||||
|
||||
// sometimes rate limits how often a function f() is called. Specifically, Do()
|
||||
// will run the provided function f() up to threshold times every interval
|
||||
// duration.
|
||||
type sometimes struct {
|
||||
threshold int
|
||||
interval time.Duration
|
||||
|
||||
clock clock.Clock
|
||||
mu sync.Mutex
|
||||
|
||||
count int // times we have called f() in this window
|
||||
window time.Time // beginning of current window of length interval
|
||||
}
|
||||
|
||||
func (s *sometimes) Do(f func()) {
|
||||
s.mu.Lock()
|
||||
defer s.mu.Unlock()
|
||||
|
||||
now := s.clock.Now()
|
||||
if s.window.IsZero() {
|
||||
s.window = now
|
||||
}
|
||||
|
||||
// If we are no longer in our saved time window, then we get to reset our run
|
||||
// count back to 0 and start increasing towards the threshold again.
|
||||
if inWindow := now.Sub(s.window) < s.interval; !inWindow {
|
||||
s.window = now
|
||||
s.count = 0
|
||||
}
|
||||
|
||||
// If we have not run the function more than threshold times in this current
|
||||
// time window, we get to run it now!
|
||||
if underThreshold := s.count < s.threshold; underThreshold {
|
||||
s.count++
|
||||
f()
|
||||
}
|
||||
}
|
||||
|
||||
// GetAuthenticator returns an exec-based plugin for providing client credentials.
|
||||
func GetAuthenticator(config *api.ExecConfig) (*Authenticator, error) {
|
||||
return newAuthenticator(globalCache, config)
|
||||
@@ -129,6 +175,13 @@ func newAuthenticator(c *cache, config *api.ExecConfig) (*Authenticator, error)
|
||||
args: config.Args,
|
||||
group: gv,
|
||||
|
||||
installHint: config.InstallHint,
|
||||
sometimes: &sometimes{
|
||||
threshold: 10,
|
||||
interval: time.Hour,
|
||||
clock: clock.RealClock{},
|
||||
},
|
||||
|
||||
stdin: os.Stdin,
|
||||
stderr: os.Stderr,
|
||||
interactive: terminal.IsTerminal(int(os.Stdout.Fd())),
|
||||
@@ -152,6 +205,12 @@ type Authenticator struct {
|
||||
group schema.GroupVersion
|
||||
env []string
|
||||
|
||||
// Used to avoid log spew by rate limiting install hint printing. We didn't do
|
||||
// this by interval based rate limiting alone since that way may have prevented
|
||||
// the install hint from showing up for kubectl users.
|
||||
sometimes *sometimes
|
||||
installHint string
|
||||
|
||||
// Stubbable for testing
|
||||
stdin io.Reader
|
||||
stderr io.Writer
|
||||
@@ -178,6 +237,15 @@ type credentials struct {
|
||||
// UpdateTransportConfig updates the transport.Config to use credentials
|
||||
// returned by the plugin.
|
||||
func (a *Authenticator) UpdateTransportConfig(c *transport.Config) error {
|
||||
// If a bearer token is present in the request - avoid the GetCert callback when
|
||||
// setting up the transport, as that triggers the exec action if the server is
|
||||
// also configured to allow client certificates for authentication. For requests
|
||||
// like "kubectl get --token (token) pods" we should assume the intention is to
|
||||
// use the provided token for authentication.
|
||||
if c.HasTokenAuth() {
|
||||
return nil
|
||||
}
|
||||
|
||||
c.Wrap(func(rt http.RoundTripper) http.RoundTripper {
|
||||
return &roundTripper{a, rt}
|
||||
})
|
||||
@@ -323,7 +391,7 @@ func (a *Authenticator) refreshCredsLocked(r *clientauthentication.Response) err
|
||||
}
|
||||
|
||||
if err := cmd.Run(); err != nil {
|
||||
return fmt.Errorf("exec: %v", err)
|
||||
return a.wrapCmdRunErrorLocked(err)
|
||||
}
|
||||
|
||||
_, gvk, err := codecs.UniversalDecoder(a.group).Decode(stdout.Bytes(), nil, cred)
|
||||
@@ -394,3 +462,35 @@ func (a *Authenticator) refreshCredsLocked(r *clientauthentication.Response) err
|
||||
expirationMetrics.set(a, expiry)
|
||||
return nil
|
||||
}
|
||||
|
||||
// wrapCmdRunErrorLocked pulls out the code to construct a helpful error message
|
||||
// for when the exec plugin's binary fails to Run().
|
||||
//
|
||||
// It must be called while holding the Authenticator's mutex.
|
||||
func (a *Authenticator) wrapCmdRunErrorLocked(err error) error {
|
||||
switch err.(type) {
|
||||
case *exec.Error: // Binary does not exist (see exec.Error).
|
||||
builder := strings.Builder{}
|
||||
fmt.Fprintf(&builder, "exec: executable %s not found", a.cmd)
|
||||
|
||||
a.sometimes.Do(func() {
|
||||
fmt.Fprint(&builder, installHintVerboseHelp)
|
||||
if a.installHint != "" {
|
||||
fmt.Fprintf(&builder, "\n\n%s", a.installHint)
|
||||
}
|
||||
})
|
||||
|
||||
return errors.New(builder.String())
|
||||
|
||||
case *exec.ExitError: // Binary execution failed (see exec.Cmd.Run()).
|
||||
e := err.(*exec.ExitError)
|
||||
return fmt.Errorf(
|
||||
"exec: executable %s failed with exit code %d",
|
||||
a.cmd,
|
||||
e.ProcessState.ExitCode(),
|
||||
)
|
||||
|
||||
default:
|
||||
return fmt.Errorf("exec: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
4
vendor/k8s.io/client-go/rest/client.go
generated
vendored
4
vendor/k8s.io/client-go/rest/client.go
generated
vendored
@@ -94,6 +94,10 @@ type RESTClient struct {
|
||||
// overridden.
|
||||
rateLimiter flowcontrol.RateLimiter
|
||||
|
||||
// warningHandler is shared among all requests created by this client.
|
||||
// If not set, defaultWarningHandler is used.
|
||||
warningHandler WarningHandler
|
||||
|
||||
// Set specific behavior of the client. If not set http.DefaultClient will be used.
|
||||
Client *http.Client
|
||||
}
|
||||
|
||||
18
vendor/k8s.io/client-go/rest/config.go
generated
vendored
18
vendor/k8s.io/client-go/rest/config.go
generated
vendored
@@ -123,6 +123,10 @@ type Config struct {
|
||||
// Rate limiter for limiting connections to the master from this client. If present overwrites QPS/Burst
|
||||
RateLimiter flowcontrol.RateLimiter
|
||||
|
||||
// WarningHandler handles warnings in server responses.
|
||||
// If not set, the default warning handler is used.
|
||||
WarningHandler WarningHandler
|
||||
|
||||
// The maximum length of time to wait before giving up on a server request. A value of zero means no timeout.
|
||||
Timeout time.Duration
|
||||
|
||||
@@ -339,7 +343,11 @@ func RESTClientFor(config *Config) (*RESTClient, error) {
|
||||
Negotiator: runtime.NewClientNegotiator(config.NegotiatedSerializer, gv),
|
||||
}
|
||||
|
||||
return NewRESTClient(baseURL, versionedAPIPath, clientContent, rateLimiter, httpClient)
|
||||
restClient, err := NewRESTClient(baseURL, versionedAPIPath, clientContent, rateLimiter, httpClient)
|
||||
if err == nil && config.WarningHandler != nil {
|
||||
restClient.warningHandler = config.WarningHandler
|
||||
}
|
||||
return restClient, err
|
||||
}
|
||||
|
||||
// UnversionedRESTClientFor is the same as RESTClientFor, except that it allows
|
||||
@@ -393,7 +401,11 @@ func UnversionedRESTClientFor(config *Config) (*RESTClient, error) {
|
||||
Negotiator: runtime.NewClientNegotiator(config.NegotiatedSerializer, gv),
|
||||
}
|
||||
|
||||
return NewRESTClient(baseURL, versionedAPIPath, clientContent, rateLimiter, httpClient)
|
||||
restClient, err := NewRESTClient(baseURL, versionedAPIPath, clientContent, rateLimiter, httpClient)
|
||||
if err == nil && config.WarningHandler != nil {
|
||||
restClient.warningHandler = config.WarningHandler
|
||||
}
|
||||
return restClient, err
|
||||
}
|
||||
|
||||
// SetKubernetesDefaults sets default values on the provided client config for accessing the
|
||||
@@ -562,6 +574,7 @@ func AnonymousClientConfig(config *Config) *Config {
|
||||
NextProtos: config.TLSClientConfig.NextProtos,
|
||||
},
|
||||
RateLimiter: config.RateLimiter,
|
||||
WarningHandler: config.WarningHandler,
|
||||
UserAgent: config.UserAgent,
|
||||
DisableCompression: config.DisableCompression,
|
||||
QPS: config.QPS,
|
||||
@@ -608,6 +621,7 @@ func CopyConfig(config *Config) *Config {
|
||||
QPS: config.QPS,
|
||||
Burst: config.Burst,
|
||||
RateLimiter: config.RateLimiter,
|
||||
WarningHandler: config.WarningHandler,
|
||||
Timeout: config.Timeout,
|
||||
Dial: config.Dial,
|
||||
Proxy: config.Proxy,
|
||||
|
||||
34
vendor/k8s.io/client-go/rest/request.go
generated
vendored
34
vendor/k8s.io/client-go/rest/request.go
generated
vendored
@@ -88,6 +88,8 @@ var noBackoff = &NoBackoff{}
|
||||
type Request struct {
|
||||
c *RESTClient
|
||||
|
||||
warningHandler WarningHandler
|
||||
|
||||
rateLimiter flowcontrol.RateLimiter
|
||||
backoff BackoffManager
|
||||
timeout time.Duration
|
||||
@@ -135,12 +137,13 @@ func NewRequest(c *RESTClient) *Request {
|
||||
}
|
||||
|
||||
r := &Request{
|
||||
c: c,
|
||||
rateLimiter: c.rateLimiter,
|
||||
backoff: backoff,
|
||||
timeout: timeout,
|
||||
pathPrefix: pathPrefix,
|
||||
maxRetries: 10,
|
||||
c: c,
|
||||
rateLimiter: c.rateLimiter,
|
||||
backoff: backoff,
|
||||
timeout: timeout,
|
||||
pathPrefix: pathPrefix,
|
||||
maxRetries: 10,
|
||||
warningHandler: c.warningHandler,
|
||||
}
|
||||
|
||||
switch {
|
||||
@@ -218,6 +221,13 @@ func (r *Request) BackOff(manager BackoffManager) *Request {
|
||||
return r
|
||||
}
|
||||
|
||||
// WarningHandler sets the handler this client uses when warning headers are encountered.
|
||||
// If set to nil, this client will use the default warning handler (see SetDefaultWarningHandler).
|
||||
func (r *Request) WarningHandler(handler WarningHandler) *Request {
|
||||
r.warningHandler = handler
|
||||
return r
|
||||
}
|
||||
|
||||
// Throttle receives a rate-limiter and sets or replaces an existing request limiter
|
||||
func (r *Request) Throttle(limiter flowcontrol.RateLimiter) *Request {
|
||||
r.rateLimiter = limiter
|
||||
@@ -692,6 +702,8 @@ func (r *Request) Watch(ctx context.Context) (watch.Interface, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
handleWarnings(resp.Header, r.warningHandler)
|
||||
|
||||
frameReader := framer.NewFrameReader(resp.Body)
|
||||
watchEventDecoder := streaming.NewDecoder(frameReader, streamingSerializer)
|
||||
|
||||
@@ -764,6 +776,7 @@ func (r *Request) Stream(ctx context.Context) (io.ReadCloser, error) {
|
||||
|
||||
switch {
|
||||
case (resp.StatusCode >= 200) && (resp.StatusCode < 300):
|
||||
handleWarnings(resp.Header, r.warningHandler)
|
||||
return resp.Body, nil
|
||||
|
||||
default:
|
||||
@@ -1020,6 +1033,7 @@ func (r *Request) transformResponse(resp *http.Response, req *http.Request) Resu
|
||||
body: body,
|
||||
contentType: contentType,
|
||||
statusCode: resp.StatusCode,
|
||||
warnings: handleWarnings(resp.Header, r.warningHandler),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1038,6 +1052,7 @@ func (r *Request) transformResponse(resp *http.Response, req *http.Request) Resu
|
||||
statusCode: resp.StatusCode,
|
||||
decoder: decoder,
|
||||
err: err,
|
||||
warnings: handleWarnings(resp.Header, r.warningHandler),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1046,6 +1061,7 @@ func (r *Request) transformResponse(resp *http.Response, req *http.Request) Resu
|
||||
contentType: contentType,
|
||||
statusCode: resp.StatusCode,
|
||||
decoder: decoder,
|
||||
warnings: handleWarnings(resp.Header, r.warningHandler),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1181,6 +1197,7 @@ func retryAfterSeconds(resp *http.Response) (int, bool) {
|
||||
// Result contains the result of calling Request.Do().
|
||||
type Result struct {
|
||||
body []byte
|
||||
warnings []net.WarningHeader
|
||||
contentType string
|
||||
err error
|
||||
statusCode int
|
||||
@@ -1294,6 +1311,11 @@ func (r Result) Error() error {
|
||||
return r.err
|
||||
}
|
||||
|
||||
// Warnings returns any warning headers received in the response
|
||||
func (r Result) Warnings() []net.WarningHeader {
|
||||
return r.warnings
|
||||
}
|
||||
|
||||
// NameMayNotBe specifies strings that cannot be used as names specified as path segments (like the REST API or etcd store)
|
||||
var NameMayNotBe = []string{".", ".."}
|
||||
|
||||
|
||||
144
vendor/k8s.io/client-go/rest/warnings.go
generated
vendored
Normal file
144
vendor/k8s.io/client-go/rest/warnings.go
generated
vendored
Normal file
@@ -0,0 +1,144 @@
|
||||
/*
|
||||
Copyright 2020 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.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package rest
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"sync"
|
||||
|
||||
"k8s.io/klog/v2"
|
||||
|
||||
"k8s.io/apimachinery/pkg/util/net"
|
||||
)
|
||||
|
||||
// WarningHandler is an interface for handling warning headers
|
||||
type WarningHandler interface {
|
||||
// HandleWarningHeader is called with the warn code, agent, and text when a warning header is countered.
|
||||
HandleWarningHeader(code int, agent string, text string)
|
||||
}
|
||||
|
||||
var (
|
||||
defaultWarningHandler WarningHandler = WarningLogger{}
|
||||
defaultWarningHandlerLock sync.RWMutex
|
||||
)
|
||||
|
||||
// SetDefaultWarningHandler sets the default handler client uses when warning headers are encountered.
|
||||
// By default, warnings are printed to stderr.
|
||||
func SetDefaultWarningHandler(l WarningHandler) {
|
||||
defaultWarningHandlerLock.Lock()
|
||||
defer defaultWarningHandlerLock.Unlock()
|
||||
defaultWarningHandler = l
|
||||
}
|
||||
func getDefaultWarningHandler() WarningHandler {
|
||||
defaultWarningHandlerLock.RLock()
|
||||
defer defaultWarningHandlerLock.RUnlock()
|
||||
l := defaultWarningHandler
|
||||
return l
|
||||
}
|
||||
|
||||
// NoWarnings is an implementation of WarningHandler that suppresses warnings.
|
||||
type NoWarnings struct{}
|
||||
|
||||
func (NoWarnings) HandleWarningHeader(code int, agent string, message string) {}
|
||||
|
||||
// WarningLogger is an implementation of WarningHandler that logs code 299 warnings
|
||||
type WarningLogger struct{}
|
||||
|
||||
func (WarningLogger) HandleWarningHeader(code int, agent string, message string) {
|
||||
if code != 299 || len(message) == 0 {
|
||||
return
|
||||
}
|
||||
klog.Warning(message)
|
||||
}
|
||||
|
||||
type warningWriter struct {
|
||||
// out is the writer to output warnings to
|
||||
out io.Writer
|
||||
// opts contains options controlling warning output
|
||||
opts WarningWriterOptions
|
||||
// writtenLock guards written and writtenCount
|
||||
writtenLock sync.Mutex
|
||||
writtenCount int
|
||||
written map[string]struct{}
|
||||
}
|
||||
|
||||
// WarningWriterOptions controls the behavior of a WarningHandler constructed using NewWarningWriter()
|
||||
type WarningWriterOptions struct {
|
||||
// Deduplicate indicates a given warning message should only be written once.
|
||||
// Setting this to true in a long-running process handling many warnings can result in increased memory use.
|
||||
Deduplicate bool
|
||||
// Color indicates that warning output can include ANSI color codes
|
||||
Color bool
|
||||
}
|
||||
|
||||
// NewWarningWriter returns an implementation of WarningHandler that outputs code 299 warnings to the specified writer.
|
||||
func NewWarningWriter(out io.Writer, opts WarningWriterOptions) *warningWriter {
|
||||
h := &warningWriter{out: out, opts: opts}
|
||||
if opts.Deduplicate {
|
||||
h.written = map[string]struct{}{}
|
||||
}
|
||||
return h
|
||||
}
|
||||
|
||||
const (
|
||||
yellowColor = "\u001b[33;1m"
|
||||
resetColor = "\u001b[0m"
|
||||
)
|
||||
|
||||
// HandleWarningHeader prints warnings with code=299 to the configured writer.
|
||||
func (w *warningWriter) HandleWarningHeader(code int, agent string, message string) {
|
||||
if code != 299 || len(message) == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
w.writtenLock.Lock()
|
||||
defer w.writtenLock.Unlock()
|
||||
|
||||
if w.opts.Deduplicate {
|
||||
if _, alreadyWritten := w.written[message]; alreadyWritten {
|
||||
return
|
||||
}
|
||||
w.written[message] = struct{}{}
|
||||
}
|
||||
w.writtenCount++
|
||||
|
||||
if w.opts.Color {
|
||||
fmt.Fprintf(w.out, "%sWarning:%s %s\n", yellowColor, resetColor, message)
|
||||
} else {
|
||||
fmt.Fprintf(w.out, "Warning: %s\n", message)
|
||||
}
|
||||
}
|
||||
|
||||
func (w *warningWriter) WarningCount() int {
|
||||
w.writtenLock.Lock()
|
||||
defer w.writtenLock.Unlock()
|
||||
return w.writtenCount
|
||||
}
|
||||
|
||||
func handleWarnings(headers http.Header, handler WarningHandler) []net.WarningHeader {
|
||||
if handler == nil {
|
||||
handler = getDefaultWarningHandler()
|
||||
}
|
||||
|
||||
warnings, _ := net.ParseWarningHeaders(headers["Warning"])
|
||||
for _, warning := range warnings {
|
||||
handler.HandleWarningHeader(warning.Code, warning.Agent, warning.Text)
|
||||
}
|
||||
return warnings
|
||||
}
|
||||
7
vendor/k8s.io/client-go/tools/clientcmd/api/types.go
generated
vendored
7
vendor/k8s.io/client-go/tools/clientcmd/api/types.go
generated
vendored
@@ -193,7 +193,7 @@ func (c AuthProviderConfig) String() string {
|
||||
// ExecConfig specifies a command to provide client credentials. The command is exec'd
|
||||
// and outputs structured stdout holding credentials.
|
||||
//
|
||||
// See the client.authentiction.k8s.io API group for specifications of the exact input
|
||||
// See the client.authentication.k8s.io API group for specifications of the exact input
|
||||
// and output format
|
||||
type ExecConfig struct {
|
||||
// Command to execute.
|
||||
@@ -210,6 +210,11 @@ type ExecConfig struct {
|
||||
// Preferred input version of the ExecInfo. The returned ExecCredentials MUST use
|
||||
// the same encoding version as the input.
|
||||
APIVersion string `json:"apiVersion,omitempty"`
|
||||
|
||||
// This text is shown to the user when the executable doesn't seem to be
|
||||
// present. For example, `brew install foo-cli` might be a good InstallHint for
|
||||
// foo-cli on Mac OS systems.
|
||||
InstallHint string `json:"installHint,omitempty"`
|
||||
}
|
||||
|
||||
var _ fmt.Stringer = new(ExecConfig)
|
||||
|
||||
Reference in New Issue
Block a user