apiserver: enforce shared RequestContextMapper in delegation chain

This commit is contained in:
Dr. Stefan Schimanski 2018-04-04 10:05:06 +02:00
parent 90d3b5a802
commit 9f906618f0
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)