vendored changes

This commit is contained in:
Sergii Koshel 2020-02-12 17:56:04 +02:00
parent d091fff18b
commit 128f9a29f5
522 changed files with 29974 additions and 25705 deletions

View file

@ -35,6 +35,7 @@ import (
"k8s.io/klog"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/runtime/serializer"
"k8s.io/apimachinery/pkg/util/sets"
utilwaitgroup "k8s.io/apimachinery/pkg/util/waitgroup"
@ -159,7 +160,7 @@ type Config struct {
// patch may cause.
// This affects all places that applies json patch in the binary.
JSONPatchMaxCopyBytes int64
// The limit on the request body size that would be accepted and decoded in a write request.
// The limit on the request size that would be accepted and decoded in a write request
// 0 means no limit.
MaxRequestBodyBytes int64
// MaxRequestsInFlight is the maximum number of parallel non-long-running requests. Every further
@ -188,6 +189,10 @@ type Config struct {
// kube-proxy, services, etc.) can reach the GenericAPIServer.
// If nil or 0.0.0.0, the host's default interface will be used.
PublicAddress net.IP
// EquivalentResourceRegistry provides information about resources equivalent to a given resource,
// and the kind associated with a given resource. As resources are installed, they are registered here.
EquivalentResourceRegistry runtime.EquivalentResourceRegistry
}
type RecommendedConfig struct {
@ -266,22 +271,20 @@ func NewConfig(codecs serializer.CodecFactory) *Config {
MaxMutatingRequestsInFlight: 200,
RequestTimeout: time.Duration(60) * time.Second,
MinRequestTimeout: 1800,
// 10MB is the recommended maximum client request size in bytes
// 1.5MB is the recommended client request size in byte
// the etcd server should accept. See
// https://github.com/etcd-io/etcd/blob/release-3.3/etcdserver/server.go#L90.
// https://github.com/etcd-io/etcd/blob/release-3.4/embed/config.go#L56.
// A request body might be encoded in json, and is converted to
// proto when persisted in etcd. Assuming the upper bound of
// the size ratio is 10:1, we set 100MB as the largest size
// proto when persisted in etcd, so we allow 2x as the largest size
// increase the "copy" operations in a json patch may cause.
JSONPatchMaxCopyBytes: int64(100 * 1024 * 1024),
// 10MB is the recommended maximum client request size in bytes
JSONPatchMaxCopyBytes: int64(3 * 1024 * 1024),
// 1.5MB is the recommended client request size in byte
// the etcd server should accept. See
// https://github.com/etcd-io/etcd/blob/release-3.3/etcdserver/server.go#L90.
// https://github.com/etcd-io/etcd/blob/release-3.4/embed/config.go#L56.
// A request body might be encoded in json, and is converted to
// proto when persisted in etcd. Assuming the upper bound of
// the size ratio is 10:1, we set 100MB as the largest request
// proto when persisted in etcd, so we allow 2x as the largest request
// body size to be accepted and decoded in a write request.
MaxRequestBodyBytes: int64(100 * 1024 * 1024),
MaxRequestBodyBytes: int64(3 * 1024 * 1024),
EnableAPIResponseCompression: utilfeature.DefaultFeatureGate.Enabled(features.APIResponseCompression),
// Default to treating watch as a long-running operation
@ -417,6 +420,21 @@ func (c *Config) Complete(informers informers.SharedInformerFactory) CompletedCo
c.RequestInfoResolver = NewRequestInfoResolver(c)
}
if c.EquivalentResourceRegistry == nil {
if c.RESTOptionsGetter == nil {
c.EquivalentResourceRegistry = runtime.NewEquivalentResourceRegistry()
} else {
c.EquivalentResourceRegistry = runtime.NewEquivalentResourceRegistryWithIdentity(func(groupResource schema.GroupResource) string {
// use the storage prefix as the key if possible
if opts, err := c.RESTOptionsGetter.GetRESTOptions(groupResource); err == nil {
return opts.ResourcePrefix
}
// otherwise return "" to use the default key (parent GV name)
return ""
})
}
}
return CompletedConfig{&completedConfig{c, informers}}
}
@ -436,6 +454,9 @@ func (c completedConfig) New(name string, delegationTarget DelegationTarget) (*G
if c.LoopbackClientConfig == nil {
return nil, fmt.Errorf("Genericapiserver.New() called with config.LoopbackClientConfig == nil")
}
if c.EquivalentResourceRegistry == nil {
return nil, fmt.Errorf("Genericapiserver.New() called with config.EquivalentResourceRegistry == nil")
}
handlerChainBuilder := func(handler http.Handler) http.Handler {
return c.BuildHandlerChainFunc(handler, c.Config)
@ -443,15 +464,16 @@ func (c completedConfig) New(name string, delegationTarget DelegationTarget) (*G
apiServerHandler := NewAPIServerHandler(name, c.Serializer, handlerChainBuilder, delegationTarget.UnprotectedHandler())
s := &GenericAPIServer{
discoveryAddresses: c.DiscoveryAddresses,
LoopbackClientConfig: c.LoopbackClientConfig,
legacyAPIGroupPrefixes: c.LegacyAPIGroupPrefixes,
admissionControl: c.AdmissionControl,
Serializer: c.Serializer,
AuditBackend: c.AuditBackend,
Authorizer: c.Authorization.Authorizer,
delegationTarget: delegationTarget,
HandlerChainWaitGroup: c.HandlerChainWaitGroup,
discoveryAddresses: c.DiscoveryAddresses,
LoopbackClientConfig: c.LoopbackClientConfig,
legacyAPIGroupPrefixes: c.LegacyAPIGroupPrefixes,
admissionControl: c.AdmissionControl,
Serializer: c.Serializer,
AuditBackend: c.AuditBackend,
Authorizer: c.Authorization.Authorizer,
delegationTarget: delegationTarget,
EquivalentResourceRegistry: c.EquivalentResourceRegistry,
HandlerChainWaitGroup: c.HandlerChainWaitGroup,
minRequestTimeout: time.Duration(c.MinRequestTimeout) * time.Second,
ShutdownTimeout: c.RequestTimeout,
@ -614,9 +636,18 @@ func (s *SecureServingInfo) HostPort() (string, int, error) {
}
// AuthorizeClientBearerToken wraps the authenticator and authorizer in loopback authentication logic
// if the loopback client config is specified AND it has a bearer token.
// if the loopback client config is specified AND it has a bearer token. Note that if either authn or
// authz is nil, this function won't add a token authenticator or authorizer.
func AuthorizeClientBearerToken(loopback *restclient.Config, authn *AuthenticationInfo, authz *AuthorizationInfo) {
if loopback == nil || authn == nil || authz == nil || authn.Authenticator == nil && authz.Authorizer == nil || len(loopback.BearerToken) == 0 {
if loopback == nil || len(loopback.BearerToken) == 0 {
return
}
if authn == nil || authz == nil {
// prevent nil pointer panic
}
if authn.Authenticator == nil || authz.Authorizer == nil {
// authenticator or authorizer might be nil if we want to bypass authz/authn
// and we also do nothing in this case.
return
}

View file

@ -38,12 +38,9 @@ func (s *SecureServingInfo) NewClientConfig(caCert []byte) (*restclient.Config,
}
return &restclient.Config{
// Increase QPS limits. The client is currently passed to all admission plugins,
// and those can be throttled in case of higher load on apiserver - see #22340 and #22422
// for more details. Once #22422 is fixed, we may want to remove it.
QPS: 50,
Burst: 100,
Host: "https://" + net.JoinHostPort(host, port),
// Do not limit loopback client QPS.
QPS: -1,
Host: "https://" + net.JoinHostPort(host, port),
// override the ServerName to select our loopback certificate via SNI. This name is also
// used by the client to compare the returns server certificate against.
TLSClientConfig: restclient.TLSClientConfig{

View file

@ -29,6 +29,8 @@ import (
)
// DeprecatedInsecureServingInfo is the main context object for the insecure http server.
// HTTP does NOT include authentication or authorization.
// You shouldn't be using this. It makes sig-auth sad.
type DeprecatedInsecureServingInfo struct {
// Listener is the secure server network listener.
Listener net.Listener

View file

@ -28,6 +28,7 @@ import (
"time"
apierrors "k8s.io/apimachinery/pkg/api/errors"
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
"k8s.io/apiserver/pkg/endpoints/metrics"
apirequest "k8s.io/apiserver/pkg/endpoints/request"
)
@ -92,28 +93,49 @@ func (t *timeoutHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
return
}
errCh := make(chan interface{})
// resultCh is used as both errCh and stopCh
resultCh := make(chan interface{})
tw := newTimeoutWriter(w)
go func() {
defer func() {
err := recover()
if err != nil {
// Same as stdlib http server code. Manually allocate stack
// trace buffer size to prevent excessively large logs
const size = 64 << 10
buf := make([]byte, size)
buf = buf[:runtime.Stack(buf, false)]
err = fmt.Sprintf("%v\n%s", err, buf)
}
errCh <- err
resultCh <- err
}()
t.handler.ServeHTTP(tw, r)
}()
select {
case err := <-errCh:
case err := <-resultCh:
// panic if error occurs; stop otherwise
if err != nil {
panic(err)
}
return
case <-after:
defer func() {
// resultCh needs to have a reader, since the function doing
// the work needs to send to it. This is defer'd to ensure it runs
// ever if the post timeout work itself panics.
go func() {
res := <-resultCh
if res != nil {
switch t := res.(type) {
case error:
utilruntime.HandleError(t)
default:
utilruntime.HandleError(fmt.Errorf("%v", res))
}
}
}()
}()
postTimeoutFn()
tw.timeout(err)
}

View file

@ -157,6 +157,10 @@ type GenericAPIServer struct {
// the create-on-update case
Authorizer authorizer.Authorizer
// EquivalentResourceRegistry provides information about resources equivalent to a given resource,
// and the kind associated with a given resource. As resources are installed, they are registered here.
EquivalentResourceRegistry runtime.EquivalentResourceRegistry
// enableAPIResponseCompression indicates whether API Responses should support compression
// if the client requests it via Accept-Encoding
enableAPIResponseCompression bool
@ -258,10 +262,13 @@ func (s *GenericAPIServer) PrepareRun() preparedGenericAPIServer {
// Register audit backend preShutdownHook.
if s.AuditBackend != nil {
s.AddPreShutdownHook("audit-backend", func() error {
err := s.AddPreShutdownHook("audit-backend", func() error {
s.AuditBackend.Shutdown()
return nil
})
if err != nil {
klog.Errorf("Failed to add pre-shutdown hook for audit-backend %s", err)
}
}
return preparedGenericAPIServer{s}
@ -464,6 +471,8 @@ func (s *GenericAPIServer) newAPIGroupVersion(apiGroupInfo *APIGroupInfo, groupV
Typer: apiGroupInfo.Scheme,
Linker: runtime.SelfLinker(meta.NewAccessor()),
EquivalentResourceRegistry: s.EquivalentResourceRegistry,
Admit: s.admissionControl,
MinRequestTimeout: s.minRequestTimeout,
EnableAPIResponseCompression: s.enableAPIResponseCompression,

View file

@ -17,5 +17,5 @@ limitations under the License.
// Package healthz implements basic http server health checking.
// Usage:
// import "k8s.io/apiserver/pkg/server/healthz"
// healthz.DefaultHealthz()
// healthz.InstallHandler(mux)
package healthz // import "k8s.io/apiserver/pkg/server/healthz"

View file

@ -37,15 +37,6 @@ type HealthzChecker interface {
Check(req *http.Request) error
}
var defaultHealthz = sync.Once{}
// DefaultHealthz installs the default healthz check to the http.DefaultServeMux.
func DefaultHealthz(checks ...HealthzChecker) {
defaultHealthz.Do(func() {
InstallHandler(http.DefaultServeMux, checks...)
})
}
// PingHealthz returns true automatically when checked
var PingHealthz HealthzChecker = ping{}
@ -181,6 +172,7 @@ func handleRootHealthz(checks ...HealthzChecker) http.HandlerFunc {
}
// always be verbose on failure
if failed {
klog.V(2).Infof("%vhealthz check failed", verboseOut.String())
http.Error(w, fmt.Sprintf("%vhealthz check failed", verboseOut.String()), http.StatusInternalServerError)
return
}

View file

@ -125,13 +125,13 @@ func (rl *respLogger) StacktraceWhen(pred StacktracePred) *respLogger {
// StatusIsNot returns a StacktracePred which will cause stacktraces to be logged
// for any status *not* in the given list.
func StatusIsNot(statuses ...int) StacktracePred {
statusesNoTrace := map[int]bool{}
for _, s := range statuses {
statusesNoTrace[s] = true
}
return func(status int) bool {
for _, s := range statuses {
if status == s {
return false
}
}
return true
_, ok := statusesNoTrace[status]
return !ok
}
}

View file

@ -229,6 +229,7 @@ func (f *SimpleRestOptionsFactory) GetRESTOptions(resource schema.GroupResource)
if !ok {
cacheSize = f.Options.DefaultWatchCacheSize
}
// depending on cache size this might return an undecorated storage
ret.Decorator = genericregistry.StorageWithCacher(cacheSize)
}
return ret, nil
@ -262,6 +263,7 @@ func (f *StorageFactoryRestOptionsFactory) GetRESTOptions(resource schema.GroupR
if !ok {
cacheSize = f.Options.DefaultWatchCacheSize
}
// depending on cache size this might return an undecorated storage
ret.Decorator = genericregistry.StorageWithCacher(cacheSize)
}
@ -285,7 +287,6 @@ func ParseWatchCacheSizes(cacheSizes []string) (map[schema.GroupResource]int, er
if size < 0 {
return nil, fmt.Errorf("watch cache size cannot be negative: %s", c)
}
watchCacheSizes[schema.ParseGroupResource(tokens[0])] = size
}
return watchCacheSizes, nil

View file

@ -27,7 +27,7 @@ import (
utilfeature "k8s.io/apiserver/pkg/util/feature"
// add the generic feature gates
_ "k8s.io/apiserver/pkg/features"
"k8s.io/apiserver/pkg/features"
"github.com/spf13/pflag"
)
@ -49,8 +49,9 @@ type ServerRunOptions struct {
// decoded in a write request. 0 means no limit.
// We intentionally did not add a flag for this option. Users of the
// apiserver library can wire it to a flag.
MaxRequestBodyBytes int64
TargetRAMMB int
MaxRequestBodyBytes int64
TargetRAMMB int
EnableInfightQuotaHandler bool
}
func NewServerRunOptions() *ServerRunOptions {
@ -104,11 +105,27 @@ func (s *ServerRunOptions) Validate() []error {
if s.TargetRAMMB < 0 {
errors = append(errors, fmt.Errorf("--target-ram-mb can not be negative value"))
}
if s.MaxRequestsInFlight < 0 {
errors = append(errors, fmt.Errorf("--max-requests-inflight can not be negative value"))
}
if s.MaxMutatingRequestsInFlight < 0 {
errors = append(errors, fmt.Errorf("--max-mutating-requests-inflight can not be negative value"))
if s.EnableInfightQuotaHandler {
if !utilfeature.DefaultFeatureGate.Enabled(features.RequestManagement) {
errors = append(errors, fmt.Errorf("--enable-inflight-quota-handler can not be set if feature "+
"gate RequestManagement is disabled"))
}
if s.MaxMutatingRequestsInFlight != 0 {
errors = append(errors, fmt.Errorf("--max-mutating-requests-inflight=%v "+
"can not be set if enabled inflight quota handler", s.MaxMutatingRequestsInFlight))
}
if s.MaxRequestsInFlight != 0 {
errors = append(errors, fmt.Errorf("--max-requests-inflight=%v "+
"can not be set if enabled inflight quota handler", s.MaxRequestsInFlight))
}
} else {
if s.MaxRequestsInFlight < 0 {
errors = append(errors, fmt.Errorf("--max-requests-inflight can not be negative value"))
}
if s.MaxMutatingRequestsInFlight < 0 {
errors = append(errors, fmt.Errorf("--max-mutating-requests-inflight can not be negative value"))
}
}
if s.RequestTimeout.Nanoseconds() < 0 {
@ -174,5 +191,8 @@ func (s *ServerRunOptions) AddUniversalFlags(fs *pflag.FlagSet) {
"handler, which picks a randomized value above this number as the connection timeout, "+
"to spread out load.")
fs.BoolVar(&s.EnableInfightQuotaHandler, "enable-inflight-quota-handler", s.EnableInfightQuotaHandler, ""+
"If true, replace the max-in-flight handler with an enhanced one that queues and dispatches with priority and fairness")
utilfeature.DefaultMutableFeatureGate.AddFlag(fs)
}