Update go dependencies

This commit is contained in:
Manuel Alejandro de Brito Fontes 2018-09-27 14:20:02 -03:00
parent 3c1a5c5fc2
commit 6c33bee8fd
No known key found for this signature in database
GPG key ID: 786136016A8BA02A
620 changed files with 29782 additions and 15901 deletions

View file

@ -20,7 +20,6 @@ import (
"crypto/tls"
"crypto/x509"
"fmt"
"io"
"net"
"net/http"
goruntime "runtime"
@ -31,6 +30,7 @@ import (
"github.com/emicklei/go-restful-swagger12"
"github.com/go-openapi/spec"
"github.com/golang/glog"
"github.com/pborman/uuid"
"k8s.io/apimachinery/pkg/runtime"
@ -59,13 +59,13 @@ import (
"k8s.io/apiserver/pkg/server/routes"
serverstore "k8s.io/apiserver/pkg/server/storage"
utilfeature "k8s.io/apiserver/pkg/util/feature"
"k8s.io/apiserver/pkg/util/logs"
"k8s.io/client-go/informers"
restclient "k8s.io/client-go/rest"
certutil "k8s.io/client-go/util/cert"
openapicommon "k8s.io/kube-openapi/pkg/common"
// install apis
"github.com/golang/glog"
_ "k8s.io/apiserver/pkg/apis/apiserver/install"
)
@ -113,8 +113,6 @@ type Config struct {
// Version will enable the /version endpoint if non-nil
Version *version.Info
// LegacyAuditWriter is the destination for audit logs. If nil, they will not be written.
LegacyAuditWriter io.Writer
// AuditBackend is where audit events are sent to.
AuditBackend audit.Backend
// AuditPolicyChecker makes the decision of whether and how to audit log a request.
@ -181,9 +179,6 @@ type Config struct {
// values below here are targets for removal
//===========================================================================
// The port on PublicAddress where a read-write server will be installed.
// Defaults to 6443 if not set.
ReadWritePort int
// PublicAddress is the IP address where members of the cluster (kubelet,
// kube-proxy, services, etc.) can reach the GenericAPIServer.
// If nil or 0.0.0.0, the host's default interface will be used.
@ -250,12 +245,11 @@ type AuthorizationInfo struct {
func NewConfig(codecs serializer.CodecFactory) *Config {
return &Config{
Serializer: codecs,
ReadWritePort: 443,
BuildHandlerChainFunc: DefaultBuildHandlerChain,
HandlerChainWaitGroup: new(utilwaitgroup.SafeWaitGroup),
LegacyAPIGroupPrefixes: sets.NewString(DefaultLegacyAPIPrefix),
DisabledPostStartHooks: sets.NewString(),
HealthzChecks: []healthz.HealthzChecker{healthz.PingHealthz},
HealthzChecks: []healthz.HealthzChecker{healthz.PingHealthz, healthz.LogHealthz},
EnableIndex: true,
EnableDiscovery: true,
EnableProfiling: true,
@ -354,39 +348,47 @@ type CompletedConfig struct {
// Complete fills in any fields not set that are required to have valid data and can be derived
// from other fields. If you're going to `ApplyOptions`, do that first. It's mutating the receiver.
func (c *Config) Complete(informers informers.SharedInformerFactory) CompletedConfig {
host := c.ExternalAddress
if host == "" && c.PublicAddress != nil {
host = c.PublicAddress.String()
if len(c.ExternalAddress) == 0 && c.PublicAddress != nil {
c.ExternalAddress = c.PublicAddress.String()
}
// if there is no port, and we have a ReadWritePort, use that
if _, _, err := net.SplitHostPort(host); err != nil && c.ReadWritePort != 0 {
host = net.JoinHostPort(host, strconv.Itoa(c.ReadWritePort))
// if there is no port, and we listen on one securely, use that one
if _, _, err := net.SplitHostPort(c.ExternalAddress); err != nil {
if c.SecureServing == nil {
glog.Fatalf("cannot derive external address port without listening on a secure port.")
}
_, port, err := c.SecureServing.HostPort()
if err != nil {
glog.Fatalf("cannot derive external address from the secure port: %v", err)
}
c.ExternalAddress = net.JoinHostPort(c.ExternalAddress, strconv.Itoa(port))
}
c.ExternalAddress = host
if c.OpenAPIConfig != nil && c.OpenAPIConfig.SecurityDefinitions != nil {
// Setup OpenAPI security: all APIs will have the same authentication for now.
c.OpenAPIConfig.DefaultSecurity = []map[string][]string{}
keys := []string{}
for k := range *c.OpenAPIConfig.SecurityDefinitions {
keys = append(keys, k)
}
sort.Strings(keys)
for _, k := range keys {
c.OpenAPIConfig.DefaultSecurity = append(c.OpenAPIConfig.DefaultSecurity, map[string][]string{k: {}})
}
if c.OpenAPIConfig.CommonResponses == nil {
c.OpenAPIConfig.CommonResponses = map[int]spec.Response{}
}
if _, exists := c.OpenAPIConfig.CommonResponses[http.StatusUnauthorized]; !exists {
c.OpenAPIConfig.CommonResponses[http.StatusUnauthorized] = spec.Response{
ResponseProps: spec.ResponseProps{
Description: "Unauthorized",
},
if c.OpenAPIConfig != nil {
if c.OpenAPIConfig.SecurityDefinitions != nil {
// Setup OpenAPI security: all APIs will have the same authentication for now.
c.OpenAPIConfig.DefaultSecurity = []map[string][]string{}
keys := []string{}
for k := range *c.OpenAPIConfig.SecurityDefinitions {
keys = append(keys, k)
}
sort.Strings(keys)
for _, k := range keys {
c.OpenAPIConfig.DefaultSecurity = append(c.OpenAPIConfig.DefaultSecurity, map[string][]string{k: {}})
}
if c.OpenAPIConfig.CommonResponses == nil {
c.OpenAPIConfig.CommonResponses = map[int]spec.Response{}
}
if _, exists := c.OpenAPIConfig.CommonResponses[http.StatusUnauthorized]; !exists {
c.OpenAPIConfig.CommonResponses[http.StatusUnauthorized] = spec.Response{
ResponseProps: spec.ResponseProps{
Description: "Unauthorized",
},
}
}
}
// make sure we populate info, and info.version, if not manually set
if c.OpenAPIConfig.Info == nil {
c.OpenAPIConfig.Info = &spec.Info{}
}
@ -409,24 +411,7 @@ func (c *Config) Complete(informers informers.SharedInformerFactory) CompletedCo
c.DiscoveryAddresses = discovery.DefaultAddresses{DefaultAddress: c.ExternalAddress}
}
// If the loopbackclientconfig is specified AND it has a token for use against the API server
// wrap the authenticator and authorizer in loopback authentication logic
if c.Authentication.Authenticator != nil && c.Authorization.Authorizer != nil && c.LoopbackClientConfig != nil && len(c.LoopbackClientConfig.BearerToken) > 0 {
privilegedLoopbackToken := c.LoopbackClientConfig.BearerToken
var uid = uuid.NewRandom().String()
tokens := make(map[string]*user.DefaultInfo)
tokens[privilegedLoopbackToken] = &user.DefaultInfo{
Name: user.APIServerUser,
UID: uid,
Groups: []string{user.SystemPrivilegedGroup},
}
tokenAuthenticator := authenticatorfactory.NewFromTokens(tokens)
c.Authentication.Authenticator = authenticatorunion.New(tokenAuthenticator, c.Authentication.Authenticator)
tokenAuthorizer := authorizerfactory.NewPrivilegedGroups(user.SystemPrivilegedGroup)
c.Authorization.Authorizer = authorizerunion.New(tokenAuthorizer, c.Authorization.Authorizer)
}
AuthorizeClientBearerToken(c.LoopbackClientConfig, &c.Authentication, &c.Authorization)
if c.RequestInfoResolver == nil {
c.RequestInfoResolver = NewRequestInfoResolver(c)
@ -464,6 +449,7 @@ func (c completedConfig) New(name string, delegationTarget DelegationTarget) (*G
admissionControl: c.AdmissionControl,
Serializer: c.Serializer,
AuditBackend: c.AuditBackend,
Authorizer: c.Authorization.Authorizer,
delegationTarget: delegationTarget,
HandlerChainWaitGroup: c.HandlerChainWaitGroup,
@ -545,15 +531,9 @@ func DefaultBuildHandlerChain(apiHandler http.Handler, c *Config) http.Handler {
handler := genericapifilters.WithAuthorization(apiHandler, c.Authorization.Authorizer, c.Serializer)
handler = genericfilters.WithMaxInFlightLimit(handler, c.MaxRequestsInFlight, c.MaxMutatingRequestsInFlight, c.LongRunningFunc)
handler = genericapifilters.WithImpersonation(handler, c.Authorization.Authorizer, c.Serializer)
if utilfeature.DefaultFeatureGate.Enabled(features.AdvancedAuditing) {
handler = genericapifilters.WithAudit(handler, c.AuditBackend, c.AuditPolicyChecker, c.LongRunningFunc)
} else {
handler = genericapifilters.WithLegacyAudit(handler, c.LegacyAuditWriter)
}
handler = genericapifilters.WithAudit(handler, c.AuditBackend, c.AuditPolicyChecker, c.LongRunningFunc)
failedHandler := genericapifilters.Unauthorized(c.Serializer, c.Authentication.SupportsBasicAuth)
if utilfeature.DefaultFeatureGate.Enabled(features.AdvancedAuditing) {
failedHandler = genericapifilters.WithFailedAuthenticationAudit(failedHandler, c.AuditBackend, c.AuditPolicyChecker)
}
failedHandler = genericapifilters.WithFailedAuthenticationAudit(failedHandler, c.AuditBackend, c.AuditPolicyChecker)
handler = genericapifilters.WithAuthentication(handler, c.Authentication.Authenticator, failedHandler)
handler = genericfilters.WithCORS(handler, c.CorsAllowedOriginList, nil, nil, nil, "true")
handler = genericfilters.WithTimeoutForNonLongRunningRequests(handler, c.LongRunningFunc, c.RequestTimeout)
@ -576,15 +556,7 @@ func installAPI(s *GenericAPIServer, c *Config) {
goruntime.SetBlockProfileRate(1)
}
// so far, only logging related endpoints are considered valid to add for these debug flags.
routes.DebugFlags{}.Install(s.Handler.NonGoRestfulMux, "v", routes.StringFlagPutHandler(
routes.StringFlagSetterFunc(func(val string) (string, error) {
var level glog.Level
if err := level.Set(val); err != nil {
return "", fmt.Errorf("failed set glog.logging.verbosity %s: %v", val, err)
}
return "successfully set glog.logging.verbosity to " + val, nil
}),
))
routes.DebugFlags{}.Install(s.Handler.NonGoRestfulMux, "v", routes.StringFlagPutHandler(logs.GlogSetter))
}
if c.EnableMetrics {
if c.EnableProfiling {
@ -614,3 +586,42 @@ func NewRequestInfoResolver(c *Config) *apirequest.RequestInfoFactory {
GrouplessAPIPrefixes: legacyAPIPrefixes,
}
}
func (s *SecureServingInfo) HostPort() (string, int, error) {
if s == nil || s.Listener == nil {
return "", 0, fmt.Errorf("no listener found")
}
addr := s.Listener.Addr().String()
host, portStr, err := net.SplitHostPort(addr)
if err != nil {
return "", 0, fmt.Errorf("failed to get port from listener address %q: %v", addr, err)
}
port, err := strconv.Atoi(portStr)
if err != nil {
return "", 0, fmt.Errorf("invalid non-numeric port %q", portStr)
}
return host, port, nil
}
// AuthorizeClientBearerToken wraps the authenticator and authorizer in loopback authentication logic
// if the loopback client config is specified AND it has a bearer token.
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 {
return
}
privilegedLoopbackToken := loopback.BearerToken
var uid = uuid.NewRandom().String()
tokens := make(map[string]*user.DefaultInfo)
tokens[privilegedLoopbackToken] = &user.DefaultInfo{
Name: user.APIServerUser,
UID: uid,
Groups: []string{user.SystemPrivilegedGroup},
}
tokenAuthenticator := authenticatorfactory.NewFromTokens(tokens)
authn.Authenticator = authenticatorunion.New(tokenAuthenticator, authn.Authenticator)
tokenAuthorizer := authorizerfactory.NewPrivilegedGroups(user.SystemPrivilegedGroup)
authz.Authorizer = authorizerunion.New(tokenAuthorizer, authz.Authorizer)
}

View file

@ -27,7 +27,7 @@ import (
// select the loopback certificate via SNI if TLS is used.
const LoopbackClientServerNameOverride = "apiserver-loopback-client"
func (s *SecureServingInfo) NewLoopbackClientConfig(token string, loopbackCert []byte) (*restclient.Config, error) {
func (s *SecureServingInfo) NewClientConfig(caCert []byte) (*restclient.Config, error) {
if s == nil || (s.Cert == nil && len(s.SNICerts) == 0) {
return nil, nil
}
@ -41,19 +41,29 @@ func (s *SecureServingInfo) NewLoopbackClientConfig(token string, loopbackCert [
// 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),
BearerToken: token,
QPS: 50,
Burst: 100,
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{
ServerName: LoopbackClientServerNameOverride,
CAData: loopbackCert,
CAData: caCert,
},
}, nil
}
func (s *SecureServingInfo) NewLoopbackClientConfig(token string, loopbackCert []byte) (*restclient.Config, error) {
c, err := s.NewClientConfig(loopbackCert)
if err != nil || c == nil {
return c, err
}
c.BearerToken = token
c.TLSClientConfig.ServerName = LoopbackClientServerNameOverride
return c, nil
}
// LoopbackHostPort returns the host and port loopback REST clients should use
// to contact the server.
func LoopbackHostPort(bindAddress string) (string, string, error) {
@ -63,6 +73,8 @@ func LoopbackHostPort(bindAddress string) (string, string, error) {
return "", "", fmt.Errorf("invalid server bind address: %q", bindAddress)
}
isIPv6 := net.ParseIP(host).To4() == nil
// Value is expected to be an IP or DNS name, not "0.0.0.0".
if host == "0.0.0.0" || host == "::" {
host = "localhost"
@ -72,7 +84,7 @@ func LoopbackHostPort(bindAddress string) (string, string, error) {
addrs, err := net.InterfaceAddrs()
if err == nil {
for _, address := range addrs {
if ipnet, ok := address.(*net.IPNet); ok && ipnet.IP.IsLoopback() {
if ipnet, ok := address.(*net.IPNet); ok && ipnet.IP.IsLoopback() && isIPv6 == (ipnet.IP.To4() == nil) {
host = ipnet.IP.String()
break
}

View file

@ -0,0 +1,85 @@
/*
Copyright 2017 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 server
import (
"net"
"net/http"
"time"
"github.com/golang/glog"
"k8s.io/apiserver/pkg/authentication/user"
"k8s.io/client-go/rest"
)
// DeprecatedInsecureServingInfo is the main context object for the insecure http server.
type DeprecatedInsecureServingInfo struct {
// Listener is the secure server network listener.
Listener net.Listener
// optional server name for log messages
Name string
}
// Serve starts an insecure http server with the given handler. It fails only if
// the initial listen call fails. It does not block.
func (s *DeprecatedInsecureServingInfo) Serve(handler http.Handler, shutdownTimeout time.Duration, stopCh <-chan struct{}) error {
insecureServer := &http.Server{
Addr: s.Listener.Addr().String(),
Handler: handler,
MaxHeaderBytes: 1 << 20,
}
if len(s.Name) > 0 {
glog.Infof("Serving %s insecurely on %s", s.Name, s.Listener.Addr())
} else {
glog.Infof("Serving insecurely on %s", s.Listener.Addr())
}
return RunServer(insecureServer, s.Listener, shutdownTimeout, stopCh)
}
func (s *DeprecatedInsecureServingInfo) NewLoopbackClientConfig() (*rest.Config, error) {
if s == nil {
return nil, nil
}
host, port, err := LoopbackHostPort(s.Listener.Addr().String())
if err != nil {
return nil, err
}
return &rest.Config{
Host: "http://" + net.JoinHostPort(host, port),
// 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,
}, nil
}
// InsecureSuperuser implements authenticator.Request to always return a superuser.
// This is functionally equivalent to skipping authentication and authorization,
// but allows apiserver code to stop special-casing a nil user to skip authorization checks.
type InsecureSuperuser struct{}
func (InsecureSuperuser) AuthenticateRequest(req *http.Request) (user.Info, bool, error) {
return &user.DefaultInfo{
Name: "system:unsecured",
Groups: []string{user.SystemPrivilegedGroup, user.AllAuthenticated},
}, true, nil
}

View file

@ -36,6 +36,7 @@ import (
utilwaitgroup "k8s.io/apimachinery/pkg/util/waitgroup"
"k8s.io/apiserver/pkg/admission"
"k8s.io/apiserver/pkg/audit"
"k8s.io/apiserver/pkg/authorization/authorizer"
genericapi "k8s.io/apiserver/pkg/endpoints"
"k8s.io/apiserver/pkg/endpoints/discovery"
"k8s.io/apiserver/pkg/registry/rest"
@ -138,6 +139,11 @@ type GenericAPIServer struct {
// auditing. The backend is started after the server starts listening.
AuditBackend audit.Backend
// Authorizer determines whether a user is allowed to make a certain request. The Handler does a preliminary
// authorization check using the request URI but it may be necessary to make additional checks, such as in
// the create-on-update case
Authorizer authorizer.Authorizer
// enableAPIResponseCompression indicates whether API Responses should support compression
// if the client requests it via Accept-Encoding
enableAPIResponseCompression bool
@ -341,14 +347,9 @@ func (s *GenericAPIServer) InstallLegacyAPIGroup(apiPrefix string, apiGroupInfo
return err
}
// setup discovery
apiVersions := []string{}
for _, groupVersion := range apiGroupInfo.PrioritizedVersions {
apiVersions = append(apiVersions, groupVersion.Version)
}
// Install the version handler.
// Add a handler at /<apiPrefix> to enumerate the supported api versions.
s.Handler.GoRestfulContainer.Add(discovery.NewLegacyRootAPIHandler(s.discoveryAddresses, s.Serializer, apiPrefix, apiVersions).WebService())
s.Handler.GoRestfulContainer.Add(discovery.NewLegacyRootAPIHandler(s.discoveryAddresses, s.Serializer, apiPrefix).WebService())
return nil
}
@ -427,6 +428,7 @@ func (s *GenericAPIServer) newAPIGroupVersion(apiGroupInfo *APIGroupInfo, groupV
MinRequestTimeout: s.minRequestTimeout,
EnableAPIResponseCompression: s.enableAPIResponseCompression,
OpenAPIConfig: s.openAPIConfig,
Authorizer: s.Authorizer,
}
}

View file

@ -22,8 +22,12 @@ import (
"net/http"
"strings"
"sync"
"sync/atomic"
"time"
"github.com/golang/glog"
"k8s.io/apimachinery/pkg/util/wait"
)
// HealthzChecker is a named healthz checker.
@ -56,6 +60,34 @@ func (ping) Check(_ *http.Request) error {
return nil
}
// LogHealthz returns true if logging is not blocked
var LogHealthz HealthzChecker = &log{}
type log struct {
startOnce sync.Once
lastVerified atomic.Value
}
func (l *log) Name() string {
return "log"
}
func (l *log) Check(_ *http.Request) error {
l.startOnce.Do(func() {
l.lastVerified.Store(time.Now())
go wait.Forever(func() {
glog.Flush()
l.lastVerified.Store(time.Now())
}, time.Minute)
})
lastVerified := l.lastVerified.Load().(time.Time)
if time.Since(lastVerified) < (2 * time.Minute) {
return nil
}
return fmt.Errorf("logging blocked")
}
// NamedCheck returns a healthz checker for the given name and function.
func NamedCheck(name string, check func(r *http.Request) error) HealthzChecker {
return &healthzCheck{name, check}

View file

@ -87,10 +87,30 @@ func (s *SecureServingInfo) Serve(handler http.Handler, shutdownTimeout time.Dur
secureServer.TLSConfig.ClientCAs = s.ClientCA
}
// At least 99% of serialized resources in surveyed clusters were smaller than 256kb.
// This should be big enough to accommodate most API POST requests in a single frame,
// and small enough to allow a per connection buffer of this size multiplied by `MaxConcurrentStreams`.
const resourceBody99Percentile = 256 * 1024
http2Options := &http2.Server{}
// shrink the per-stream buffer and max framesize from the 1MB default while still accommodating most API POST requests in a single frame
http2Options.MaxUploadBufferPerStream = resourceBody99Percentile
http2Options.MaxReadFrameSize = resourceBody99Percentile
// use the overridden concurrent streams setting or make the default of 250 explicit so we can size MaxUploadBufferPerConnection appropriately
if s.HTTP2MaxStreamsPerConnection > 0 {
http2.ConfigureServer(secureServer, &http2.Server{
MaxConcurrentStreams: uint32(s.HTTP2MaxStreamsPerConnection),
})
http2Options.MaxConcurrentStreams = uint32(s.HTTP2MaxStreamsPerConnection)
} else {
http2Options.MaxConcurrentStreams = 250
}
// increase the connection buffer size from the 1MB default to handle the specified number of concurrent streams
http2Options.MaxUploadBufferPerConnection = http2Options.MaxUploadBufferPerStream * int32(http2Options.MaxConcurrentStreams)
// apply settings to the server
if err := http2.ConfigureServer(secureServer, http2Options); err != nil {
return fmt.Errorf("error configuring http2: %v", err)
}
glog.Infof("Serving securely on %s", secureServer.Addr)