Skip to content

Commit

Permalink
apiserver: make config completion structural recursion
Browse files Browse the repository at this point in the history
  • Loading branch information
sttts committed Sep 8, 2017
1 parent 7d09148 commit 1bcea54
Show file tree
Hide file tree
Showing 9 changed files with 87 additions and 74 deletions.
2 changes: 1 addition & 1 deletion pkg/master/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ type Controller struct {
}

// NewBootstrapController returns a controller for watching the core capabilities of the master
func (c *Config) NewBootstrapController(legacyRESTStorage corerest.LegacyRESTStorage, serviceClient coreclient.ServicesGetter, nsClient coreclient.NamespacesGetter) *Controller {
func (c *completedConfig) NewBootstrapController(legacyRESTStorage corerest.LegacyRESTStorage, serviceClient coreclient.ServicesGetter, nsClient coreclient.NamespacesGetter) *Controller {
return &Controller{
ServiceClient: serviceClient,
NamespaceClient: nsClient,
Expand Down
34 changes: 19 additions & 15 deletions pkg/master/master.go
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,16 @@ type Config struct {
ExtraConfig ExtraConfig
}

type completedConfig struct {
GenericConfig genericapiserver.CompletedConfig
ExtraConfig *ExtraConfig
}

type CompletedConfig struct {
// Embed a private pointer that cannot be instantiated outside of this package.
*completedConfig
}

// EndpointReconcilerConfig holds the endpoint reconciler and endpoint reconciliation interval to be
// used by the master.
type EndpointReconcilerConfig struct {
Expand All @@ -152,13 +162,12 @@ type Master struct {
ClientCARegistrationHook ClientCARegistrationHook
}

type completedConfig struct {
*Config
}

// Complete fills in any fields not set that are required to have valid data. It's mutating the receiver.
func (c *Config) Complete() completedConfig {
c.GenericConfig.Complete()
func (cfg *Config) Complete() CompletedConfig {
c := completedConfig{
cfg.GenericConfig.Complete(),
&cfg.ExtraConfig,
}

serviceIPRange, apiServerServiceIP, err := DefaultServiceIPRange(c.ExtraConfig.ServiceIPRange)
if err != nil {
Expand Down Expand Up @@ -201,12 +210,7 @@ func (c *Config) Complete() completedConfig {
// this has always been hardcoded true in the past
c.GenericConfig.EnableMetrics = true

return completedConfig{c}
}

// SkipComplete provides a way to construct a server instance without config completion.
func (c *Config) SkipComplete() completedConfig {
return completedConfig{c}
return CompletedConfig{&c}
}

// New returns a new instance of Master from the given config.
Expand All @@ -218,7 +222,7 @@ func (c completedConfig) New(delegationTarget genericapiserver.DelegationTarget)
return nil, fmt.Errorf("Master.New() called with empty config.KubeletClientConfig")
}

s, err := c.Config.GenericConfig.SkipComplete().New("kube-apiserver", delegationTarget) // completion is done in Complete, no need for a second time
s, err := c.GenericConfig.New("kube-apiserver", delegationTarget)
if err != nil {
return nil, err
}
Expand All @@ -245,7 +249,7 @@ func (c completedConfig) New(delegationTarget genericapiserver.DelegationTarget)
ServiceNodePortRange: c.ExtraConfig.ServiceNodePortRange,
LoopbackClientConfig: c.GenericConfig.LoopbackClientConfig,
}
m.InstallLegacyAPI(c.Config, c.Config.GenericConfig.RESTOptionsGetter, legacyRESTStorageProvider)
m.InstallLegacyAPI(&c, c.GenericConfig.RESTOptionsGetter, legacyRESTStorageProvider)
}

// The order here is preserved in discovery.
Expand Down Expand Up @@ -284,7 +288,7 @@ func (c completedConfig) New(delegationTarget genericapiserver.DelegationTarget)
return m, nil
}

func (m *Master) InstallLegacyAPI(c *Config, restOptionsGetter generic.RESTOptionsGetter, legacyRESTStorageProvider corerest.LegacyRESTStorageProvider) {
func (m *Master) InstallLegacyAPI(c *completedConfig, restOptionsGetter generic.RESTOptionsGetter, legacyRESTStorageProvider corerest.LegacyRESTStorageProvider) {
legacyRESTStorage, apiGroupInfo, err := legacyRESTStorageProvider.NewLegacyRESTStorage(restOptionsGetter)
if err != nil {
glog.Fatalf("Error building core storage: %v", err)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,11 +81,20 @@ func init() {
type ExtraConfig struct {
CRDRESTOptionsGetter genericregistry.RESTOptionsGetter
}

type Config struct {
GenericConfig *genericapiserver.Config
ExtraConfig ExtraConfig
}

type completedConfig struct {
GenericConfig genericapiserver.CompletedConfig
ExtraConfig *ExtraConfig
}

type CompletedConfig struct {
// Embed a private pointer that cannot be instantiated outside of this package.
*completedConfig
}

type CustomResourceDefinitions struct {
Expand All @@ -95,31 +104,25 @@ type CustomResourceDefinitions struct {
Informers internalinformers.SharedInformerFactory
}

type completedConfig struct {
*Config
}

// Complete fills in any fields not set that are required to have valid data. It's mutating the receiver.
func (c *Config) Complete() completedConfig {
c.GenericConfig.EnableDiscovery = false
c.GenericConfig.Complete()
func (cfg *Config) Complete() CompletedConfig {
c := completedConfig{
cfg.GenericConfig.Complete(),
&cfg.ExtraConfig,
}

c.GenericConfig.EnableDiscovery = false
c.GenericConfig.Version = &version.Info{
Major: "0",
Minor: "1",
}

return completedConfig{c}
}

// SkipComplete provides a way to construct a server instance without config completion.
func (c *Config) SkipComplete() completedConfig {
return completedConfig{c}
return CompletedConfig{&c}
}

// New returns a new instance of CustomResourceDefinitions from the given config.
func (c completedConfig) New(delegationTarget genericapiserver.DelegationTarget) (*CustomResourceDefinitions, error) {
genericServer, err := c.Config.GenericConfig.SkipComplete().New("apiextensions-apiserver", delegationTarget) // completion is done in Complete, no need for a second time
genericServer, err := c.GenericConfig.New("apiextensions-apiserver", delegationTarget)
if err != nil {
return nil, err
}
Expand Down
15 changes: 8 additions & 7 deletions staging/src/k8s.io/apiserver/pkg/server/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ import (
certutil "k8s.io/client-go/util/cert"
openapicommon "k8s.io/kube-openapi/pkg/common"

// install apis
_ "k8s.io/apiserver/pkg/apis/apiserver/install"
)

Expand Down Expand Up @@ -302,9 +303,14 @@ type completedConfig struct {
*Config
}

type CompletedConfig struct {
// Embed a private pointer that cannot be instantiated outside of this package.
*completedConfig
}

// Complete fills in any fields not set that are required to have valid data and can be derived
// from other fields. If you're going to `ApplyOptions`, do that first. It's mutating the receiver.
func (c *Config) Complete() completedConfig {
func (c *Config) Complete() CompletedConfig {
if len(c.ExternalAddress) == 0 && c.PublicAddress != nil {
hostAndPort := c.PublicAddress.String()
if c.ReadWritePort != 0 {
Expand Down Expand Up @@ -379,12 +385,7 @@ func (c *Config) Complete() completedConfig {
c.RequestInfoResolver = NewRequestInfoResolver(c)
}

return completedConfig{c}
}

// SkipComplete provides a way to construct a server instance without config completion.
func (c *Config) SkipComplete() completedConfig {
return completedConfig{c}
return CompletedConfig{&completedConfig{c}}
}

// New creates a new server which logically combines the handling chain with the passed server.
Expand Down
2 changes: 1 addition & 1 deletion staging/src/k8s.io/apiserver/pkg/server/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ func TestNewWithDelegate(t *testing.T) {
return fmt.Errorf("delegate failed healthcheck")
}))

delegateServer, err := delegateConfig.SkipComplete().New("test", EmptyDelegate)
delegateServer, err := delegateConfig.Complete().New("test", EmptyDelegate)
if err != nil {
t.Fatal(err)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ func TestInstallAPIGroups(t *testing.T) {
config.LegacyAPIGroupPrefixes = sets.NewString("/apiPrefix")
config.DiscoveryAddresses = discovery.DefaultAddresses{DefaultAddress: "ExternalAddress"}

s, err := config.SkipComplete().New("test", EmptyDelegate)
s, err := config.Complete().New("test", EmptyDelegate)
if err != nil {
t.Fatalf("Error in bringing up the server: %v", err)
}
Expand Down Expand Up @@ -351,7 +351,7 @@ func TestCustomHandlerChain(t *testing.T) {
called = true
})

s, err := config.SkipComplete().New("test", EmptyDelegate)
s, err := config.Complete().New("test", EmptyDelegate)
if err != nil {
t.Fatalf("Error in bringing up the server: %v", err)
}
Expand Down Expand Up @@ -406,7 +406,7 @@ func TestNotRestRoutesHaveAuth(t *testing.T) {
kubeVersion := fakeVersion()
config.Version = &kubeVersion

s, err := config.SkipComplete().New("test", EmptyDelegate)
s, err := config.Complete().New("test", EmptyDelegate)
if err != nil {
t.Fatalf("Error in bringing up the server: %v", err)
}
Expand Down
40 changes: 22 additions & 18 deletions staging/src/k8s.io/kube-aggregator/pkg/apiserver/apiserver.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,10 +88,20 @@ type ExtraConfig struct {
}

type Config struct {
GenericConfig *genericapiserver.RecommendedConfig
GenericConfig *genericapiserver.Config
ExtraConfig ExtraConfig
}

type completedConfig struct {
GenericConfig genericapiserver.CompletedConfig
ExtraConfig *ExtraConfig
}

type CompletedConfig struct {
// Embed a private pointer that cannot be instantiated outside of this package.
*completedConfig
}

// APIAggregator contains state for a Kubernetes cluster master/api server.
type APIAggregator struct {
GenericAPIServer *genericapiserver.GenericAPIServer
Expand Down Expand Up @@ -124,41 +134,35 @@ type APIAggregator struct {
openAPIAggregationController *openapicontroller.AggregationController
}

type completedConfig struct {
*Config
}

// Complete fills in any fields not set that are required to have valid data. It's mutating the receiver.
func (c *Config) Complete() completedConfig {
func (cfg *Config) Complete() CompletedConfig {
c := completedConfig{
cfg.GenericConfig.Complete(),
&cfg.ExtraConfig,
}

// the kube aggregator wires its own discovery mechanism
// TODO eventually collapse this by extracting all of the discovery out
c.GenericConfig.EnableDiscovery = false
c.GenericConfig.Complete()

version := version.Get()
c.GenericConfig.Version = &version

return completedConfig{c}
}

// SkipComplete provides a way to construct a server instance without config completion.
func (c *Config) SkipComplete() completedConfig {
return completedConfig{c}
return CompletedConfig{&c}
}

// New returns a new instance of APIAggregator from the given config.
func (c completedConfig) NewWithDelegate(delegationTarget genericapiserver.DelegationTarget) (*APIAggregator, error) {
// Prevent generic API server to install OpenAPI handler. Aggregator server
// has its own customized OpenAPI handler.
openApiConfig := c.Config.GenericConfig.OpenAPIConfig
c.Config.GenericConfig.OpenAPIConfig = nil
openApiConfig := c.GenericConfig.OpenAPIConfig
c.GenericConfig.OpenAPIConfig = nil

genericServer, err := c.Config.GenericConfig.SkipComplete().New("kube-aggregator", delegationTarget) // completion is done in Complete, no need for a second time
genericServer, err := c.GenericConfig.New("kube-aggregator", delegationTarget)
if err != nil {
return nil, err
}

apiregistrationClient, err := internalclientset.NewForConfig(c.Config.GenericConfig.LoopbackClientConfig)
apiregistrationClient, err := internalclientset.NewForConfig(c.GenericConfig.LoopbackClientConfig)
if err != nil {
return nil, err
}
Expand Down
26 changes: 14 additions & 12 deletions staging/src/k8s.io/sample-apiserver/pkg/apiserver/apiserver.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,6 @@ type ExtraConfig struct {

type Config struct {
GenericConfig *genericapiserver.Config
// SharedInformerFactory provides shared informers for resources
SharedInformerFactory informers.SharedInformerFactory
ExtraConfig ExtraConfig
}

Expand All @@ -78,29 +76,33 @@ type WardleServer struct {
}

type completedConfig struct {
*Config
GenericConfig genericapiserver.CompletedConfig
ExtraConfig *ExtraConfig
}

type CompletedConfig struct {
// Embed a private pointer that cannot be instantiated outside of this package.
*completedConfig
}

// Complete fills in any fields not set that are required to have valid data. It's mutating the receiver.
func (c *Config) Complete() completedConfig {
c.GenericConfig.Complete()
func (cfg *Config) Complete() CompletedConfig {
c := completedConfig{
cfg.GenericConfig.Complete(),
&cfg.ExtraConfig,
}

c.GenericConfig.Version = &version.Info{
Major: "1",
Minor: "0",
}

return completedConfig{c}
}

// SkipComplete provides a way to construct a server instance without config completion.
func (c *Config) SkipComplete() completedConfig {
return completedConfig{c}
return CompletedConfig{&c}
}

// New returns a new instance of WardleServer from the given config.
func (c completedConfig) New() (*WardleServer, error) {
genericServer, err := c.Config.GenericConfig.SkipComplete().New("sample-apiserver", genericapiserver.EmptyDelegate) // completion is done in Complete, no need for a second time
genericServer, err := c.GenericConfig.New("sample-apiserver", genericapiserver.EmptyDelegate)
if err != nil {
return nil, err
}
Expand Down
5 changes: 2 additions & 3 deletions staging/src/k8s.io/sample-apiserver/pkg/cmd/server/start.go
Original file line number Diff line number Diff line change
Expand Up @@ -124,8 +124,7 @@ func (o WardleServerOptions) Config() (*apiserver.Config, error) {
}

config := &apiserver.Config{
GenericConfig: serverConfig,
SharedInformerFactory: informerFactory,
GenericConfig: serverConfig,
ExtraConfig: apiserver.ExtraConfig{},
}
return config, nil
Expand All @@ -143,7 +142,7 @@ func (o WardleServerOptions) RunWardleServer(stopCh <-chan struct{}) error {
}

server.GenericAPIServer.AddPostStartHook("start-sample-server-informers", func(context genericapiserver.PostStartHookContext) error {
config.SharedInformerFactory.Start(context.StopCh)
config.GenericConfig.SharedInformerFactory.Start(context.StopCh)
return nil
})

Expand Down

0 comments on commit 1bcea54

Please sign in to comment.