Merge pull request #60628 from sttts/sttts-global-requestcontextmapper-in-delegation

Automatic merge from submit-queue. If you want to cherry-pick this change to another branch, please follow the instructions <a href="https://github.com/kubernetes/community/blob/master/contributors/devel/cherry-picks.md">here</a>.

apiserver: enforce global RequestContextMapper in delegation chain

Having a request context mapper in the generic config makes it easy to forget setting
a common mapper for the whole delegation chain. This PR moves it into the New
constructors that already have the delegationTarget argument. So it is obvious
that the mapper is passed down as well.

Fixes https://github.com/kubernetes/kubernetes/issues/60610
This commit is contained in:
Kubernetes Submit Queue 2018-04-05 12:32:18 -07:00 committed by GitHub
commit 0354cac6f4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
19 changed files with 65 additions and 81 deletions

View File

@ -166,7 +166,7 @@ func CreateServerChain(completedOptions completedServerRunOptions, stopCh <-chan
if err != nil { if err != nil {
return nil, err return nil, err
} }
apiExtensionsServer, err := createAPIExtensionsServer(apiExtensionsConfig, genericapiserver.EmptyDelegate) apiExtensionsServer, err := createAPIExtensionsServer(apiExtensionsConfig, genericapiserver.NewEmptyDelegate())
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -180,7 +180,7 @@ func CreateServerChain(completedOptions completedServerRunOptions, stopCh <-chan
// just start the API server as is because clients don't get built correctly when you do this // just start the API server as is because clients don't get built correctly when you do this
if len(os.Getenv("KUBE_API_VERSIONS")) > 0 { if len(os.Getenv("KUBE_API_VERSIONS")) > 0 {
if insecureServingOptions != nil { if insecureServingOptions != nil {
insecureHandlerChain := kubeserver.BuildInsecureHandlerChain(kubeAPIServer.GenericAPIServer.UnprotectedHandler(), kubeAPIServerConfig.GenericConfig) insecureHandlerChain := kubeserver.BuildInsecureHandlerChain(kubeAPIServer.GenericAPIServer.UnprotectedHandler(), kubeAPIServerConfig.GenericConfig, kubeAPIServer.GenericAPIServer.RequestContextMapper())
if err := kubeserver.NonBlockingRun(insecureServingOptions, insecureHandlerChain, kubeAPIServerConfig.GenericConfig.RequestTimeout, stopCh); err != nil { if err := kubeserver.NonBlockingRun(insecureServingOptions, insecureHandlerChain, kubeAPIServerConfig.GenericConfig.RequestTimeout, stopCh); err != nil {
return nil, err return nil, err
} }
@ -208,7 +208,7 @@ func CreateServerChain(completedOptions completedServerRunOptions, stopCh <-chan
} }
if insecureServingOptions != nil { if insecureServingOptions != nil {
insecureHandlerChain := kubeserver.BuildInsecureHandlerChain(aggregatorServer.GenericAPIServer.UnprotectedHandler(), kubeAPIServerConfig.GenericConfig) insecureHandlerChain := kubeserver.BuildInsecureHandlerChain(aggregatorServer.GenericAPIServer.UnprotectedHandler(), kubeAPIServerConfig.GenericConfig, aggregatorServer.GenericAPIServer.RequestContextMapper())
if err := kubeserver.NonBlockingRun(insecureServingOptions, insecureHandlerChain, kubeAPIServerConfig.GenericConfig.RequestTimeout, stopCh); err != nil { if err := kubeserver.NonBlockingRun(insecureServingOptions, insecureHandlerChain, kubeAPIServerConfig.GenericConfig.RequestTimeout, stopCh); err != nil {
return nil, err return nil, err
} }

View File

@ -38,20 +38,20 @@ import (
// You shouldn't be using this. It makes sig-auth sad. // You shouldn't be using this. It makes sig-auth sad.
// InsecureServingInfo *ServingInfo // InsecureServingInfo *ServingInfo
func BuildInsecureHandlerChain(apiHandler http.Handler, c *server.Config) http.Handler { func BuildInsecureHandlerChain(apiHandler http.Handler, c *server.Config, contextMapper apirequest.RequestContextMapper) http.Handler {
handler := apiHandler handler := apiHandler
if utilfeature.DefaultFeatureGate.Enabled(features.AdvancedAuditing) { if utilfeature.DefaultFeatureGate.Enabled(features.AdvancedAuditing) {
handler = genericapifilters.WithAudit(handler, c.RequestContextMapper, c.AuditBackend, c.AuditPolicyChecker, c.LongRunningFunc) handler = genericapifilters.WithAudit(handler, contextMapper, c.AuditBackend, c.AuditPolicyChecker, c.LongRunningFunc)
} else { } else {
handler = genericapifilters.WithLegacyAudit(handler, c.RequestContextMapper, c.LegacyAuditWriter) handler = genericapifilters.WithLegacyAudit(handler, contextMapper, c.LegacyAuditWriter)
} }
handler = genericapifilters.WithAuthentication(handler, c.RequestContextMapper, insecureSuperuser{}, nil) handler = genericapifilters.WithAuthentication(handler, contextMapper, insecureSuperuser{}, nil)
handler = genericfilters.WithCORS(handler, c.CorsAllowedOriginList, nil, nil, nil, "true") handler = genericfilters.WithCORS(handler, c.CorsAllowedOriginList, nil, nil, nil, "true")
handler = genericfilters.WithTimeoutForNonLongRunningRequests(handler, c.RequestContextMapper, c.LongRunningFunc, c.RequestTimeout) handler = genericfilters.WithTimeoutForNonLongRunningRequests(handler, contextMapper, c.LongRunningFunc, c.RequestTimeout)
handler = genericfilters.WithMaxInFlightLimit(handler, c.MaxRequestsInFlight, c.MaxMutatingRequestsInFlight, c.RequestContextMapper, c.LongRunningFunc) handler = genericfilters.WithMaxInFlightLimit(handler, c.MaxRequestsInFlight, c.MaxMutatingRequestsInFlight, contextMapper, c.LongRunningFunc)
handler = genericfilters.WithWaitGroup(handler, c.RequestContextMapper, c.LongRunningFunc, c.HandlerChainWaitGroup) handler = genericfilters.WithWaitGroup(handler, contextMapper, c.LongRunningFunc, c.HandlerChainWaitGroup)
handler = genericapifilters.WithRequestInfo(handler, server.NewRequestInfoResolver(c), c.RequestContextMapper) handler = genericapifilters.WithRequestInfo(handler, server.NewRequestInfoResolver(c), contextMapper)
handler = apirequest.WithRequestContext(handler, c.RequestContextMapper) handler = apirequest.WithRequestContext(handler, contextMapper)
handler = genericfilters.WithPanicRecovery(handler) handler = genericfilters.WithPanicRecovery(handler)
return handler return handler

View File

@ -54,7 +54,7 @@ func TestValidOpenAPISpec(t *testing.T) {
} }
config.GenericConfig.SwaggerConfig = genericapiserver.DefaultSwaggerConfig() config.GenericConfig.SwaggerConfig = genericapiserver.DefaultSwaggerConfig()
master, err := config.Complete(sharedInformers).New(genericapiserver.EmptyDelegate) master, err := config.Complete(sharedInformers).New(genericapiserver.NewEmptyDelegate())
if err != nil { if err != nil {
t.Fatalf("Error in bringing up the master: %v", err) t.Fatalf("Error in bringing up the master: %v", err)
} }

View File

@ -106,7 +106,6 @@ func setUp(t *testing.T) (*etcdtesting.EtcdTestServer, Config, informers.SharedI
config.GenericConfig.LoopbackClientConfig = &restclient.Config{APIPath: "/api", ContentConfig: restclient.ContentConfig{NegotiatedSerializer: legacyscheme.Codecs}} config.GenericConfig.LoopbackClientConfig = &restclient.Config{APIPath: "/api", ContentConfig: restclient.ContentConfig{NegotiatedSerializer: legacyscheme.Codecs}}
config.GenericConfig.PublicAddress = net.ParseIP("192.168.10.4") config.GenericConfig.PublicAddress = net.ParseIP("192.168.10.4")
config.GenericConfig.LegacyAPIGroupPrefixes = sets.NewString("/api") config.GenericConfig.LegacyAPIGroupPrefixes = sets.NewString("/api")
config.GenericConfig.RequestContextMapper = genericapirequest.NewRequestContextMapper()
config.GenericConfig.LoopbackClientConfig = &restclient.Config{APIPath: "/api", ContentConfig: restclient.ContentConfig{NegotiatedSerializer: legacyscheme.Codecs}} config.GenericConfig.LoopbackClientConfig = &restclient.Config{APIPath: "/api", ContentConfig: restclient.ContentConfig{NegotiatedSerializer: legacyscheme.Codecs}}
config.ExtraConfig.KubeletClientConfig = kubeletclient.KubeletClientConfig{Port: 10250} config.ExtraConfig.KubeletClientConfig = kubeletclient.KubeletClientConfig{Port: 10250}
config.ExtraConfig.ProxyTransport = utilnet.SetTransportDefaults(&http.Transport{ config.ExtraConfig.ProxyTransport = utilnet.SetTransportDefaults(&http.Transport{
@ -185,7 +184,7 @@ func TestCertificatesRestStorageStrategies(t *testing.T) {
func newMaster(t *testing.T) (*Master, *etcdtesting.EtcdTestServer, Config, *assert.Assertions) { func newMaster(t *testing.T) (*Master, *etcdtesting.EtcdTestServer, Config, *assert.Assertions) {
etcdserver, config, sharedInformers, assert := setUp(t) etcdserver, config, sharedInformers, assert := setUp(t)
master, err := config.Complete(sharedInformers).New(genericapiserver.EmptyDelegate) master, err := config.Complete(sharedInformers).New(genericapiserver.NewEmptyDelegate())
if err != nil { if err != nil {
t.Fatalf("Error in bringing up the master: %v", err) t.Fatalf("Error in bringing up the master: %v", err)
} }

View File

@ -197,7 +197,7 @@ func (c completedConfig) New(delegationTarget genericapiserver.DelegationTarget)
return s, nil return s, nil
} }
crdController := NewDiscoveryController(s.Informers.Apiextensions().InternalVersion().CustomResourceDefinitions(), versionDiscoveryHandler, groupDiscoveryHandler, c.GenericConfig.RequestContextMapper) crdController := NewDiscoveryController(s.Informers.Apiextensions().InternalVersion().CustomResourceDefinitions(), versionDiscoveryHandler, groupDiscoveryHandler, delegationTarget.RequestContextMapper())
namingController := status.NewNamingConditionController(s.Informers.Apiextensions().InternalVersion().CustomResourceDefinitions(), crdClient.Apiextensions()) namingController := status.NewNamingConditionController(s.Informers.Apiextensions().InternalVersion().CustomResourceDefinitions(), crdClient.Apiextensions())
finalizingController := finalizer.NewCRDFinalizer( finalizingController := finalizer.NewCRDFinalizer(
s.Informers.Apiextensions().InternalVersion().CustomResourceDefinitions(), s.Informers.Apiextensions().InternalVersion().CustomResourceDefinitions(),

View File

@ -137,7 +137,7 @@ func (o CustomResourceDefinitionsServerOptions) RunCustomResourceDefinitionsServ
return err return err
} }
server, err := config.Complete().New(genericapiserver.EmptyDelegate) server, err := config.Complete().New(genericapiserver.NewEmptyDelegate())
if err != nil { if err != nil {
return err return err
} }

View File

@ -90,7 +90,7 @@ func DefaultServerConfig() (*extensionsapiserver.Config, error) {
func StartServer(config *extensionsapiserver.Config) (chan struct{}, *rest.Config, error) { func StartServer(config *extensionsapiserver.Config) (chan struct{}, *rest.Config, error) {
stopCh := make(chan struct{}) stopCh := make(chan struct{})
server, err := config.Complete().New(genericapiserver.EmptyDelegate) server, err := config.Complete().New(genericapiserver.NewEmptyDelegate())
if err != nil { if err != nil {
return nil, nil, err return nil, nil, err
} }

View File

@ -127,7 +127,7 @@ type Config struct {
//=========================================================================== //===========================================================================
// BuildHandlerChainFunc allows you to build custom handler chains by decorating the apiHandler. // BuildHandlerChainFunc allows you to build custom handler chains by decorating the apiHandler.
BuildHandlerChainFunc func(apiHandler http.Handler, c *Config) (secure http.Handler) BuildHandlerChainFunc func(apiHandler http.Handler, c *Config, contextMapper apirequest.RequestContextMapper) (secure http.Handler)
// HandlerChainWaitGroup allows you to wait for all chain handlers exit after the server shutdown. // HandlerChainWaitGroup allows you to wait for all chain handlers exit after the server shutdown.
HandlerChainWaitGroup *utilwaitgroup.SafeWaitGroup HandlerChainWaitGroup *utilwaitgroup.SafeWaitGroup
// DiscoveryAddresses is used to build the IPs pass to discovery. If nil, the ExternalAddress is // DiscoveryAddresses is used to build the IPs pass to discovery. If nil, the ExternalAddress is
@ -138,9 +138,6 @@ type Config struct {
// LegacyAPIGroupPrefixes is used to set up URL parsing for authorization and for validating requests // LegacyAPIGroupPrefixes is used to set up URL parsing for authorization and for validating requests
// to InstallLegacyAPIGroup. New API servers don't generally have legacy groups at all. // to InstallLegacyAPIGroup. New API servers don't generally have legacy groups at all.
LegacyAPIGroupPrefixes sets.String LegacyAPIGroupPrefixes sets.String
// RequestContextMapper maps requests to contexts. Exported so downstream consumers can provider their own mappers
// TODO confirm that anyone downstream actually uses this and doesn't just need an accessor
RequestContextMapper apirequest.RequestContextMapper
// RequestInfoResolver is used to assign attributes (used by admission and authorization) based on a request URL. // RequestInfoResolver is used to assign attributes (used by admission and authorization) based on a request URL.
// Use-cases that are like kubelets may need to customize this. // Use-cases that are like kubelets may need to customize this.
RequestInfoResolver apirequest.RequestInfoResolver RequestInfoResolver apirequest.RequestInfoResolver
@ -253,7 +250,6 @@ func NewConfig(codecs serializer.CodecFactory) *Config {
return &Config{ return &Config{
Serializer: codecs, Serializer: codecs,
ReadWritePort: 443, ReadWritePort: 443,
RequestContextMapper: apirequest.NewRequestContextMapper(),
BuildHandlerChainFunc: DefaultBuildHandlerChain, BuildHandlerChainFunc: DefaultBuildHandlerChain,
HandlerChainWaitGroup: new(utilwaitgroup.SafeWaitGroup), HandlerChainWaitGroup: new(utilwaitgroup.SafeWaitGroup),
LegacyAPIGroupPrefixes: sets.NewString(DefaultLegacyAPIPrefix), LegacyAPIGroupPrefixes: sets.NewString(DefaultLegacyAPIPrefix),
@ -447,9 +443,8 @@ func (c *RecommendedConfig) Complete() CompletedConfig {
// New creates a new server which logically combines the handling chain with the passed server. // New creates a new server which logically combines the handling chain with the passed server.
// name is used to differentiate for logging. The handler chain in particular can be difficult as it starts delgating. // name is used to differentiate for logging. The handler chain in particular can be difficult as it starts delgating.
// delegationTarget may not be nil.
func (c completedConfig) New(name string, delegationTarget DelegationTarget) (*GenericAPIServer, error) { func (c completedConfig) New(name string, delegationTarget DelegationTarget) (*GenericAPIServer, error) {
// The delegationTarget and the config must agree on the RequestContextMapper
if c.Serializer == nil { if c.Serializer == nil {
return nil, fmt.Errorf("Genericapiserver.New() called with config.Serializer == nil") return nil, fmt.Errorf("Genericapiserver.New() called with config.Serializer == nil")
} }
@ -457,17 +452,17 @@ func (c completedConfig) New(name string, delegationTarget DelegationTarget) (*G
return nil, fmt.Errorf("Genericapiserver.New() called with config.LoopbackClientConfig == nil") return nil, fmt.Errorf("Genericapiserver.New() called with config.LoopbackClientConfig == nil")
} }
contextMapper := delegationTarget.RequestContextMapper()
handlerChainBuilder := func(handler http.Handler) http.Handler { handlerChainBuilder := func(handler http.Handler) http.Handler {
return c.BuildHandlerChainFunc(handler, c.Config) return c.BuildHandlerChainFunc(handler, c.Config, contextMapper)
} }
apiServerHandler := NewAPIServerHandler(name, c.RequestContextMapper, c.Serializer, handlerChainBuilder, delegationTarget.UnprotectedHandler()) apiServerHandler := NewAPIServerHandler(name, contextMapper, c.Serializer, handlerChainBuilder, delegationTarget.UnprotectedHandler())
s := &GenericAPIServer{ s := &GenericAPIServer{
discoveryAddresses: c.DiscoveryAddresses, discoveryAddresses: c.DiscoveryAddresses,
LoopbackClientConfig: c.LoopbackClientConfig, LoopbackClientConfig: c.LoopbackClientConfig,
legacyAPIGroupPrefixes: c.LegacyAPIGroupPrefixes, legacyAPIGroupPrefixes: c.LegacyAPIGroupPrefixes,
admissionControl: c.AdmissionControl, admissionControl: c.AdmissionControl,
requestContextMapper: c.RequestContextMapper,
Serializer: c.Serializer, Serializer: c.Serializer,
AuditBackend: c.AuditBackend, AuditBackend: c.AuditBackend,
delegationTarget: delegationTarget, delegationTarget: delegationTarget,
@ -492,7 +487,7 @@ func (c completedConfig) New(name string, delegationTarget DelegationTarget) (*G
healthzChecks: c.HealthzChecks, healthzChecks: c.HealthzChecks,
DiscoveryGroupManager: discovery.NewRootAPIsHandler(c.DiscoveryAddresses, c.Serializer, c.RequestContextMapper), DiscoveryGroupManager: discovery.NewRootAPIsHandler(c.DiscoveryAddresses, c.Serializer, contextMapper),
enableAPIResponseCompression: c.EnableAPIResponseCompression, enableAPIResponseCompression: c.EnableAPIResponseCompression,
} }
@ -547,25 +542,25 @@ func (c completedConfig) New(name string, delegationTarget DelegationTarget) (*G
return s, nil return s, nil
} }
func DefaultBuildHandlerChain(apiHandler http.Handler, c *Config) http.Handler { func DefaultBuildHandlerChain(apiHandler http.Handler, c *Config, contextMapper apirequest.RequestContextMapper) http.Handler {
handler := genericapifilters.WithAuthorization(apiHandler, c.RequestContextMapper, c.Authorization.Authorizer, c.Serializer) handler := genericapifilters.WithAuthorization(apiHandler, contextMapper, c.Authorization.Authorizer, c.Serializer)
handler = genericfilters.WithMaxInFlightLimit(handler, c.MaxRequestsInFlight, c.MaxMutatingRequestsInFlight, c.RequestContextMapper, c.LongRunningFunc) handler = genericfilters.WithMaxInFlightLimit(handler, c.MaxRequestsInFlight, c.MaxMutatingRequestsInFlight, contextMapper, c.LongRunningFunc)
handler = genericapifilters.WithImpersonation(handler, c.RequestContextMapper, c.Authorization.Authorizer, c.Serializer) handler = genericapifilters.WithImpersonation(handler, contextMapper, c.Authorization.Authorizer, c.Serializer)
if utilfeature.DefaultFeatureGate.Enabled(features.AdvancedAuditing) { if utilfeature.DefaultFeatureGate.Enabled(features.AdvancedAuditing) {
handler = genericapifilters.WithAudit(handler, c.RequestContextMapper, c.AuditBackend, c.AuditPolicyChecker, c.LongRunningFunc) handler = genericapifilters.WithAudit(handler, contextMapper, c.AuditBackend, c.AuditPolicyChecker, c.LongRunningFunc)
} else { } else {
handler = genericapifilters.WithLegacyAudit(handler, c.RequestContextMapper, c.LegacyAuditWriter) handler = genericapifilters.WithLegacyAudit(handler, contextMapper, c.LegacyAuditWriter)
} }
failedHandler := genericapifilters.Unauthorized(c.RequestContextMapper, c.Serializer, c.Authentication.SupportsBasicAuth) failedHandler := genericapifilters.Unauthorized(contextMapper, c.Serializer, c.Authentication.SupportsBasicAuth)
if utilfeature.DefaultFeatureGate.Enabled(features.AdvancedAuditing) { if utilfeature.DefaultFeatureGate.Enabled(features.AdvancedAuditing) {
failedHandler = genericapifilters.WithFailedAuthenticationAudit(failedHandler, c.RequestContextMapper, c.AuditBackend, c.AuditPolicyChecker) failedHandler = genericapifilters.WithFailedAuthenticationAudit(failedHandler, contextMapper, c.AuditBackend, c.AuditPolicyChecker)
} }
handler = genericapifilters.WithAuthentication(handler, c.RequestContextMapper, c.Authentication.Authenticator, failedHandler) handler = genericapifilters.WithAuthentication(handler, contextMapper, c.Authentication.Authenticator, failedHandler)
handler = genericfilters.WithCORS(handler, c.CorsAllowedOriginList, nil, nil, nil, "true") handler = genericfilters.WithCORS(handler, c.CorsAllowedOriginList, nil, nil, nil, "true")
handler = genericfilters.WithTimeoutForNonLongRunningRequests(handler, c.RequestContextMapper, c.LongRunningFunc, c.RequestTimeout) handler = genericfilters.WithTimeoutForNonLongRunningRequests(handler, contextMapper, c.LongRunningFunc, c.RequestTimeout)
handler = genericfilters.WithWaitGroup(handler, c.RequestContextMapper, c.LongRunningFunc, c.HandlerChainWaitGroup) handler = genericfilters.WithWaitGroup(handler, contextMapper, c.LongRunningFunc, c.HandlerChainWaitGroup)
handler = genericapifilters.WithRequestInfo(handler, c.RequestInfoResolver, c.RequestContextMapper) handler = genericapifilters.WithRequestInfo(handler, c.RequestInfoResolver, contextMapper)
handler = apirequest.WithRequestContext(handler, c.RequestContextMapper) handler = apirequest.WithRequestContext(handler, contextMapper)
handler = genericfilters.WithPanicRecovery(handler) handler = genericfilters.WithPanicRecovery(handler)
return handler return handler
} }

View File

@ -26,7 +26,6 @@ import (
"testing" "testing"
"k8s.io/apimachinery/pkg/util/sets" "k8s.io/apimachinery/pkg/util/sets"
genericapirequest "k8s.io/apiserver/pkg/endpoints/request"
"k8s.io/apiserver/pkg/server/healthz" "k8s.io/apiserver/pkg/server/healthz"
"k8s.io/client-go/informers" "k8s.io/client-go/informers"
"k8s.io/client-go/kubernetes/fake" "k8s.io/client-go/kubernetes/fake"
@ -36,7 +35,6 @@ import (
func TestNewWithDelegate(t *testing.T) { func TestNewWithDelegate(t *testing.T) {
delegateConfig := NewConfig(codecs) delegateConfig := NewConfig(codecs)
delegateConfig.PublicAddress = net.ParseIP("192.168.10.4") delegateConfig.PublicAddress = net.ParseIP("192.168.10.4")
delegateConfig.RequestContextMapper = genericapirequest.NewRequestContextMapper()
delegateConfig.LegacyAPIGroupPrefixes = sets.NewString("/api") delegateConfig.LegacyAPIGroupPrefixes = sets.NewString("/api")
delegateConfig.LoopbackClientConfig = &rest.Config{} delegateConfig.LoopbackClientConfig = &rest.Config{}
delegateConfig.SwaggerConfig = DefaultSwaggerConfig() delegateConfig.SwaggerConfig = DefaultSwaggerConfig()
@ -50,7 +48,7 @@ func TestNewWithDelegate(t *testing.T) {
})) }))
sharedInformers := informers.NewSharedInformerFactory(clientset, delegateConfig.LoopbackClientConfig.Timeout) sharedInformers := informers.NewSharedInformerFactory(clientset, delegateConfig.LoopbackClientConfig.Timeout)
delegateServer, err := delegateConfig.Complete(sharedInformers).New("test", EmptyDelegate) delegateServer, err := delegateConfig.Complete(sharedInformers).New("test", NewEmptyDelegate())
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
@ -67,7 +65,6 @@ func TestNewWithDelegate(t *testing.T) {
wrappingConfig := NewConfig(codecs) wrappingConfig := NewConfig(codecs)
wrappingConfig.PublicAddress = net.ParseIP("192.168.10.4") wrappingConfig.PublicAddress = net.ParseIP("192.168.10.4")
wrappingConfig.RequestContextMapper = genericapirequest.NewRequestContextMapper()
wrappingConfig.LegacyAPIGroupPrefixes = sets.NewString("/api") wrappingConfig.LegacyAPIGroupPrefixes = sets.NewString("/api")
wrappingConfig.LoopbackClientConfig = &rest.Config{} wrappingConfig.LoopbackClientConfig = &rest.Config{}
wrappingConfig.SwaggerConfig = DefaultSwaggerConfig() wrappingConfig.SwaggerConfig = DefaultSwaggerConfig()

View File

@ -95,9 +95,7 @@ type GenericAPIServer struct {
// admissionControl is used to build the RESTStorage that backs an API Group. // admissionControl is used to build the RESTStorage that backs an API Group.
admissionControl admission.Interface admissionControl admission.Interface
// requestContextMapper provides a way to get the context for a request. It may be nil. // SecureServingInfo holds configuration of the TLS server.
requestContextMapper apirequest.RequestContextMapper
SecureServingInfo *SecureServingInfo SecureServingInfo *SecureServingInfo
// ExternalAddress is the address (hostname or IP and port) that should be used in // ExternalAddress is the address (hostname or IP and port) that should be used in
@ -146,7 +144,7 @@ type GenericAPIServer struct {
// if the client requests it via Accept-Encoding // if the client requests it via Accept-Encoding
enableAPIResponseCompression bool enableAPIResponseCompression bool
// delegationTarget is the next delegate in the chain or nil // delegationTarget is the next delegate in the chain. This is never nil.
delegationTarget DelegationTarget delegationTarget DelegationTarget
// HandlerChainWaitGroup allows you to wait for all chain handlers finish after the server shutdown. // HandlerChainWaitGroup allows you to wait for all chain handlers finish after the server shutdown.
@ -200,14 +198,16 @@ func (s *GenericAPIServer) NextDelegate() DelegationTarget {
return s.delegationTarget return s.delegationTarget
} }
var EmptyDelegate = emptyDelegate{
requestContextMapper: apirequest.NewRequestContextMapper(),
}
type emptyDelegate struct { type emptyDelegate struct {
requestContextMapper apirequest.RequestContextMapper requestContextMapper apirequest.RequestContextMapper
} }
func NewEmptyDelegate() DelegationTarget {
return emptyDelegate{
requestContextMapper: apirequest.NewRequestContextMapper(),
}
}
func (s emptyDelegate) UnprotectedHandler() http.Handler { func (s emptyDelegate) UnprotectedHandler() http.Handler {
return nil return nil
} }
@ -230,10 +230,8 @@ func (s emptyDelegate) NextDelegate() DelegationTarget {
return nil return nil
} }
// RequestContextMapper is exposed so that third party resource storage can be build in a different location.
// TODO refactor third party resource storage
func (s *GenericAPIServer) RequestContextMapper() apirequest.RequestContextMapper { func (s *GenericAPIServer) RequestContextMapper() apirequest.RequestContextMapper {
return s.requestContextMapper return s.delegationTarget.RequestContextMapper()
} }
// preparedGenericAPIServer is a private wrapper that enforces a call of PrepareRun() before Run can be invoked. // preparedGenericAPIServer is a private wrapper that enforces a call of PrepareRun() before Run can be invoked.
@ -366,7 +364,7 @@ func (s *GenericAPIServer) InstallLegacyAPIGroup(apiPrefix string, apiGroupInfo
} }
// Install the version handler. // Install the version handler.
// Add a handler at /<apiPrefix> to enumerate the supported api versions. // Add a handler at /<apiPrefix> to enumerate the supported api versions.
s.Handler.GoRestfulContainer.Add(discovery.NewLegacyRootAPIHandler(s.discoveryAddresses, s.Serializer, apiPrefix, apiVersions, s.requestContextMapper).WebService()) s.Handler.GoRestfulContainer.Add(discovery.NewLegacyRootAPIHandler(s.discoveryAddresses, s.Serializer, apiPrefix, apiVersions, s.delegationTarget.RequestContextMapper()).WebService())
return nil return nil
} }
@ -411,7 +409,7 @@ func (s *GenericAPIServer) InstallAPIGroup(apiGroupInfo *APIGroupInfo) error {
} }
s.DiscoveryGroupManager.AddGroup(apiGroup) s.DiscoveryGroupManager.AddGroup(apiGroup)
s.Handler.GoRestfulContainer.Add(discovery.NewAPIGroupHandler(s.Serializer, apiGroup, s.requestContextMapper).WebService()) s.Handler.GoRestfulContainer.Add(discovery.NewAPIGroupHandler(s.Serializer, apiGroup, s.delegationTarget.RequestContextMapper()).WebService())
return nil return nil
} }

View File

@ -84,7 +84,6 @@ func init() {
func setUp(t *testing.T) (Config, *assert.Assertions) { func setUp(t *testing.T) (Config, *assert.Assertions) {
config := NewConfig(codecs) config := NewConfig(codecs)
config.PublicAddress = net.ParseIP("192.168.10.4") config.PublicAddress = net.ParseIP("192.168.10.4")
config.RequestContextMapper = apirequest.NewRequestContextMapper()
config.LegacyAPIGroupPrefixes = sets.NewString("/api") config.LegacyAPIGroupPrefixes = sets.NewString("/api")
config.LoopbackClientConfig = &restclient.Config{} config.LoopbackClientConfig = &restclient.Config{}
@ -111,7 +110,7 @@ func setUp(t *testing.T) (Config, *assert.Assertions) {
func newMaster(t *testing.T) (*GenericAPIServer, Config, *assert.Assertions) { func newMaster(t *testing.T) (*GenericAPIServer, Config, *assert.Assertions) {
config, assert := setUp(t) config, assert := setUp(t)
s, err := config.Complete(nil).New("test", EmptyDelegate) s, err := config.Complete(nil).New("test", NewEmptyDelegate())
if err != nil { if err != nil {
t.Fatalf("Error in bringing up the server: %v", err) t.Fatalf("Error in bringing up the server: %v", err)
} }
@ -126,7 +125,6 @@ func TestNew(t *testing.T) {
// Verify many of the variables match their config counterparts // Verify many of the variables match their config counterparts
assert.Equal(s.legacyAPIGroupPrefixes, config.LegacyAPIGroupPrefixes) assert.Equal(s.legacyAPIGroupPrefixes, config.LegacyAPIGroupPrefixes)
assert.Equal(s.admissionControl, config.AdmissionControl) assert.Equal(s.admissionControl, config.AdmissionControl)
assert.Equal(s.RequestContextMapper(), config.RequestContextMapper)
// these values get defaulted // these values get defaulted
assert.Equal(net.JoinHostPort(config.PublicAddress.String(), "443"), s.ExternalAddress) assert.Equal(net.JoinHostPort(config.PublicAddress.String(), "443"), s.ExternalAddress)
@ -141,7 +139,7 @@ func TestInstallAPIGroups(t *testing.T) {
config.LegacyAPIGroupPrefixes = sets.NewString("/apiPrefix") config.LegacyAPIGroupPrefixes = sets.NewString("/apiPrefix")
config.DiscoveryAddresses = discovery.DefaultAddresses{DefaultAddress: "ExternalAddress"} config.DiscoveryAddresses = discovery.DefaultAddresses{DefaultAddress: "ExternalAddress"}
s, err := config.Complete(nil).New("test", EmptyDelegate) s, err := config.Complete(nil).New("test", NewEmptyDelegate())
if err != nil { if err != nil {
t.Fatalf("Error in bringing up the server: %v", err) t.Fatalf("Error in bringing up the server: %v", err)
} }
@ -333,7 +331,7 @@ func TestCustomHandlerChain(t *testing.T) {
var protected, called bool var protected, called bool
config.BuildHandlerChainFunc = func(apiHandler http.Handler, c *Config) http.Handler { config.BuildHandlerChainFunc = func(apiHandler http.Handler, c *Config, contextMapper apirequest.RequestContextMapper) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
protected = true protected = true
apiHandler.ServeHTTP(w, req) apiHandler.ServeHTTP(w, req)
@ -343,7 +341,7 @@ func TestCustomHandlerChain(t *testing.T) {
called = true called = true
}) })
s, err := config.Complete(nil).New("test", EmptyDelegate) s, err := config.Complete(nil).New("test", NewEmptyDelegate())
if err != nil { if err != nil {
t.Fatalf("Error in bringing up the server: %v", err) t.Fatalf("Error in bringing up the server: %v", err)
} }
@ -397,7 +395,7 @@ func TestNotRestRoutesHaveAuth(t *testing.T) {
kubeVersion := fakeVersion() kubeVersion := fakeVersion()
config.Version = &kubeVersion config.Version = &kubeVersion
s, err := config.Complete(nil).New("test", EmptyDelegate) s, err := config.Complete(nil).New("test", NewEmptyDelegate())
if err != nil { if err != nil {
t.Fatalf("Error in bringing up the server: %v", err) t.Fatalf("Error in bringing up the server: %v", err)
} }
@ -509,10 +507,10 @@ func TestGracefulShutdown(t *testing.T) {
wg := sync.WaitGroup{} wg := sync.WaitGroup{}
wg.Add(1) wg.Add(1)
config.BuildHandlerChainFunc = func(apiHandler http.Handler, c *Config) http.Handler { config.BuildHandlerChainFunc = func(apiHandler http.Handler, c *Config, contextMapper apirequest.RequestContextMapper) http.Handler {
handler := genericfilters.WithWaitGroup(apiHandler, c.RequestContextMapper, c.LongRunningFunc, c.HandlerChainWaitGroup) handler := genericfilters.WithWaitGroup(apiHandler, contextMapper, c.LongRunningFunc, c.HandlerChainWaitGroup)
handler = genericapifilters.WithRequestInfo(handler, c.RequestInfoResolver, c.RequestContextMapper) handler = genericapifilters.WithRequestInfo(handler, c.RequestInfoResolver, contextMapper)
handler = apirequest.WithRequestContext(handler, c.RequestContextMapper) handler = apirequest.WithRequestContext(handler, contextMapper)
return handler return handler
} }
@ -523,7 +521,7 @@ func TestGracefulShutdown(t *testing.T) {
graceShutdown = true graceShutdown = true
}) })
s, err := config.Complete(nil).New("test", EmptyDelegate) s, err := config.Complete(nil).New("test", NewEmptyDelegate())
if err != nil { if err != nil {
t.Fatalf("Error in bringing up the server: %v", err) t.Fatalf("Error in bringing up the server: %v", err)
} }

View File

@ -89,7 +89,6 @@ go_test(
"//vendor/k8s.io/apimachinery/pkg/util/sets:go_default_library", "//vendor/k8s.io/apimachinery/pkg/util/sets:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/version:go_default_library", "//vendor/k8s.io/apimachinery/pkg/version:go_default_library",
"//vendor/k8s.io/apiserver/pkg/admission:go_default_library", "//vendor/k8s.io/apiserver/pkg/admission:go_default_library",
"//vendor/k8s.io/apiserver/pkg/endpoints/request:go_default_library",
"//vendor/k8s.io/apiserver/pkg/server:go_default_library", "//vendor/k8s.io/apiserver/pkg/server:go_default_library",
"//vendor/k8s.io/apiserver/pkg/util/flag:go_default_library", "//vendor/k8s.io/apiserver/pkg/util/flag:go_default_library",
"//vendor/k8s.io/client-go/discovery:go_default_library", "//vendor/k8s.io/client-go/discovery:go_default_library",

View File

@ -42,7 +42,6 @@ import (
"k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/serializer" "k8s.io/apimachinery/pkg/runtime/serializer"
"k8s.io/apimachinery/pkg/version" "k8s.io/apimachinery/pkg/version"
genericapirequest "k8s.io/apiserver/pkg/endpoints/request"
"k8s.io/apiserver/pkg/server" "k8s.io/apiserver/pkg/server"
. "k8s.io/apiserver/pkg/server" . "k8s.io/apiserver/pkg/server"
utilflag "k8s.io/apiserver/pkg/util/flag" utilflag "k8s.io/apiserver/pkg/util/flag"
@ -55,7 +54,6 @@ func setUp(t *testing.T) Config {
codecs := serializer.NewCodecFactory(scheme) codecs := serializer.NewCodecFactory(scheme)
config := NewConfig(codecs) config := NewConfig(codecs)
config.RequestContextMapper = genericapirequest.NewRequestContextMapper()
return *config return *config
} }
@ -497,7 +495,7 @@ NextTest:
return return
} }
s, err := config.Complete(nil).New("test", server.EmptyDelegate) s, err := config.Complete(nil).New("test", server.NewEmptyDelegate())
if err != nil { if err != nil {
t.Errorf("%q - failed creating the server: %v", title, err) t.Errorf("%q - failed creating the server: %v", title, err)
return return

View File

@ -158,7 +158,7 @@ func (c completedConfig) NewWithDelegate(delegationTarget genericapiserver.Deleg
s := &APIAggregator{ s := &APIAggregator{
GenericAPIServer: genericServer, GenericAPIServer: genericServer,
delegateHandler: delegationTarget.UnprotectedHandler(), delegateHandler: delegationTarget.UnprotectedHandler(),
contextMapper: c.GenericConfig.RequestContextMapper, contextMapper: genericServer.RequestContextMapper(),
proxyClientCert: c.ExtraConfig.ProxyClientCert, proxyClientCert: c.ExtraConfig.ProxyClientCert,
proxyClientKey: c.ExtraConfig.ProxyClientKey, proxyClientKey: c.ExtraConfig.ProxyClientKey,
proxyTransport: c.ExtraConfig.ProxyTransport, proxyTransport: c.ExtraConfig.ProxyTransport,

View File

@ -144,7 +144,7 @@ func (o AggregatorOptions) RunAggregator(stopCh <-chan struct{}) error {
return err return err
} }
server, err := config.Complete().NewWithDelegate(genericapiserver.EmptyDelegate) server, err := config.Complete().NewWithDelegate(genericapiserver.NewEmptyDelegate())
if err != nil { if err != nil {
return err return err
} }

View File

@ -101,7 +101,7 @@ func (cfg *Config) Complete() CompletedConfig {
// New returns a new instance of WardleServer from the given config. // New returns a new instance of WardleServer from the given config.
func (c completedConfig) New() (*WardleServer, error) { func (c completedConfig) New() (*WardleServer, error) {
genericServer, err := c.GenericConfig.New("sample-apiserver", genericapiserver.EmptyDelegate) genericServer, err := c.GenericConfig.New("sample-apiserver", genericapiserver.NewEmptyDelegate())
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@ -751,7 +751,7 @@ func startRealMasterOrDie(t *testing.T, certDir string) (*allClient, clientv3.KV
kubeAPIServerConfig.ExtraConfig.APIResourceConfigSource = &allResourceSource{} // force enable all resources kubeAPIServerConfig.ExtraConfig.APIResourceConfigSource = &allResourceSource{} // force enable all resources
kubeAPIServer, err := app.CreateKubeAPIServer(kubeAPIServerConfig, genericapiserver.EmptyDelegate, sharedInformers, versionedInformers) kubeAPIServer, err := app.CreateKubeAPIServer(kubeAPIServerConfig, genericapiserver.NewEmptyDelegate(), sharedInformers, versionedInformers)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }

View File

@ -130,7 +130,7 @@ func TestAggregatedAPIServer(t *testing.T) {
kubeAPIServerClientConfig.ServerName = "" kubeAPIServerClientConfig.ServerName = ""
kubeClientConfigValue.Store(kubeAPIServerClientConfig) kubeClientConfigValue.Store(kubeAPIServerClientConfig)
kubeAPIServer, err := app.CreateKubeAPIServer(kubeAPIServerConfig, genericapiserver.EmptyDelegate, sharedInformers, versionedInformers) kubeAPIServer, err := app.CreateKubeAPIServer(kubeAPIServerConfig, genericapiserver.NewEmptyDelegate(), sharedInformers, versionedInformers)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }

View File

@ -177,7 +177,7 @@ func startMasterOrDie(masterConfig *master.Config, incomingServer *httptest.Serv
} }
sharedInformers := informers.NewSharedInformerFactory(clientset, masterConfig.GenericConfig.LoopbackClientConfig.Timeout) sharedInformers := informers.NewSharedInformerFactory(clientset, masterConfig.GenericConfig.LoopbackClientConfig.Timeout)
m, err = masterConfig.Complete(sharedInformers).New(genericapiserver.EmptyDelegate) m, err = masterConfig.Complete(sharedInformers).New(genericapiserver.NewEmptyDelegate())
if err != nil { if err != nil {
closeFn() closeFn()
glog.Fatalf("error in bringing up the master: %v", err) glog.Fatalf("error in bringing up the master: %v", err)