From 6406aacb598a6e94118c944dedf5132320632fa8 Mon Sep 17 00:00:00 2001 From: deads2k Date: Mon, 10 Oct 2016 14:52:39 -0400 Subject: [PATCH] remove legacy API prefix from generic --- .../cmd/federation-apiserver/app/core.go | 3 +- pkg/genericapiserver/config.go | 41 ++++-- pkg/genericapiserver/genericapiserver.go | 134 ++++++++++-------- pkg/genericapiserver/genericapiserver_test.go | 29 ++-- .../options/server_run_options.go | 2 - pkg/master/master.go | 81 +++++------ pkg/master/master_test.go | 2 +- pkg/registry/core/rest/storage_core.go | 9 +- test/integration/framework/master_utils.go | 3 +- 9 files changed, 165 insertions(+), 139 deletions(-) diff --git a/federation/cmd/federation-apiserver/app/core.go b/federation/cmd/federation-apiserver/app/core.go index 793359fc0ce..ae0ed9085b7 100644 --- a/federation/cmd/federation-apiserver/app/core.go +++ b/federation/cmd/federation-apiserver/app/core.go @@ -61,12 +61,11 @@ func installCoreAPIs(s *options.ServerRunOptions, g *genericapiserver.GenericAPI v1.SchemeGroupVersion.Version: coreResources, }, OptionsExternalVersion: ®istered.GroupOrDie(core.GroupName).GroupVersion, - IsLegacyGroup: true, Scheme: core.Scheme, ParameterCodec: core.ParameterCodec, NegotiatedSerializer: core.Codecs, } - if err := g.InstallAPIGroup(&apiGroupInfo); err != nil { + if err := g.InstallLegacyAPIGroup(genericapiserver.LegacyAPIPrefix, &apiGroupInfo); err != nil { glog.Fatalf("Error in registering group version: %+v.\n Error: %v\n", apiGroupInfo, err) } } diff --git a/pkg/genericapiserver/config.go b/pkg/genericapiserver/config.go index 8d7492370ca..212f7ad10ec 100644 --- a/pkg/genericapiserver/config.go +++ b/pkg/genericapiserver/config.go @@ -56,6 +56,11 @@ import ( "k8s.io/kubernetes/pkg/util/sets" ) +const ( + // LegacyAPIPrefix is where the the legacy APIs will be located + LegacyAPIPrefix = "/api" +) + // Config is a structure used to configure a GenericAPIServer. type Config struct { // Destination for audit logs @@ -73,7 +78,6 @@ type Config struct { EnableProfiling bool EnableVersion bool EnableGarbageCollection bool - APIPrefix string APIGroupPrefix string CorsAllowedOriginList []string Authenticator authenticator.Request @@ -175,6 +179,10 @@ type Config struct { // Build the handler chains by decorating the apiHandler. BuildHandlerChainsFunc func(apiHandler http.Handler, c *Config) (secure, insecure http.Handler) + + // LegacyAPIGroupPrefixes is used to set up URL parsing for authorization and for validating requests + // to InstallLegacyAPIGroup + LegacyAPIGroupPrefixes sets.String } type ServingInfo struct { @@ -234,7 +242,6 @@ func NewConfig(options *options.ServerRunOptions) *Config { return &Config{ APIGroupPrefix: options.APIGroupPrefix, - APIPrefix: options.APIPrefix, CorsAllowedOriginList: options.CorsAllowedOriginList, AuditWriter: auditWriter, EnableGarbageCollection: options.EnableGarbageCollection, @@ -262,8 +269,9 @@ func NewConfig(options *options.ServerRunOptions) *Config { Version: "unversioned", }, }, - MaxRequestsInFlight: options.MaxRequestsInFlight, - LongRunningFunc: genericfilters.BasicLongRunningRequestCheck(longRunningRE, map[string]string{"watch": "true"}), + MaxRequestsInFlight: options.MaxRequestsInFlight, + LongRunningFunc: genericfilters.BasicLongRunningRequestCheck(longRunningRE, map[string]string{"watch": "true"}), + LegacyAPIGroupPrefixes: sets.NewString(LegacyAPIPrefix), } } @@ -364,13 +372,13 @@ func (c completedConfig) New() (*GenericAPIServer, error) { } s := &GenericAPIServer{ - ServiceClusterIPRange: c.ServiceClusterIPRange, - LoopbackClientConfig: c.LoopbackClientConfig, - legacyAPIPrefix: c.APIPrefix, - apiPrefix: c.APIGroupPrefix, - admissionControl: c.AdmissionControl, - requestContextMapper: c.RequestContextMapper, - Serializer: c.Serializer, + ServiceClusterIPRange: c.ServiceClusterIPRange, + LoopbackClientConfig: c.LoopbackClientConfig, + apiPrefix: c.APIGroupPrefix, + legacyAPIGroupPrefixes: c.LegacyAPIGroupPrefixes, + admissionControl: c.AdmissionControl, + requestContextMapper: c.RequestContextMapper, + Serializer: c.Serializer, minRequestTimeout: time.Duration(c.MinRequestTimeout) * time.Second, enableSwaggerSupport: c.EnableSwaggerSupport, @@ -501,8 +509,15 @@ func DefaultAndValidateRunOptions(options *options.ServerRunOptions) { } func NewRequestInfoResolver(c *Config) *request.RequestInfoFactory { + apiPrefixes := sets.NewString(strings.Trim(c.APIGroupPrefix, "/")) // all possible API prefixes + legacyAPIPrefixes := sets.String{} // APIPrefixes that won't have groups (legacy) + for legacyAPIPrefix := range c.LegacyAPIGroupPrefixes { + apiPrefixes.Insert(strings.Trim(legacyAPIPrefix, "/")) + legacyAPIPrefixes.Insert(strings.Trim(legacyAPIPrefix, "/")) + } + return &request.RequestInfoFactory{ - APIPrefixes: sets.NewString(strings.Trim(c.APIPrefix, "/"), strings.Trim(c.APIGroupPrefix, "/")), // all possible API prefixes - GrouplessAPIPrefixes: sets.NewString(strings.Trim(c.APIPrefix, "/")), // APIPrefixes that won't have groups (legacy) + APIPrefixes: apiPrefixes, + GrouplessAPIPrefixes: legacyAPIPrefixes, } } diff --git a/pkg/genericapiserver/genericapiserver.go b/pkg/genericapiserver/genericapiserver.go index d53266dd8f4..9a9b4b135ab 100644 --- a/pkg/genericapiserver/genericapiserver.go +++ b/pkg/genericapiserver/genericapiserver.go @@ -49,6 +49,7 @@ import ( certutil "k8s.io/kubernetes/pkg/util/cert" utilnet "k8s.io/kubernetes/pkg/util/net" utilruntime "k8s.io/kubernetes/pkg/util/runtime" + "k8s.io/kubernetes/pkg/util/sets" ) // Info about an API group. @@ -56,8 +57,6 @@ type APIGroupInfo struct { GroupMeta apimachinery.GroupMeta // Info about the resources in this group. Its a map from version to resource to the storage. VersionedResourcesStorageMap map[string]map[string]rest.Storage - // True, if this is the legacy group ("/v1"). - IsLegacyGroup bool // OptionsExternalVersion controls the APIVersion used for common objects in the // schema like api.Status, api.DeleteOptions, and api.ListOptions. Other implementors may // define a version "v1beta1" but want to use the Kubernetes "v1" internal objects. @@ -102,13 +101,13 @@ type GenericAPIServer struct { // TODO eventually we should be able to factor this out to take place during initialization. enableSwaggerSupport bool - // legacyAPIPrefix is the prefix used for legacy API groups that existed before we had API groups - // usuallly /api - legacyAPIPrefix string - // apiPrefix is the prefix where API groups live, usually /apis apiPrefix string + // legacyAPIGroupPrefixes is used to set up URL parsing for authorization and for validating requests + // to InstallLegacyAPIGroup + legacyAPIGroupPrefixes sets.String + // admissionControl is used to build the RESTStorage that backs an API Group. admissionControl admission.Interface @@ -290,18 +289,9 @@ func (s *GenericAPIServer) Run() { select {} } -// Exposes the given api group in the API. -func (s *GenericAPIServer) InstallAPIGroup(apiGroupInfo *APIGroupInfo) error { - apiPrefix := s.apiPrefix - if apiGroupInfo.IsLegacyGroup { - apiPrefix = s.legacyAPIPrefix - } - - // Install REST handlers for all the versions in this group. - apiVersions := []string{} +// installAPIResources is a private method for installing the REST storage backing each api groupversionresource +func (s *GenericAPIServer) installAPIResources(apiPrefix string, apiGroupInfo *APIGroupInfo) error { for _, groupVersion := range apiGroupInfo.GroupMeta.GroupVersions { - apiVersions = append(apiVersions, groupVersion.Version) - apiGroupVersion, err := s.getAPIGroupVersion(apiGroupInfo, groupVersion, apiPrefix) if err != nil { return err @@ -314,51 +304,77 @@ func (s *GenericAPIServer) InstallAPIGroup(apiGroupInfo *APIGroupInfo) error { return fmt.Errorf("Unable to setup API %v: %v", apiGroupInfo, err) } } - // Install the version handler. - if apiGroupInfo.IsLegacyGroup { - // Add a handler at /api to enumerate the supported api versions. - apiserver.AddApiWebService(s.Serializer, s.HandlerContainer.Container, apiPrefix, func(req *restful.Request) *unversioned.APIVersions { - apiVersionsForDiscovery := unversioned.APIVersions{ - ServerAddressByClientCIDRs: s.getServerAddressByClientCIDRs(req.Request), - Versions: apiVersions, - } - return &apiVersionsForDiscovery - }) - } else { - // Do not register empty group or empty version. Doing so claims /apis/ for the wrong entity to be returned. - // Catching these here places the error much closer to its origin - if len(apiGroupInfo.GroupMeta.GroupVersion.Group) == 0 { - return fmt.Errorf("cannot register handler with an empty group for %#v", *apiGroupInfo) - } - if len(apiGroupInfo.GroupMeta.GroupVersion.Version) == 0 { - return fmt.Errorf("cannot register handler with an empty version for %#v", *apiGroupInfo) - } - // Add a handler at /apis/ to enumerate all versions supported by this group. - apiVersionsForDiscovery := []unversioned.GroupVersionForDiscovery{} - for _, groupVersion := range apiGroupInfo.GroupMeta.GroupVersions { - // Check the config to make sure that we elide versions that don't have any resources - if len(apiGroupInfo.VersionedResourcesStorageMap[groupVersion.Version]) == 0 { - continue - } - apiVersionsForDiscovery = append(apiVersionsForDiscovery, unversioned.GroupVersionForDiscovery{ - GroupVersion: groupVersion.String(), - Version: groupVersion.Version, - }) - } - preferedVersionForDiscovery := unversioned.GroupVersionForDiscovery{ - GroupVersion: apiGroupInfo.GroupMeta.GroupVersion.String(), - Version: apiGroupInfo.GroupMeta.GroupVersion.Version, - } - apiGroup := unversioned.APIGroup{ - Name: apiGroupInfo.GroupMeta.GroupVersion.Group, - Versions: apiVersionsForDiscovery, - PreferredVersion: preferedVersionForDiscovery, - } + return nil +} - s.AddAPIGroupForDiscovery(apiGroup) - s.HandlerContainer.Add(apiserver.NewGroupWebService(s.Serializer, apiPrefix+"/"+apiGroup.Name, apiGroup)) +func (s *GenericAPIServer) InstallLegacyAPIGroup(apiPrefix string, apiGroupInfo *APIGroupInfo) error { + if !s.legacyAPIGroupPrefixes.Has(apiPrefix) { + return fmt.Errorf("%q is not in the allowed legacy API prefixes: %v", apiPrefix, s.legacyAPIGroupPrefixes.List()) } + if err := s.installAPIResources(apiPrefix, apiGroupInfo); err != nil { + return err + } + + // setup discovery + apiVersions := []string{} + for _, groupVersion := range apiGroupInfo.GroupMeta.GroupVersions { + apiVersions = append(apiVersions, groupVersion.Version) + } + // Install the version handler. + // Add a handler at / to enumerate the supported api versions. + apiserver.AddApiWebService(s.Serializer, s.HandlerContainer.Container, apiPrefix, func(req *restful.Request) *unversioned.APIVersions { + apiVersionsForDiscovery := unversioned.APIVersions{ + ServerAddressByClientCIDRs: s.getServerAddressByClientCIDRs(req.Request), + Versions: apiVersions, + } + return &apiVersionsForDiscovery + }) + return nil +} + +// Exposes the given api group in the API. +func (s *GenericAPIServer) InstallAPIGroup(apiGroupInfo *APIGroupInfo) error { + // Do not register empty group or empty version. Doing so claims /apis/ for the wrong entity to be returned. + // Catching these here places the error much closer to its origin + if len(apiGroupInfo.GroupMeta.GroupVersion.Group) == 0 { + return fmt.Errorf("cannot register handler with an empty group for %#v", *apiGroupInfo) + } + if len(apiGroupInfo.GroupMeta.GroupVersion.Version) == 0 { + return fmt.Errorf("cannot register handler with an empty version for %#v", *apiGroupInfo) + } + + if err := s.installAPIResources(s.apiPrefix, apiGroupInfo); err != nil { + return err + } + + // setup discovery + // Install the version handler. + // Add a handler at /apis/ to enumerate all versions supported by this group. + apiVersionsForDiscovery := []unversioned.GroupVersionForDiscovery{} + for _, groupVersion := range apiGroupInfo.GroupMeta.GroupVersions { + // Check the config to make sure that we elide versions that don't have any resources + if len(apiGroupInfo.VersionedResourcesStorageMap[groupVersion.Version]) == 0 { + continue + } + apiVersionsForDiscovery = append(apiVersionsForDiscovery, unversioned.GroupVersionForDiscovery{ + GroupVersion: groupVersion.String(), + Version: groupVersion.Version, + }) + } + preferedVersionForDiscovery := unversioned.GroupVersionForDiscovery{ + GroupVersion: apiGroupInfo.GroupMeta.GroupVersion.String(), + Version: apiGroupInfo.GroupMeta.GroupVersion.Version, + } + apiGroup := unversioned.APIGroup{ + Name: apiGroupInfo.GroupMeta.GroupVersion.Group, + Versions: apiVersionsForDiscovery, + PreferredVersion: preferedVersionForDiscovery, + } + + s.AddAPIGroupForDiscovery(apiGroup) + s.HandlerContainer.Add(apiserver.NewGroupWebService(s.Serializer, s.apiPrefix+"/"+apiGroup.Name, apiGroup)) + return nil } diff --git a/pkg/genericapiserver/genericapiserver_test.go b/pkg/genericapiserver/genericapiserver_test.go index fd7bbe1e7db..288fbda8fe5 100644 --- a/pkg/genericapiserver/genericapiserver_test.go +++ b/pkg/genericapiserver/genericapiserver_test.go @@ -41,6 +41,7 @@ import ( ipallocator "k8s.io/kubernetes/pkg/registry/core/service/ipallocator" etcdtesting "k8s.io/kubernetes/pkg/storage/etcd/testing" utilnet "k8s.io/kubernetes/pkg/util/net" + "k8s.io/kubernetes/pkg/util/sets" "github.com/stretchr/testify/assert" ) @@ -55,7 +56,7 @@ func setUp(t *testing.T) (*etcdtesting.EtcdTestServer, Config, *assert.Assertion config.ProxyDialer = func(network, addr string) (net.Conn, error) { return nil, nil } config.ProxyTLSClientConfig = &tls.Config{} config.Serializer = api.Codecs - config.APIPrefix = "/api" + config.LegacyAPIGroupPrefixes = sets.NewString("/api") config.APIGroupPrefix = "/apis" return etcdServer, config, assert.New(t) @@ -79,7 +80,7 @@ func TestNew(t *testing.T) { // Verify many of the variables match their config counterparts assert.Equal(s.enableSwaggerSupport, config.EnableSwaggerSupport) - assert.Equal(s.legacyAPIPrefix, config.APIPrefix) + assert.Equal(s.legacyAPIGroupPrefixes, config.LegacyAPIGroupPrefixes) assert.Equal(s.apiPrefix, config.APIGroupPrefix) assert.Equal(s.admissionControl, config.AdmissionControl) assert.Equal(s.RequestContextMapper(), config.RequestContextMapper) @@ -105,7 +106,7 @@ func TestInstallAPIGroups(t *testing.T) { etcdserver, config, assert := setUp(t) defer etcdserver.Terminate(t) - config.APIPrefix = "/apiPrefix" + config.LegacyAPIGroupPrefixes = sets.NewString("/apiPrefix") config.APIGroupPrefix = "/apiGroupPrefix" s, err := config.Complete().New() @@ -115,15 +116,15 @@ func TestInstallAPIGroups(t *testing.T) { apiGroupMeta := registered.GroupOrDie(api.GroupName) extensionsGroupMeta := registered.GroupOrDie(extensions.GroupName) + s.InstallLegacyAPIGroup("/apiPrefix", &APIGroupInfo{ + // legacy group version + GroupMeta: *apiGroupMeta, + VersionedResourcesStorageMap: map[string]map[string]rest.Storage{}, + ParameterCodec: api.ParameterCodec, + NegotiatedSerializer: api.Codecs, + }) + apiGroupsInfo := []APIGroupInfo{ - { - // legacy group version - GroupMeta: *apiGroupMeta, - VersionedResourcesStorageMap: map[string]map[string]rest.Storage{}, - IsLegacyGroup: true, - ParameterCodec: api.ParameterCodec, - NegotiatedSerializer: api.Codecs, - }, { // extensions group version GroupMeta: *extensionsGroupMeta, @@ -141,9 +142,9 @@ func TestInstallAPIGroups(t *testing.T) { defer server.Close() validPaths := []string{ // "/api" - config.APIPrefix, + config.LegacyAPIGroupPrefixes.List()[0], // "/api/v1" - config.APIPrefix + "/" + apiGroupMeta.GroupVersion.Version, + config.LegacyAPIGroupPrefixes.List()[0] + "/" + apiGroupMeta.GroupVersion.Version, // "/apis/extensions" config.APIGroupPrefix + "/" + extensionsGroupMeta.GroupVersion.Group, // "/apis/extensions/v1beta1" @@ -224,7 +225,7 @@ func TestNotRestRoutesHaveAuth(t *testing.T) { authz := mockAuthorizer{} - config.APIPrefix = "/apiPrefix" + config.LegacyAPIGroupPrefixes = sets.NewString("/apiPrefix") config.APIGroupPrefix = "/apiGroupPrefix" config.Authorizer = &authz diff --git a/pkg/genericapiserver/options/server_run_options.go b/pkg/genericapiserver/options/server_run_options.go index ec1c66f0a2b..5b24d5e313c 100644 --- a/pkg/genericapiserver/options/server_run_options.go +++ b/pkg/genericapiserver/options/server_run_options.go @@ -56,7 +56,6 @@ var AuthorizationModeChoices = []string{ModeAlwaysAllow, ModeAlwaysDeny, ModeABA // ServerRunOptions contains the options while running a generic api server. type ServerRunOptions struct { APIGroupPrefix string - APIPrefix string AdmissionControl string AdmissionControlConfigFile string AdvertiseAddress net.IP @@ -125,7 +124,6 @@ type ServerRunOptions struct { func NewServerRunOptions() *ServerRunOptions { return &ServerRunOptions{ APIGroupPrefix: "/apis", - APIPrefix: "/api", AdmissionControl: "AlwaysAdmit", AnonymousAuth: true, AuthorizationMode: "AlwaysAllow", diff --git a/pkg/master/master.go b/pkg/master/master.go index 7491cc3ba57..75c7cec7c3a 100644 --- a/pkg/master/master.go +++ b/pkg/master/master.go @@ -135,8 +135,6 @@ type Master struct { // nodeClient is used to back the tunneler nodeClient coreclient.NodeInterface - - restOptionsFactory restOptionsFactory } // thirdPartyEntry combines objects storage and API group into one struct @@ -209,31 +207,33 @@ func (c completedConfig) New() (*Master, error) { nodeClient: coreclient.NewForConfigOrDie(c.GenericConfig.LoopbackClientConfig).Nodes(), disableThirdPartyControllerForTesting: c.disableThirdPartyControllerForTesting, + } - restOptionsFactory: restOptionsFactory{ - deleteCollectionWorkers: c.DeleteCollectionWorkers, - enableGarbageCollection: c.GenericConfig.EnableGarbageCollection, - storageFactory: c.StorageFactory, - }, + restOptionsFactory := restOptionsFactory{ + deleteCollectionWorkers: c.DeleteCollectionWorkers, + enableGarbageCollection: c.GenericConfig.EnableGarbageCollection, + storageFactory: c.StorageFactory, } if c.EnableWatchCache { - m.restOptionsFactory.storageDecorator = registry.StorageWithCacher + restOptionsFactory.storageDecorator = registry.StorageWithCacher } else { - m.restOptionsFactory.storageDecorator = generic.UndecoratedStorage + restOptionsFactory.storageDecorator = generic.UndecoratedStorage } // install legacy rest storage - // because of other hacks, this always has to come first - legacyRESTStorageProvider := corerest.LegacyRESTStorageProvider{ - StorageFactory: c.StorageFactory, - ProxyTransport: s.ProxyTransport, - KubeletClient: c.KubeletClient, - EventTTL: c.EventTTL, - ServiceClusterIPRange: c.GenericConfig.ServiceClusterIPRange, - ServiceNodePortRange: c.GenericConfig.ServiceNodePortRange, - ComponentStatusServerFunc: func() map[string]apiserver.Server { return getServersToValidate(c.StorageFactory) }, - LoopbackClientConfig: c.GenericConfig.LoopbackClientConfig, + if c.GenericConfig.APIResourceConfigSource.AnyResourcesForVersionEnabled(apiv1.SchemeGroupVersion) { + legacyRESTStorageProvider := corerest.LegacyRESTStorageProvider{ + StorageFactory: c.StorageFactory, + ProxyTransport: s.ProxyTransport, + KubeletClient: c.KubeletClient, + EventTTL: c.EventTTL, + ServiceClusterIPRange: c.GenericConfig.ServiceClusterIPRange, + ServiceNodePortRange: c.GenericConfig.ServiceNodePortRange, + ComponentStatusServerFunc: func() map[string]apiserver.Server { return getServersToValidate(c.StorageFactory) }, + LoopbackClientConfig: c.GenericConfig.LoopbackClientConfig, + } + m.InstallLegacyAPI(c.Config, restOptionsFactory.NewFor, legacyRESTStorageProvider) } // Add some hardcoded storage for now. Append to the map. @@ -253,13 +253,31 @@ func (c completedConfig) New() (*Master, error) { c.RESTStorageProviders[policy.GroupName] = policyrest.RESTStorageProvider{} c.RESTStorageProviders[rbac.GroupName] = &rbacrest.RESTStorageProvider{AuthorizerRBACSuperUser: c.GenericConfig.AuthorizerRBACSuperUser} c.RESTStorageProviders[storage.GroupName] = storagerest.RESTStorageProvider{} - m.InstallAPIs(c.Config, legacyRESTStorageProvider) + m.InstallAPIs(c.Config, restOptionsFactory.NewFor) m.InstallGeneralEndpoints(c.Config) return m, nil } +func (m *Master) InstallLegacyAPI(c *Config, restOptionsGetter genericapiserver.RESTOptionsGetter, legacyRESTStorageProvider corerest.LegacyRESTStorageProvider) { + legacyRESTStorage, apiGroupInfo, err := legacyRESTStorageProvider.NewLegacyRESTStorage(restOptionsGetter) + if err != nil { + glog.Fatalf("Error building core storage: %v", err) + } + + if c.EnableCoreControllers { + bootstrapController := c.NewBootstrapController(legacyRESTStorage) + if err := m.GenericAPIServer.AddPostStartHook("bootstrap-controller", bootstrapController.PostStartHook); err != nil { + glog.Fatalf("Error registering PostStartHook %q: %v", "bootstrap-controller", err) + } + } + + if err := m.GenericAPIServer.InstallLegacyAPIGroup(genericapiserver.LegacyAPIPrefix, &apiGroupInfo); err != nil { + glog.Fatalf("Error in registering group versions: %v", err) + } +} + // TODO this needs to be refactored so we have a way to add general health checks to genericapiserver // TODO profiling should be generic func (m *Master) InstallGeneralEndpoints(c *Config) { @@ -283,30 +301,9 @@ func (m *Master) InstallGeneralEndpoints(c *Config) { } -func (m *Master) InstallAPIs(c *Config, legacyRESTStorageProvider corerest.LegacyRESTStorageProvider) { - restOptionsGetter := func(resource unversioned.GroupResource) generic.RESTOptions { - return m.restOptionsFactory.NewFor(resource) - } - +func (m *Master) InstallAPIs(c *Config, restOptionsGetter genericapiserver.RESTOptionsGetter) { apiGroupsInfo := []genericapiserver.APIGroupInfo{} - // Install v1 unless disabled. - if c.GenericConfig.APIResourceConfigSource.AnyResourcesForVersionEnabled(apiv1.SchemeGroupVersion) { - legacyRESTStorage, apiGroupInfo, err := legacyRESTStorageProvider.NewLegacyRESTStorage(restOptionsGetter) - if err != nil { - glog.Fatalf("Error building core storage: %v", err) - } - - if c.EnableCoreControllers { - bootstrapController := c.NewBootstrapController(legacyRESTStorage) - if err := m.GenericAPIServer.AddPostStartHook("bootstrap-controller", bootstrapController.PostStartHook); err != nil { - glog.Fatalf("Error registering PostStartHook %q: %v", "bootstrap-controller", err) - } - } - - apiGroupsInfo = append(apiGroupsInfo, apiGroupInfo) - } - // Install third party resource support if requested // TODO seems like this bit ought to be unconditional and the REST API is controlled by the config if c.GenericConfig.APIResourceConfigSource.ResourceEnabled(extensionsapiv1beta1.SchemeGroupVersion.WithResource("thirdpartyresources")) { diff --git a/pkg/master/master_test.go b/pkg/master/master_test.go index 655de7612e7..9da00829a13 100644 --- a/pkg/master/master_test.go +++ b/pkg/master/master_test.go @@ -88,7 +88,7 @@ func setUp(t *testing.T) (*Master, *etcdtesting.EtcdTestServer, Config, *assert. config.GenericConfig.PublicAddress = net.ParseIP("192.168.10.4") config.GenericConfig.Serializer = api.Codecs config.KubeletClient = client.FakeKubeletClient{} - config.GenericConfig.APIPrefix = "/api" + config.GenericConfig.LegacyAPIGroupPrefixes = sets.NewString("/api") config.GenericConfig.APIGroupPrefix = "/apis" config.GenericConfig.APIResourceConfigSource = DefaultAPIResourceConfigSource() config.GenericConfig.ProxyDialer = func(network, addr string) (net.Conn, error) { return nil, nil } diff --git a/pkg/registry/core/rest/storage_core.go b/pkg/registry/core/rest/storage_core.go index ba3d7ee7aff..65135b85a94 100644 --- a/pkg/registry/core/rest/storage_core.go +++ b/pkg/registry/core/rest/storage_core.go @@ -96,11 +96,10 @@ func (c LegacyRESTStorageProvider) NewLegacyRESTStorage(restOptionsGetter generi apiGroupInfo := genericapiserver.APIGroupInfo{ GroupMeta: *registered.GroupOrDie(api.GroupName), VersionedResourcesStorageMap: map[string]map[string]rest.Storage{}, - IsLegacyGroup: true, - Scheme: api.Scheme, - ParameterCodec: api.ParameterCodec, - NegotiatedSerializer: api.Codecs, - SubresourceGroupVersionKind: map[string]unversioned.GroupVersionKind{}, + Scheme: api.Scheme, + ParameterCodec: api.ParameterCodec, + NegotiatedSerializer: api.Codecs, + SubresourceGroupVersionKind: map[string]unversioned.GroupVersionKind{}, } if autoscalingGroupVersion := (unversioned.GroupVersion{Group: "autoscaling", Version: "v1"}); registered.IsEnabledVersion(autoscalingGroupVersion) { apiGroupInfo.SubresourceGroupVersionKind["replicationcontrollers/scale"] = autoscalingGroupVersion.WithKind("Scale") diff --git a/test/integration/framework/master_utils.go b/test/integration/framework/master_utils.go index 0ab1b10c715..ab9732c7da0 100644 --- a/test/integration/framework/master_utils.go +++ b/test/integration/framework/master_utils.go @@ -61,6 +61,7 @@ import ( "k8s.io/kubernetes/pkg/runtime" "k8s.io/kubernetes/pkg/storage/storagebackend" utilnet "k8s.io/kubernetes/pkg/util/net" + "k8s.io/kubernetes/pkg/util/sets" "k8s.io/kubernetes/pkg/util/wait" "k8s.io/kubernetes/pkg/watch" "k8s.io/kubernetes/plugin/pkg/admission/admit" @@ -346,7 +347,7 @@ func NewMasterConfig() *master.Config { return &master.Config{ GenericConfig: &genericapiserver.Config{ APIResourceConfigSource: master.DefaultAPIResourceConfigSource(), - APIPrefix: "/api", + LegacyAPIGroupPrefixes: sets.NewString("/api"), APIGroupPrefix: "/apis", Authorizer: authorizer.NewAlwaysAllowAuthorizer(), AdmissionControl: admit.NewAlwaysAdmit(),