apiserver: stratify versioned informer construction

This commit is contained in:
Dr. Stefan Schimanski 2017-09-06 18:22:23 +02:00
parent dffe50f8bd
commit ca3f745346
24 changed files with 115 additions and 84 deletions

View File

@ -76,7 +76,10 @@ func createAggregatorConfig(kubeAPIServerConfig genericapiserver.Config, command
} }
aggregatorConfig := &aggregatorapiserver.Config{ aggregatorConfig := &aggregatorapiserver.Config{
GenericConfig: &genericConfig, GenericConfig: &genericapiserver.RecommendedConfig{
Config: genericConfig,
SharedInformerFactory: externalInformers,
},
ExtraConfig: aggregatorapiserver.ExtraConfig{ ExtraConfig: aggregatorapiserver.ExtraConfig{
CoreKubeInformers: externalInformers, CoreKubeInformers: externalInformers,
ProxyClientCert: certBytes, ProxyClientCert: certBytes,

View File

@ -25,10 +25,11 @@ import (
apiextensionscmd "k8s.io/apiextensions-apiserver/pkg/cmd/server" apiextensionscmd "k8s.io/apiextensions-apiserver/pkg/cmd/server"
genericapiserver "k8s.io/apiserver/pkg/server" genericapiserver "k8s.io/apiserver/pkg/server"
genericoptions "k8s.io/apiserver/pkg/server/options" genericoptions "k8s.io/apiserver/pkg/server/options"
kubeexternalinformers "k8s.io/client-go/informers"
"k8s.io/kubernetes/cmd/kube-apiserver/app/options" "k8s.io/kubernetes/cmd/kube-apiserver/app/options"
) )
func createAPIExtensionsConfig(kubeAPIServerConfig genericapiserver.Config, commandOptions *options.ServerRunOptions) (*apiextensionsapiserver.Config, error) { func createAPIExtensionsConfig(kubeAPIServerConfig genericapiserver.Config, externalInformers kubeexternalinformers.SharedInformerFactory, commandOptions *options.ServerRunOptions) (*apiextensionsapiserver.Config, error) {
// make a shallow copy to let us twiddle a few things // make a shallow copy to let us twiddle a few things
// most of the config actually remains the same. We only need to mess with a couple items related to the particulars of the apiextensions // most of the config actually remains the same. We only need to mess with a couple items related to the particulars of the apiextensions
genericConfig := kubeAPIServerConfig genericConfig := kubeAPIServerConfig
@ -40,7 +41,10 @@ func createAPIExtensionsConfig(kubeAPIServerConfig genericapiserver.Config, comm
genericConfig.RESTOptionsGetter = &genericoptions.SimpleRestOptionsFactory{Options: etcdOptions} genericConfig.RESTOptionsGetter = &genericoptions.SimpleRestOptionsFactory{Options: etcdOptions}
apiextensionsConfig := &apiextensionsapiserver.Config{ apiextensionsConfig := &apiextensionsapiserver.Config{
GenericConfig: &genericConfig, GenericConfig: &genericapiserver.RecommendedConfig{
Config: genericConfig,
SharedInformerFactory: externalInformers,
},
ExtraConfig: apiextensionsapiserver.ExtraConfig{ ExtraConfig: apiextensionsapiserver.ExtraConfig{
CRDRESTOptionsGetter: apiextensionscmd.NewCRDRESTOptionsGetter(etcdOptions), CRDRESTOptionsGetter: apiextensionscmd.NewCRDRESTOptionsGetter(etcdOptions),
}, },

View File

@ -133,7 +133,7 @@ func CreateServerChain(runOptions *options.ServerRunOptions, stopCh <-chan struc
// TPRs are enabled and not yet beta, since this these are the successor, they fall under the same enablement rule // TPRs are enabled and not yet beta, since this these are the successor, they fall under the same enablement rule
// If additional API servers are added, they should be gated. // If additional API servers are added, they should be gated.
apiExtensionsConfig, err := createAPIExtensionsConfig(*kubeAPIServerConfig.GenericConfig, runOptions) apiExtensionsConfig, err := createAPIExtensionsConfig(*kubeAPIServerConfig.GenericConfig, versionedInformers, runOptions)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -142,7 +142,7 @@ func CreateServerChain(runOptions *options.ServerRunOptions, stopCh <-chan struc
return nil, err return nil, err
} }
kubeAPIServer, err := CreateKubeAPIServer(kubeAPIServerConfig, apiExtensionsServer.GenericAPIServer, sharedInformers) kubeAPIServer, err := CreateKubeAPIServer(kubeAPIServerConfig, apiExtensionsServer.GenericAPIServer, sharedInformers, versionedInformers)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -191,8 +191,8 @@ func CreateServerChain(runOptions *options.ServerRunOptions, stopCh <-chan struc
} }
// CreateKubeAPIServer creates and wires a workable kube-apiserver // CreateKubeAPIServer creates and wires a workable kube-apiserver
func CreateKubeAPIServer(kubeAPIServerConfig *master.Config, delegateAPIServer genericapiserver.DelegationTarget, sharedInformers informers.SharedInformerFactory) (*master.Master, error) { func CreateKubeAPIServer(kubeAPIServerConfig *master.Config, delegateAPIServer genericapiserver.DelegationTarget, sharedInformers informers.SharedInformerFactory, versionedInformers clientgoinformers.SharedInformerFactory) (*master.Master, error) {
kubeAPIServer, err := kubeAPIServerConfig.Complete().New(delegateAPIServer) kubeAPIServer, err := kubeAPIServerConfig.Complete(versionedInformers).New(delegateAPIServer)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -466,6 +466,7 @@ func BuildGenericConfig(s *options.ServerRunOptions) (*genericapiserver.Config,
err = s.Admission.ApplyTo( err = s.Admission.ApplyTo(
genericConfig, genericConfig,
versionedInformers,
pluginInitializer) pluginInitializer)
if err != nil { if err != nil {
return nil, nil, nil, nil, nil, fmt.Errorf("failed to initialize admission: %v", err) return nil, nil, nil, nil, nil, fmt.Errorf("failed to initialize admission: %v", err)

View File

@ -39,6 +39,8 @@ import (
genericapiserver "k8s.io/apiserver/pkg/server" genericapiserver "k8s.io/apiserver/pkg/server"
"k8s.io/apiserver/pkg/server/filters" "k8s.io/apiserver/pkg/server/filters"
serverstorage "k8s.io/apiserver/pkg/server/storage" serverstorage "k8s.io/apiserver/pkg/server/storage"
clientgoinformers "k8s.io/client-go/informers"
clientgoclientset "k8s.io/client-go/kubernetes"
clientset "k8s.io/client-go/kubernetes" clientset "k8s.io/client-go/kubernetes"
openapicommon "k8s.io/kube-openapi/pkg/common" openapicommon "k8s.io/kube-openapi/pkg/common"
federationv1beta1 "k8s.io/kubernetes/federation/apis/federation/v1beta1" federationv1beta1 "k8s.io/kubernetes/federation/apis/federation/v1beta1"
@ -189,6 +191,12 @@ func NonBlockingRun(s *options.ServerRunOptions, stopCh <-chan struct{}) error {
} }
sharedInformers := informers.NewSharedInformerFactory(client, 10*time.Minute) sharedInformers := informers.NewSharedInformerFactory(client, 10*time.Minute)
clientgoExternalClient, err := clientgoclientset.NewForConfig(genericConfig.LoopbackClientConfig)
if err != nil {
return fmt.Errorf("failed to create real external clientset: %v", err)
}
versionedInformers := clientgoinformers.NewSharedInformerFactory(clientgoExternalClient, 10*time.Minute)
authorizationConfig := s.Authorization.ToAuthorizationConfig(sharedInformers) authorizationConfig := s.Authorization.ToAuthorizationConfig(sharedInformers)
apiAuthorizer, _, err := authorizationConfig.New() apiAuthorizer, _, err := authorizationConfig.New()
if err != nil { if err != nil {
@ -210,6 +218,7 @@ func NonBlockingRun(s *options.ServerRunOptions, stopCh <-chan struct{}) error {
err = s.Admission.ApplyTo( err = s.Admission.ApplyTo(
genericConfig, genericConfig,
versionedInformers,
pluginInitializer, pluginInitializer,
) )
if err != nil { if err != nil {
@ -235,7 +244,7 @@ func NonBlockingRun(s *options.ServerRunOptions, stopCh <-chan struct{}) error {
cachesize.SetWatchCacheSizes(s.GenericServerRunOptions.WatchCacheSizes) cachesize.SetWatchCacheSizes(s.GenericServerRunOptions.WatchCacheSizes)
} }
m, err := genericConfig.Complete().New("federation", genericapiserver.EmptyDelegate) m, err := genericConfig.Complete(versionedInformers).New("federation", genericapiserver.EmptyDelegate)
if err != nil { if err != nil {
return err return err
} }

View File

@ -62,6 +62,7 @@ import (
"github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus"
// RESTStorage installers // RESTStorage installers
"k8s.io/client-go/informers"
admissionregistrationrest "k8s.io/kubernetes/pkg/registry/admissionregistration/rest" admissionregistrationrest "k8s.io/kubernetes/pkg/registry/admissionregistration/rest"
appsrest "k8s.io/kubernetes/pkg/registry/apps/rest" appsrest "k8s.io/kubernetes/pkg/registry/apps/rest"
authenticationrest "k8s.io/kubernetes/pkg/registry/authentication/rest" authenticationrest "k8s.io/kubernetes/pkg/registry/authentication/rest"
@ -163,9 +164,9 @@ type Master struct {
} }
// Complete fills in any fields not set that are required to have valid data. It's mutating the receiver. // Complete fills in any fields not set that are required to have valid data. It's mutating the receiver.
func (cfg *Config) Complete() CompletedConfig { func (cfg *Config) Complete(informers informers.SharedInformerFactory) CompletedConfig {
c := completedConfig{ c := completedConfig{
cfg.GenericConfig.Complete(), cfg.GenericConfig.Complete(informers),
&cfg.ExtraConfig, &cfg.ExtraConfig,
} }

View File

@ -41,7 +41,7 @@ import (
// TestValidOpenAPISpec verifies that the open api is added // TestValidOpenAPISpec verifies that the open api is added
// at the proper endpoint and the spec is valid. // at the proper endpoint and the spec is valid.
func TestValidOpenAPISpec(t *testing.T) { func TestValidOpenAPISpec(t *testing.T) {
etcdserver, config, assert := setUp(t) etcdserver, config, sharedInformers, assert := setUp(t)
defer etcdserver.Terminate(t) defer etcdserver.Terminate(t)
config.GenericConfig.EnableIndex = true config.GenericConfig.EnableIndex = true
@ -54,7 +54,7 @@ func TestValidOpenAPISpec(t *testing.T) {
} }
config.GenericConfig.SwaggerConfig = genericapiserver.DefaultSwaggerConfig() config.GenericConfig.SwaggerConfig = genericapiserver.DefaultSwaggerConfig()
master, err := config.Complete().New(genericapiserver.EmptyDelegate) master, err := config.Complete(sharedInformers).New(genericapiserver.EmptyDelegate)
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

@ -66,11 +66,11 @@ import (
) )
// setUp is a convience function for setting up for (most) tests. // setUp is a convience function for setting up for (most) tests.
func setUp(t *testing.T) (*etcdtesting.EtcdTestServer, Config, *assert.Assertions) { func setUp(t *testing.T) (*etcdtesting.EtcdTestServer, Config, informers.SharedInformerFactory, *assert.Assertions) {
server, storageConfig := etcdtesting.NewUnsecuredEtcd3TestClientServer(t, api.Scheme) server, storageConfig := etcdtesting.NewUnsecuredEtcd3TestClientServer(t, api.Scheme)
config := &Config{ config := &Config{
GenericConfig: genericapiserver.NewConfig(api.Codecs), GenericConfig: genericapiserver.NewConfig(api.Codecs),
ExtraConfig: ExtraConfig{ ExtraConfig: ExtraConfig{
APIResourceConfigSource: DefaultAPIResourceConfigSource(), APIResourceConfigSource: DefaultAPIResourceConfigSource(),
APIServerServicePort: 443, APIServerServicePort: 443,
@ -115,9 +115,9 @@ func setUp(t *testing.T) (*etcdtesting.EtcdTestServer, Config, *assert.Assertion
if err != nil { if err != nil {
t.Fatalf("unable to create client set due to %v", err) t.Fatalf("unable to create client set due to %v", err)
} }
config.GenericConfig.SharedInformerFactory = informers.NewSharedInformerFactory(clientset, config.GenericConfig.LoopbackClientConfig.Timeout) sharedInformers := informers.NewSharedInformerFactory(clientset, config.GenericConfig.LoopbackClientConfig.Timeout)
return server, *config, assert.New(t) return server, *config, sharedInformers, assert.New(t)
} }
// TestLegacyRestStorageStrategies ensures that all Storage objects which are using the generic registry Store have // TestLegacyRestStorageStrategies ensures that all Storage objects which are using the generic registry Store have
@ -180,9 +180,9 @@ 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, assert := setUp(t) etcdserver, config, sharedInformers, assert := setUp(t)
master, err := config.Complete().New(genericapiserver.EmptyDelegate) master, err := config.Complete(sharedInformers).New(genericapiserver.EmptyDelegate)
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)
} }
@ -206,7 +206,7 @@ func limitedAPIResourceConfigSource() *serverstorage.ResourceConfig {
// newLimitedMaster only enables the core group, the extensions group, the batch group, and the autoscaling group. // newLimitedMaster only enables the core group, the extensions group, the batch group, and the autoscaling group.
func newLimitedMaster(t *testing.T) (*Master, *etcdtesting.EtcdTestServer, Config, *assert.Assertions) { func newLimitedMaster(t *testing.T) (*Master, *etcdtesting.EtcdTestServer, Config, *assert.Assertions) {
etcdserver, config, assert := setUp(t) etcdserver, config, sharedInformers, assert := setUp(t)
config.ExtraConfig.APIResourceConfigSource = limitedAPIResourceConfigSource() config.ExtraConfig.APIResourceConfigSource = limitedAPIResourceConfigSource()
master, err := config.Complete(sharedInformers).New(genericapiserver.EmptyDelegate) master, err := config.Complete(sharedInformers).New(genericapiserver.EmptyDelegate)
if err != nil { if err != nil {

View File

@ -83,7 +83,7 @@ type ExtraConfig struct {
} }
type Config struct { type Config struct {
GenericConfig *genericapiserver.Config GenericConfig *genericapiserver.RecommendedConfig
ExtraConfig ExtraConfig ExtraConfig ExtraConfig
} }

View File

@ -94,7 +94,7 @@ func (o CustomResourceDefinitionsServerOptions) Config() (*apiserver.Config, err
return nil, fmt.Errorf("error creating self-signed certificates: %v", err) return nil, fmt.Errorf("error creating self-signed certificates: %v", err)
} }
serverConfig := genericapiserver.NewConfig(apiserver.Codecs) serverConfig := genericapiserver.NewRecommendedConfig(apiserver.Codecs)
if err := o.RecommendedOptions.ApplyTo(serverConfig); err != nil { if err := o.RecommendedOptions.ApplyTo(serverConfig); err != nil {
return nil, err return nil, err
} }

View File

@ -53,7 +53,7 @@ func DefaultServerConfig() (*extensionsapiserver.Config, error) {
options.RecommendedOptions.Etcd.StorageConfig.ServerList = []string{etcdURL} options.RecommendedOptions.Etcd.StorageConfig.ServerList = []string{etcdURL}
options.RecommendedOptions.Etcd.StorageConfig.Prefix = uuid.New() options.RecommendedOptions.Etcd.StorageConfig.Prefix = uuid.New()
genericConfig := genericapiserver.NewConfig(extensionsapiserver.Codecs) genericConfig := genericapiserver.NewRecommendedConfig(extensionsapiserver.Codecs)
if err := options.RecommendedOptions.SecureServing.MaybeDefaultWithSelfSignedCerts("localhost", nil, []net.IP{net.ParseIP("127.0.0.1")}); err != nil { if err := options.RecommendedOptions.SecureServing.MaybeDefaultWithSelfSignedCerts("localhost", nil, []net.IP{net.ParseIP("127.0.0.1")}); err != nil {
return nil, fmt.Errorf("error creating self-signed certificates: %v", err) return nil, fmt.Errorf("error creating self-signed certificates: %v", err)

View File

@ -122,8 +122,6 @@ type Config struct {
// Will default to a value based on secure serving info and available ipv4 IPs. // Will default to a value based on secure serving info and available ipv4 IPs.
ExternalAddress string ExternalAddress string
// SharedInformerFactory provides shared informers for resources
SharedInformerFactory informers.SharedInformerFactory
//=========================================================================== //===========================================================================
// Fields you probably don't care about changing // Fields you probably don't care about changing
//=========================================================================== //===========================================================================
@ -187,6 +185,13 @@ type Config struct {
PublicAddress net.IP PublicAddress net.IP
} }
type RecommendedConfig struct {
Config
// SharedInformerFactory provides shared informers for resources
SharedInformerFactory informers.SharedInformerFactory
}
type SecureServingInfo struct { type SecureServingInfo struct {
// BindAddress is the ip:port to serve on // BindAddress is the ip:port to serve on
BindAddress string BindAddress string
@ -242,6 +247,13 @@ func NewConfig(codecs serializer.CodecFactory) *Config {
} }
} }
// NewRecommendedConfig returns a RecommendedConfig struct with the default values
func NewRecommendedConfig(codecs serializer.CodecFactory) *RecommendedConfig {
return &RecommendedConfig{
Config: *NewConfig(codecs),
}
}
func DefaultOpenAPIConfig(getDefinitions openapicommon.GetOpenAPIDefinitions, scheme *runtime.Scheme) *openapicommon.Config { func DefaultOpenAPIConfig(getDefinitions openapicommon.GetOpenAPIDefinitions, scheme *runtime.Scheme) *openapicommon.Config {
defNamer := apiopenapi.NewDefinitionNamer(scheme) defNamer := apiopenapi.NewDefinitionNamer(scheme)
return &openapicommon.Config{ return &openapicommon.Config{
@ -301,6 +313,13 @@ func (c *Config) ApplyClientCert(clientCAFile string) (*Config, error) {
type completedConfig struct { type completedConfig struct {
*Config *Config
//===========================================================================
// values below here are filled in during completion
//===========================================================================
// SharedInformerFactory provides shared informers for resources
SharedInformerFactory informers.SharedInformerFactory
} }
type CompletedConfig struct { type CompletedConfig struct {
@ -310,7 +329,7 @@ type CompletedConfig struct {
// Complete fills in any fields not set that are required to have valid data and can be derived // 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. // from other fields. If you're going to `ApplyOptions`, do that first. It's mutating the receiver.
func (c *Config) Complete() CompletedConfig { func (c *Config) Complete(informers informers.SharedInformerFactory) CompletedConfig {
if len(c.ExternalAddress) == 0 && c.PublicAddress != nil { if len(c.ExternalAddress) == 0 && c.PublicAddress != nil {
hostAndPort := c.PublicAddress.String() hostAndPort := c.PublicAddress.String()
if c.ReadWritePort != 0 { if c.ReadWritePort != 0 {
@ -385,7 +404,13 @@ func (c *Config) Complete() CompletedConfig {
c.RequestInfoResolver = NewRequestInfoResolver(c) c.RequestInfoResolver = NewRequestInfoResolver(c)
} }
return CompletedConfig{&completedConfig{c}} return CompletedConfig{&completedConfig{c, informers}}
}
// 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 *RecommendedConfig) Complete() CompletedConfig {
return c.Config.Complete(c.SharedInformerFactory)
} }
// 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.

View File

@ -44,7 +44,6 @@ func TestNewWithDelegate(t *testing.T) {
if clientset == nil { if clientset == nil {
t.Fatal("unable to create fake client set") t.Fatal("unable to create fake client set")
} }
delegateConfig.SharedInformerFactory = informers.NewSharedInformerFactory(clientset, delegateConfig.LoopbackClientConfig.Timeout)
delegateHealthzCalled := false delegateHealthzCalled := false
delegateConfig.HealthzChecks = append(delegateConfig.HealthzChecks, healthz.NamedCheck("delegate-health", func(r *http.Request) error { delegateConfig.HealthzChecks = append(delegateConfig.HealthzChecks, healthz.NamedCheck("delegate-health", func(r *http.Request) error {
@ -52,7 +51,8 @@ func TestNewWithDelegate(t *testing.T) {
return fmt.Errorf("delegate failed healthcheck") return fmt.Errorf("delegate failed healthcheck")
})) }))
delegateServer, err := delegateConfig.Complete().New("test", EmptyDelegate) sharedInformers := informers.NewSharedInformerFactory(clientset, delegateConfig.LoopbackClientConfig.Timeout)
delegateServer, err := delegateConfig.Complete(sharedInformers).New("test", EmptyDelegate)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
@ -73,7 +73,6 @@ func TestNewWithDelegate(t *testing.T) {
wrappingConfig.LegacyAPIGroupPrefixes = sets.NewString("/api") wrappingConfig.LegacyAPIGroupPrefixes = sets.NewString("/api")
wrappingConfig.LoopbackClientConfig = &rest.Config{} wrappingConfig.LoopbackClientConfig = &rest.Config{}
wrappingConfig.SwaggerConfig = DefaultSwaggerConfig() wrappingConfig.SwaggerConfig = DefaultSwaggerConfig()
wrappingConfig.SharedInformerFactory = informers.NewSharedInformerFactory(clientset, wrappingConfig.LoopbackClientConfig.Timeout)
wrappingHealthzCalled := false wrappingHealthzCalled := false
wrappingConfig.HealthzChecks = append(wrappingConfig.HealthzChecks, healthz.NamedCheck("wrapping-health", func(r *http.Request) error { wrappingConfig.HealthzChecks = append(wrappingConfig.HealthzChecks, healthz.NamedCheck("wrapping-health", func(r *http.Request) error {
@ -81,7 +80,8 @@ func TestNewWithDelegate(t *testing.T) {
return fmt.Errorf("wrapping failed healthcheck") return fmt.Errorf("wrapping failed healthcheck")
})) }))
wrappingServer, err := wrappingConfig.Complete().New("test", delegateServer) sharedInformers = informers.NewSharedInformerFactory(clientset, wrappingConfig.LoopbackClientConfig.Timeout)
wrappingServer, err := wrappingConfig.Complete(sharedInformers).New("test", delegateServer)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }

View File

@ -96,7 +96,6 @@ func setUp(t *testing.T) (*etcdtesting.EtcdTestServer, Config, *assert.Assertion
if clientset == nil { if clientset == nil {
t.Fatal("unable to create fake client set") t.Fatal("unable to create fake client set")
} }
config.SharedInformerFactory = informers.NewSharedInformerFactory(clientset, config.LoopbackClientConfig.Timeout)
// TODO restore this test, but right now, eliminate our cycle // TODO restore this test, but right now, eliminate our cycle
// config.OpenAPIConfig = DefaultOpenAPIConfig(testGetOpenAPIDefinitions, runtime.NewScheme()) // config.OpenAPIConfig = DefaultOpenAPIConfig(testGetOpenAPIDefinitions, runtime.NewScheme())
@ -107,7 +106,8 @@ func setUp(t *testing.T) (*etcdtesting.EtcdTestServer, Config, *assert.Assertion
// }, // },
// } // }
config.SwaggerConfig = DefaultSwaggerConfig() config.SwaggerConfig = DefaultSwaggerConfig()
config.Complete() sharedInformers := informers.NewSharedInformerFactory(clientset, config.LoopbackClientConfig.Timeout)
config.Complete(sharedInformers)
return etcdServer, *config, assert.New(t) return etcdServer, *config, assert.New(t)
} }
@ -115,7 +115,7 @@ func setUp(t *testing.T) (*etcdtesting.EtcdTestServer, Config, *assert.Assertion
func newMaster(t *testing.T) (*GenericAPIServer, *etcdtesting.EtcdTestServer, Config, *assert.Assertions) { func newMaster(t *testing.T) (*GenericAPIServer, *etcdtesting.EtcdTestServer, Config, *assert.Assertions) {
etcdserver, config, assert := setUp(t) etcdserver, config, assert := setUp(t)
s, err := config.Complete().New("test", EmptyDelegate) s, err := config.Complete(nil).New("test", EmptyDelegate)
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)
} }
@ -147,7 +147,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().New("test", EmptyDelegate) s, err := config.Complete(nil).New("test", EmptyDelegate)
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)
} }
@ -351,7 +351,7 @@ func TestCustomHandlerChain(t *testing.T) {
called = true called = true
}) })
s, err := config.Complete().New("test", EmptyDelegate) s, err := config.Complete(nil).New("test", EmptyDelegate)
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)
} }
@ -406,7 +406,7 @@ func TestNotRestRoutesHaveAuth(t *testing.T) {
kubeVersion := fakeVersion() kubeVersion := fakeVersion()
config.Version = &kubeVersion config.Version = &kubeVersion
s, err := config.Complete().New("test", EmptyDelegate) s, err := config.Complete(nil).New("test", EmptyDelegate)
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

@ -24,6 +24,7 @@ import (
"k8s.io/apiserver/pkg/admission" "k8s.io/apiserver/pkg/admission"
"k8s.io/apiserver/pkg/admission/initializer" "k8s.io/apiserver/pkg/admission/initializer"
"k8s.io/apiserver/pkg/server" "k8s.io/apiserver/pkg/server"
"k8s.io/client-go/informers"
"k8s.io/client-go/kubernetes" "k8s.io/client-go/kubernetes"
) )
@ -63,17 +64,17 @@ func (a *AdmissionOptions) AddFlags(fs *pflag.FlagSet) {
// genericconfig.LoopbackClientConfig // genericconfig.LoopbackClientConfig
// genericconfig.SharedInformerFactory // genericconfig.SharedInformerFactory
// genericconfig.Authorizer // genericconfig.Authorizer
func (a *AdmissionOptions) ApplyTo(serverCfg *server.Config, pluginInitializers ...admission.PluginInitializer) error { func (a *AdmissionOptions) ApplyTo(c *server.Config, informers informers.SharedInformerFactory, pluginInitializers ...admission.PluginInitializer) error {
pluginsConfigProvider, err := admission.ReadAdmissionConfiguration(a.PluginNames, a.ConfigFile) pluginsConfigProvider, err := admission.ReadAdmissionConfiguration(a.PluginNames, a.ConfigFile)
if err != nil { if err != nil {
return fmt.Errorf("failed to read plugin config: %v", err) return fmt.Errorf("failed to read plugin config: %v", err)
} }
clientset, err := kubernetes.NewForConfig(serverCfg.LoopbackClientConfig) clientset, err := kubernetes.NewForConfig(c.LoopbackClientConfig)
if err != nil { if err != nil {
return err return err
} }
genericInitializer, err := initializer.New(clientset, serverCfg.SharedInformerFactory, serverCfg.Authorizer) genericInitializer, err := initializer.New(clientset, informers, c.Authorizer)
if err != nil { if err != nil {
return err return err
} }
@ -86,7 +87,7 @@ func (a *AdmissionOptions) ApplyTo(serverCfg *server.Config, pluginInitializers
return err return err
} }
serverCfg.AdmissionControl = admissionChain c.AdmissionControl = admissionChain
return nil return nil
} }

View File

@ -17,11 +17,16 @@ limitations under the License.
package options package options
import ( import (
"fmt"
"time"
"github.com/spf13/pflag" "github.com/spf13/pflag"
"k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime"
"k8s.io/apiserver/pkg/server" "k8s.io/apiserver/pkg/server"
"k8s.io/apiserver/pkg/storage/storagebackend" "k8s.io/apiserver/pkg/storage/storagebackend"
clientgoinformers "k8s.io/client-go/informers"
clientgoclientset "k8s.io/client-go/kubernetes"
) )
// RecommendedOptions contains the recommended options for running an API server // RecommendedOptions contains the recommended options for running an API server
@ -55,26 +60,33 @@ func (o *RecommendedOptions) AddFlags(fs *pflag.FlagSet) {
o.Features.AddFlags(fs) o.Features.AddFlags(fs)
} }
func (o *RecommendedOptions) ApplyTo(config *server.Config) error { func (o *RecommendedOptions) ApplyTo(config *server.RecommendedConfig) error {
if err := o.Etcd.ApplyTo(config); err != nil { if err := o.Etcd.ApplyTo(&config.Config); err != nil {
return err return err
} }
if err := o.SecureServing.ApplyTo(config); err != nil { if err := o.SecureServing.ApplyTo(&config.Config); err != nil {
return err return err
} }
if err := o.Authentication.ApplyTo(config); err != nil { if err := o.Authentication.ApplyTo(&config.Config); err != nil {
return err return err
} }
if err := o.Authorization.ApplyTo(config); err != nil { if err := o.Authorization.ApplyTo(&config.Config); err != nil {
return err return err
} }
if err := o.Audit.ApplyTo(config); err != nil { if err := o.Audit.ApplyTo(&config.Config); err != nil {
return err return err
} }
if err := o.Features.ApplyTo(config); err != nil { if err := o.Features.ApplyTo(&config.Config); err != nil {
return err return err
} }
// do convenience work for RecommendedOptions users
clientgoExternalClient, err := clientgoclientset.NewForConfig(config.LoopbackClientConfig)
if err != nil {
return fmt.Errorf("failed to create real external clientset: %v", err)
}
config.SharedInformerFactory = clientgoinformers.NewSharedInformerFactory(clientgoExternalClient, 10*time.Minute)
return nil return nil
} }

View File

@ -24,7 +24,6 @@ import (
"net" "net"
"path" "path"
"strconv" "strconv"
"time"
"github.com/golang/glog" "github.com/golang/glog"
"github.com/pborman/uuid" "github.com/pborman/uuid"
@ -33,9 +32,6 @@ import (
utilnet "k8s.io/apimachinery/pkg/util/net" utilnet "k8s.io/apimachinery/pkg/util/net"
"k8s.io/apiserver/pkg/server" "k8s.io/apiserver/pkg/server"
utilflag "k8s.io/apiserver/pkg/util/flag" utilflag "k8s.io/apiserver/pkg/util/flag"
"k8s.io/client-go/informers"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/rest"
certutil "k8s.io/client-go/util/cert" certutil "k8s.io/client-go/util/cert"
) )
@ -175,26 +171,6 @@ func (s *SecureServingOptions) ApplyTo(c *server.Config) error {
c.SecureServingInfo.SNICerts[server.LoopbackClientServerNameOverride] = &tlsCert c.SecureServingInfo.SNICerts[server.LoopbackClientServerNameOverride] = &tlsCert
} }
// create shared informers, if not explicitly set use in cluster config.
// do not fail on an error, this allows an external API server to startup
// outside of a kube cluster.
var clientCfg *rest.Config
err = nil
if s.useLoopbackCfg {
clientCfg = c.LoopbackClientConfig
} else {
clientCfg, err = rest.InClusterConfig()
}
if err != nil {
glog.Errorf("Couldn't create in cluster config due to %v. SharedInformerFactory will not be set.", err)
return nil
}
clientset, err := kubernetes.NewForConfig(clientCfg)
if err != nil {
glog.Errorf("Couldn't create clientset due to %v. SharedInformerFactory will not be set.", err)
return nil
}
c.SharedInformerFactory = informers.NewSharedInformerFactory(clientset, 10*time.Minute)
return nil return nil
} }

View File

@ -487,7 +487,7 @@ NextTest:
return return
} }
s, err := config.Complete().New("test", server.EmptyDelegate) s, err := config.Complete(nil).New("test", server.EmptyDelegate)
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

@ -88,7 +88,7 @@ type ExtraConfig struct {
} }
type Config struct { type Config struct {
GenericConfig *genericapiserver.Config GenericConfig *genericapiserver.RecommendedConfig
ExtraConfig ExtraConfig ExtraConfig ExtraConfig
} }

View File

@ -118,7 +118,7 @@ func (o AggregatorOptions) RunAggregator(stopCh <-chan struct{}) error {
return fmt.Errorf("error creating self-signed certificates: %v", err) return fmt.Errorf("error creating self-signed certificates: %v", err)
} }
serverConfig := genericapiserver.NewConfig(apiserver.Codecs) serverConfig := genericapiserver.NewRecommendedConfig(apiserver.Codecs)
if err := o.RecommendedOptions.ApplyTo(serverConfig); err != nil { if err := o.RecommendedOptions.ApplyTo(serverConfig); err != nil {
return err return err

View File

@ -30,7 +30,6 @@ import (
"k8s.io/sample-apiserver/pkg/apis/wardle" "k8s.io/sample-apiserver/pkg/apis/wardle"
"k8s.io/sample-apiserver/pkg/apis/wardle/install" "k8s.io/sample-apiserver/pkg/apis/wardle/install"
"k8s.io/sample-apiserver/pkg/apis/wardle/v1alpha1" "k8s.io/sample-apiserver/pkg/apis/wardle/v1alpha1"
informers "k8s.io/sample-apiserver/pkg/client/informers_generated/internalversion"
wardleregistry "k8s.io/sample-apiserver/pkg/registry" wardleregistry "k8s.io/sample-apiserver/pkg/registry"
fischerstorage "k8s.io/sample-apiserver/pkg/registry/wardle/fischer" fischerstorage "k8s.io/sample-apiserver/pkg/registry/wardle/fischer"
flunderstorage "k8s.io/sample-apiserver/pkg/registry/wardle/flunder" flunderstorage "k8s.io/sample-apiserver/pkg/registry/wardle/flunder"
@ -66,7 +65,7 @@ type ExtraConfig struct {
} }
type Config struct { type Config struct {
GenericConfig *genericapiserver.Config GenericConfig *genericapiserver.RecommendedConfig
ExtraConfig ExtraConfig ExtraConfig ExtraConfig
} }

View File

@ -104,7 +104,7 @@ func (o WardleServerOptions) Config() (*apiserver.Config, error) {
return nil, fmt.Errorf("error creating self-signed certificates: %v", err) return nil, fmt.Errorf("error creating self-signed certificates: %v", err)
} }
serverConfig := genericapiserver.NewConfig(apiserver.Codecs) serverConfig := genericapiserver.NewRecommendedConfig(apiserver.Codecs)
if err := o.RecommendedOptions.ApplyTo(serverConfig); err != nil { if err := o.RecommendedOptions.ApplyTo(serverConfig); err != nil {
return nil, err return nil, err
} }
@ -119,7 +119,7 @@ func (o WardleServerOptions) Config() (*apiserver.Config, error) {
return nil, err return nil, err
} }
if err := o.Admission.ApplyTo(serverConfig, admissionInitializer); err != nil { if err := o.Admission.ApplyTo(&serverConfig.Config, serverConfig.SharedInformerFactory, admissionInitializer); err != nil {
return nil, err return nil, err
} }

View File

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

View File

@ -116,13 +116,13 @@ func TestAggregatedAPIServer(t *testing.T) {
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
kubeAPIServerConfig, sharedInformers, _, _, _, err := app.CreateKubeAPIServerConfig(kubeAPIServerOptions, tunneler, proxyTransport) kubeAPIServerConfig, sharedInformers, versionedInformers, _, _, err := app.CreateKubeAPIServerConfig(kubeAPIServerOptions, tunneler, proxyTransport)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
kubeClientConfigValue.Store(kubeAPIServerConfig.GenericConfig.LoopbackClientConfig) kubeClientConfigValue.Store(kubeAPIServerConfig.GenericConfig.LoopbackClientConfig)
kubeAPIServer, err := app.CreateKubeAPIServer(kubeAPIServerConfig, genericapiserver.EmptyDelegate, sharedInformers) kubeAPIServer, err := app.CreateKubeAPIServer(kubeAPIServerConfig, genericapiserver.EmptyDelegate, sharedInformers, versionedInformers)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }

View File

@ -248,9 +248,9 @@ func startMasterOrDie(masterConfig *master.Config, incomingServer *httptest.Serv
if err != nil { if err != nil {
glog.Fatal(err) glog.Fatal(err)
} }
masterConfig.GenericConfig.SharedInformerFactory = extinformers.NewSharedInformerFactory(clientset, masterConfig.GenericConfig.LoopbackClientConfig.Timeout)
m, err = masterConfig.Complete().New(genericapiserver.EmptyDelegate) sharedInformers := extinformers.NewSharedInformerFactory(clientset, masterConfig.GenericConfig.LoopbackClientConfig.Timeout)
m, err = masterConfig.Complete(sharedInformers).New(genericapiserver.EmptyDelegate)
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)