diff --git a/api/swagger-spec/resourceListing.json b/api/swagger-spec/resourceListing.json index 33fb4c36002..2e802cfa360 100644 --- a/api/swagger-spec/resourceListing.json +++ b/api/swagger-spec/resourceListing.json @@ -1,14 +1,14 @@ { "swaggerVersion": "1.2", "apis": [ - { - "path": "/api/v1", - "description": "API at /api/v1" - }, { "path": "/version", "description": "git code version from which this is built" }, + { + "path": "/api/v1", + "description": "API at /api/v1" + }, { "path": "/api", "description": "get available API versions" diff --git a/pkg/apiserver/api_installer.go b/pkg/apiserver/api_installer.go index bad4e9033f0..10126e5f691 100644 --- a/pkg/apiserver/api_installer.go +++ b/pkg/apiserver/api_installer.go @@ -78,7 +78,7 @@ func (a *APIInstaller) Install(ws *restful.WebService) (apiResources []unversion for _, path := range paths { apiResource, err := a.registerResourceHandlers(path, a.group.Storage[path], ws, proxyHandler) if err != nil { - errors = append(errors, err) + errors = append(errors, fmt.Errorf("error in registering resource: %s, %v", path, err)) } if apiResource != nil { apiResources = append(apiResources, *apiResource) diff --git a/pkg/genericapiserver/genericapiserver.go b/pkg/genericapiserver/genericapiserver.go index b2e03bfc755..da087ecd7e2 100644 --- a/pkg/genericapiserver/genericapiserver.go +++ b/pkg/genericapiserver/genericapiserver.go @@ -18,6 +18,7 @@ package genericapiserver import ( "crypto/tls" + "fmt" "net" "net/http" "net/http/pprof" @@ -27,7 +28,9 @@ import ( "k8s.io/kubernetes/pkg/admission" "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/api/latest" "k8s.io/kubernetes/pkg/api/rest" + "k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/apiserver" "k8s.io/kubernetes/pkg/auth/authenticator" "k8s.io/kubernetes/pkg/auth/authorizer" @@ -128,6 +131,21 @@ type APIGroupVersionOverride struct { ResourceOverrides map[string]bool } +// Info about an API group. +type APIGroupInfo struct { + GroupMeta latest.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. + // If nil, defaults to groupMeta.GroupVersion. + // TODO: Remove this when https://github.com/kubernetes/kubernetes/issues/19018 is fixed. + OptionsExternalVersion *unversioned.GroupVersion +} + // Config is a structure used to configure a GenericAPIServer. type Config struct { StorageDestinations StorageDestinations @@ -229,8 +247,8 @@ type GenericAPIServer struct { enableSwaggerSupport bool enableProfiling bool enableWatchCache bool - ApiPrefix string - ApiGroupPrefix string + APIPrefix string + APIGroupPrefix string corsAllowedOriginList []string authenticator authenticator.Request authorizer authorizer.Authorizer @@ -351,8 +369,8 @@ func New(c *Config) *GenericAPIServer { enableSwaggerSupport: c.EnableSwaggerSupport, enableProfiling: c.EnableProfiling, enableWatchCache: c.EnableWatchCache, - ApiPrefix: c.APIPrefix, - ApiGroupPrefix: c.APIGroupPrefix, + APIPrefix: c.APIPrefix, + APIGroupPrefix: c.APIGroupPrefix, corsAllowedOriginList: c.CorsAllowedOriginList, authenticator: c.Authenticator, authorizer: c.Authorizer, @@ -397,8 +415,8 @@ func New(c *Config) *GenericAPIServer { func (s *GenericAPIServer) NewRequestInfoResolver() *apiserver.RequestInfoResolver { return &apiserver.RequestInfoResolver{ - sets.NewString(strings.Trim(s.ApiPrefix, "/"), strings.Trim(s.ApiGroupPrefix, "/")), // all possible API prefixes - sets.NewString(strings.Trim(s.ApiPrefix, "/")), // APIPrefixes that won't have groups (legacy) + sets.NewString(strings.Trim(s.APIPrefix, "/"), strings.Trim(s.APIGroupPrefix, "/")), // all possible API prefixes + sets.NewString(strings.Trim(s.APIPrefix, "/")), // APIPrefixes that won't have groups (legacy) } } @@ -504,6 +522,102 @@ func (s *GenericAPIServer) init(c *Config) { } } +// Exposes the given group versions in API. +func (s *GenericAPIServer) InstallAPIGroups(groupsInfo []APIGroupInfo) error { + for _, apiGroupInfo := range groupsInfo { + if err := s.installAPIGroup(&apiGroupInfo); err != nil { + return err + } + } + return nil +} + +func (s *GenericAPIServer) installAPIGroup(apiGroupInfo *APIGroupInfo) error { + apiPrefix := s.APIGroupPrefix + if apiGroupInfo.IsLegacyGroup { + apiPrefix = s.APIPrefix + } + + // Install REST handlers for all the versions in this group. + apiVersions := []string{} + for _, groupVersion := range apiGroupInfo.GroupMeta.GroupVersions { + apiVersions = append(apiVersions, groupVersion.Version) + + apiGroupVersion, err := s.getAPIGroupVersion(apiGroupInfo, groupVersion, apiPrefix) + if err != nil { + return err + } + if apiGroupInfo.OptionsExternalVersion != nil { + apiGroupVersion.OptionsExternalVersion = apiGroupInfo.OptionsExternalVersion + } + + if err := apiGroupVersion.InstallREST(s.HandlerContainer); err != nil { + 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.HandlerContainer, apiPrefix, apiVersions) + } else { + // Add a handler at /apis/ to enumerate all versions supported by this group. + apiVersionsForDiscovery := []unversioned.GroupVersionForDiscovery{} + for _, groupVersion := range apiGroupInfo.GroupMeta.GroupVersions { + 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, + } + apiserver.AddGroupWebService(s.HandlerContainer, apiPrefix+"/"+apiGroup.Name, apiGroup) + } + apiserver.InstallServiceErrorHandler(s.HandlerContainer, s.NewRequestInfoResolver(), apiVersions) + return nil +} + +func (s *GenericAPIServer) getAPIGroupVersion(apiGroupInfo *APIGroupInfo, groupVersion unversioned.GroupVersion, apiPrefix string) (*apiserver.APIGroupVersion, error) { + storage := make(map[string]rest.Storage) + for k, v := range apiGroupInfo.VersionedResourcesStorageMap[groupVersion.Version] { + storage[strings.ToLower(k)] = v + } + version, err := s.newAPIGroupVersion(apiGroupInfo.GroupMeta, groupVersion) + version.Root = apiPrefix + version.Storage = storage + return version, err +} + +func (s *GenericAPIServer) newAPIGroupVersion(groupMeta latest.GroupMeta, groupVersion unversioned.GroupVersion) (*apiserver.APIGroupVersion, error) { + versionInterface, err := groupMeta.InterfacesFor(groupVersion) + if err != nil { + return nil, err + } + return &apiserver.APIGroupVersion{ + RequestInfoResolver: s.NewRequestInfoResolver(), + + Creater: api.Scheme, + Convertor: api.Scheme, + Typer: api.Scheme, + + GroupVersion: groupVersion, + Linker: groupMeta.SelfLinker, + Mapper: groupMeta.RESTMapper, + Codec: versionInterface.Codec, + + Admit: s.AdmissionControl, + Context: s.RequestContextMapper, + + MinRequestTimeout: s.MinRequestTimeout, + }, nil +} + // InstallSwaggerAPI installs the /swaggerapi/ endpoint to allow schema discovery // and traversal. It is optional to allow consumers of the Kubernetes GenericAPIServer to // register their own web services into the Kubernetes mux prior to initialization diff --git a/pkg/genericapiserver/genericapiserver_test.go b/pkg/genericapiserver/genericapiserver_test.go index b49c18a236c..b82bb7ab5bd 100644 --- a/pkg/genericapiserver/genericapiserver_test.go +++ b/pkg/genericapiserver/genericapiserver_test.go @@ -21,8 +21,13 @@ import ( "fmt" "net" "net/http" + "net/http/httptest" "testing" + "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/api/latest" + "k8s.io/kubernetes/pkg/api/rest" + "k8s.io/kubernetes/pkg/apis/extensions" "k8s.io/kubernetes/pkg/apiserver" etcdtesting "k8s.io/kubernetes/pkg/storage/etcd/testing" "k8s.io/kubernetes/pkg/util" @@ -57,8 +62,8 @@ func TestNew(t *testing.T) { assert.Equal(s.enableUISupport, config.EnableUISupport) assert.Equal(s.enableSwaggerSupport, config.EnableSwaggerSupport) assert.Equal(s.enableProfiling, config.EnableProfiling) - assert.Equal(s.ApiPrefix, config.APIPrefix) - assert.Equal(s.ApiGroupPrefix, config.APIGroupPrefix) + assert.Equal(s.APIPrefix, config.APIPrefix) + assert.Equal(s.APIGroupPrefix, config.APIGroupPrefix) assert.Equal(s.corsAllowedOriginList, config.CorsAllowedOriginList) assert.Equal(s.authenticator, config.Authenticator) assert.Equal(s.authorizer, config.Authorizer) @@ -80,6 +85,54 @@ func TestNew(t *testing.T) { assert.Equal(s.ProxyTransport.(*http.Transport).TLSClientConfig, config.ProxyTLSClientConfig) } +// Verifies that AddGroupVersions works as expected. +func TestInstallAPIGroups(t *testing.T) { + _, etcdserver, config, assert := setUp(t) + defer etcdserver.Terminate(t) + + config.ProxyDialer = func(network, addr string) (net.Conn, error) { return nil, nil } + config.ProxyTLSClientConfig = &tls.Config{} + config.APIPrefix = "/apiPrefix" + config.APIGroupPrefix = "/apiGroupPrefix" + + s := New(&config) + apiGroupMeta := latest.GroupOrDie(api.GroupName) + extensionsGroupMeta := latest.GroupOrDie(extensions.GroupName) + apiGroupsInfo := []APIGroupInfo{ + { + // legacy group version + GroupMeta: *apiGroupMeta, + VersionedResourcesStorageMap: map[string]map[string]rest.Storage{}, + IsLegacyGroup: true, + }, + { + // extensions group version + GroupMeta: *extensionsGroupMeta, + VersionedResourcesStorageMap: map[string]map[string]rest.Storage{}, + OptionsExternalVersion: &apiGroupMeta.GroupVersion, + }, + } + s.InstallAPIGroups(apiGroupsInfo) + + server := httptest.NewServer(s.HandlerContainer.ServeMux) + validPaths := []string{ + // "/api" + config.APIPrefix, + // "/api/v1" + config.APIPrefix + "/" + apiGroupMeta.GroupVersion.Version, + // "/apis/extensions" + config.APIGroupPrefix + "/" + extensionsGroupMeta.GroupVersion.Group, + // "/apis/extensions/v1beta1" + config.APIGroupPrefix + "/" + extensionsGroupMeta.GroupVersion.String(), + } + for _, path := range validPaths { + _, err := http.Get(server.URL + path) + if !assert.NoError(err) { + t.Errorf("unexpected error: %v, for path: %s", err, path) + } + } +} + // TestNewHandlerContainer verifies that NewHandlerContainer uses the // mux provided func TestNewHandlerContainer(t *testing.T) { diff --git a/pkg/master/master.go b/pkg/master/master.go index 8b4ec7c286c..4a767fa1d44 100644 --- a/pkg/master/master.go +++ b/pkg/master/master.go @@ -30,8 +30,6 @@ import ( "k8s.io/kubernetes/pkg/api/latest" "k8s.io/kubernetes/pkg/api/rest" "k8s.io/kubernetes/pkg/api/unversioned" - apiutil "k8s.io/kubernetes/pkg/api/util" - "k8s.io/kubernetes/pkg/api/v1" "k8s.io/kubernetes/pkg/apis/extensions" "k8s.io/kubernetes/pkg/apiserver" "k8s.io/kubernetes/pkg/genericapiserver" @@ -159,14 +157,8 @@ func New(c *Config) *Master { } func (m *Master) InstallAPIs(c *Config) { - apiVersions := []string{} - // Install v1 unless disabled. - if !m.ApiGroupVersionOverrides["api/v1"].Disable { - if err := m.api_v1(c).InstallREST(m.HandlerContainer); err != nil { - glog.Fatalf("Unable to setup API v1: %v", err) - } - apiVersions = append(apiVersions, "v1") - } + apiGroupsInfo := []genericapiserver.APIGroupInfo{} + // Run the tunnel. healthzChecks := []healthz.HealthzChecker{} if m.tunneler != nil { @@ -180,12 +172,24 @@ func (m *Master) InstallAPIs(c *Config) { // TODO(nikhiljindal): Refactor generic parts of support services (like /versions) to genericapiserver. apiserver.InstallSupport(m.MuxHelper, m.RootWebService, c.EnableProfiling, healthzChecks...) + + // Install v1 unless disabled. + if !m.ApiGroupVersionOverrides["api/v1"].Disable { + // Install v1 API. + m.initV1ResourcesStorage(c) + apiGroupInfo := genericapiserver.APIGroupInfo{ + GroupMeta: *latest.GroupOrDie(api.GroupName), + VersionedResourcesStorageMap: map[string]map[string]rest.Storage{ + "v1": m.v1ResourcesStorage, + }, + IsLegacyGroup: true, + } + apiGroupsInfo = append(apiGroupsInfo, apiGroupInfo) + } + // Install root web services m.HandlerContainer.Add(m.RootWebService) - apiserver.AddApiWebService(m.HandlerContainer, c.APIPrefix, apiVersions) - apiserver.InstallServiceErrorHandler(m.HandlerContainer, m.NewRequestInfoResolver(), apiVersions) - // allGroups records all supported groups at /apis allGroups := []unversioned.APIGroup{} // Install extensions unless disabled. @@ -193,33 +197,41 @@ func (m *Master) InstallAPIs(c *Config) { m.thirdPartyStorage = c.StorageDestinations.APIGroups[extensions.GroupName].Default m.thirdPartyResources = map[string]thirdPartyEntry{} - expVersion := m.experimental(c) - - if err := expVersion.InstallREST(m.HandlerContainer); err != nil { - glog.Fatalf("Unable to setup experimental api: %v", err) - } - g, err := latest.Group(extensions.GroupName) - if err != nil { - glog.Fatalf("Unable to setup experimental api: %v", err) - } - expAPIVersions := []unversioned.GroupVersionForDiscovery{ - { - GroupVersion: expVersion.GroupVersion.String(), - Version: expVersion.GroupVersion.Version, - }, - } - storageVersion, found := c.StorageVersions[g.GroupVersion.Group] + extensionResources := m.getExtensionResources(c) + extensionsGroupMeta := latest.GroupOrDie(extensions.GroupName) + // Update the prefered version as per StorageVersions in the config. + storageVersion, found := c.StorageVersions[extensionsGroupMeta.GroupVersion.Group] if !found { - glog.Fatalf("Couldn't find storage version of group %v", g.GroupVersion.Group) + glog.Fatalf("Couldn't find storage version of group %v", extensionsGroupMeta.GroupVersion.Group) + } + preferedGroupVersion, err := unversioned.ParseGroupVersion(storageVersion) + if err != nil { + glog.Fatalf("Error in parsing group version %s: %v", storageVersion, err) + } + extensionsGroupMeta.GroupVersion = preferedGroupVersion + + apiGroupInfo := genericapiserver.APIGroupInfo{ + GroupMeta: *extensionsGroupMeta, + VersionedResourcesStorageMap: map[string]map[string]rest.Storage{ + "v1beta1": extensionResources, + }, + OptionsExternalVersion: &latest.GroupOrDie(api.GroupName).GroupVersion, + } + apiGroupsInfo = append(apiGroupsInfo, apiGroupInfo) + + extensionsGVForDiscovery := unversioned.GroupVersionForDiscovery{ + GroupVersion: extensionsGroupMeta.GroupVersion.String(), + Version: extensionsGroupMeta.GroupVersion.Version, } group := unversioned.APIGroup{ - Name: g.GroupVersion.Group, - Versions: expAPIVersions, - PreferredVersion: unversioned.GroupVersionForDiscovery{GroupVersion: storageVersion, Version: apiutil.GetVersion(storageVersion)}, + Name: extensionsGroupMeta.GroupVersion.Group, + Versions: []unversioned.GroupVersionForDiscovery{extensionsGVForDiscovery}, + PreferredVersion: extensionsGVForDiscovery, } - apiserver.AddGroupWebService(m.HandlerContainer, c.APIGroupPrefix+"/"+latest.GroupOrDie(extensions.GroupName).GroupVersion.Group, group) allGroups = append(allGroups, group) - apiserver.InstallServiceErrorHandler(m.HandlerContainer, m.NewRequestInfoResolver(), []string{expVersion.GroupVersion.String()}) + } + if err := m.InstallAPIGroups(apiGroupsInfo); err != nil { + glog.Fatalf("Error in registering group versions: %v", err) } // This should be done after all groups are registered @@ -398,39 +410,6 @@ func (m *Master) getServersToValidate(c *Config) map[string]apiserver.Server { return serversToValidate } -func (m *Master) defaultAPIGroupVersion() *apiserver.APIGroupVersion { - return &apiserver.APIGroupVersion{ - Root: m.ApiPrefix, - RequestInfoResolver: m.NewRequestInfoResolver(), - - Mapper: latest.GroupOrDie(api.GroupName).RESTMapper, - - Creater: api.Scheme, - Convertor: api.Scheme, - Typer: api.Scheme, - Linker: latest.GroupOrDie(api.GroupName).SelfLinker, - - Admit: m.AdmissionControl, - Context: m.RequestContextMapper, - - MinRequestTimeout: m.MinRequestTimeout, - } -} - -// api_v1 returns the resources and codec for API version v1. -func (m *Master) api_v1(c *Config) *apiserver.APIGroupVersion { - m.initV1ResourcesStorage(c) - storage := make(map[string]rest.Storage) - for k, v := range m.v1ResourcesStorage { - storage[strings.ToLower(k)] = v - } - version := m.defaultAPIGroupVersion() - version.Storage = storage - version.GroupVersion = unversioned.GroupVersion{Version: "v1"} - version.Codec = v1.Codec - return version -} - // HasThirdPartyResource returns true if a particular third party resource currently installed. func (m *Master) HasThirdPartyResource(rsrc *extensions.ThirdPartyResource) (bool, error) { _, group, err := thirdpartyresourcedata.ExtractApiGroupAndKind(rsrc) @@ -575,8 +554,8 @@ func (m *Master) thirdpartyapi(group, kind, version string) *apiserver.APIGroupV } } -// experimental returns the resources and codec for the experimental api -func (m *Master) experimental(c *Config) *apiserver.APIGroupVersion { +// getExperimentalResources returns the resources for extenstions api +func (m *Master) getExtensionResources(c *Config) map[string]rest.Storage { // All resources except these are disabled by default. enabledResources := sets.NewString("jobs", "horizontalpodautoscalers", "ingresses") resourceOverrides := m.ApiGroupVersionOverrides["extensions/v1beta1"].ResourceOverrides @@ -640,30 +619,7 @@ func (m *Master) experimental(c *Config) *apiserver.APIGroupVersion { storage["ingresses"] = ingressStorage storage["ingresses/status"] = ingressStatusStorage } - - extensionsGroup := latest.GroupOrDie(extensions.GroupName) - optionsExternalVersion := latest.GroupOrDie(api.GroupName).GroupVersion - - return &apiserver.APIGroupVersion{ - Root: m.ApiGroupPrefix, - RequestInfoResolver: m.NewRequestInfoResolver(), - - Creater: api.Scheme, - Convertor: api.Scheme, - Typer: api.Scheme, - - Mapper: extensionsGroup.RESTMapper, - Codec: extensionsGroup.Codec, - Linker: extensionsGroup.SelfLinker, - Storage: storage, - GroupVersion: extensionsGroup.GroupVersion, - OptionsExternalVersion: &optionsExternalVersion, - - Admit: m.AdmissionControl, - Context: m.RequestContextMapper, - - MinRequestTimeout: m.MinRequestTimeout, - } + return storage } // findExternalAddress returns ExternalIP of provided node with fallback to LegacyHostIP. diff --git a/pkg/master/master_test.go b/pkg/master/master_test.go index 3abc983b4a9..b1d2b77f07a 100644 --- a/pkg/master/master_test.go +++ b/pkg/master/master_test.go @@ -30,11 +30,9 @@ import ( "testing" "k8s.io/kubernetes/pkg/api" - "k8s.io/kubernetes/pkg/api/latest" "k8s.io/kubernetes/pkg/api/testapi" "k8s.io/kubernetes/pkg/api/unversioned" apiutil "k8s.io/kubernetes/pkg/api/util" - "k8s.io/kubernetes/pkg/api/v1" "k8s.io/kubernetes/pkg/apis/extensions" "k8s.io/kubernetes/pkg/genericapiserver" "k8s.io/kubernetes/pkg/kubelet/client" @@ -102,8 +100,8 @@ func TestNew(t *testing.T) { // Verify many of the variables match their config counterparts assert.Equal(master.enableCoreControllers, config.EnableCoreControllers) assert.Equal(master.tunneler, config.Tunneler) - assert.Equal(master.ApiPrefix, config.APIPrefix) - assert.Equal(master.ApiGroupPrefix, config.APIGroupPrefix) + assert.Equal(master.APIPrefix, config.APIPrefix) + assert.Equal(master.APIGroupPrefix, config.APIGroupPrefix) assert.Equal(master.ApiGroupVersionOverrides, config.APIGroupVersionOverrides) assert.Equal(master.RequestContextMapper, config.RequestContextMapper) assert.Equal(master.MasterCount, config.MasterCount) @@ -160,35 +158,6 @@ func TestFindExternalAddress(t *testing.T) { assert.Error(err, "expected findExternalAddress to fail on a node with missing ip information") } -// TestApi_v1 verifies that the unexported api_v1 function does indeed -// utilize the correct Version and Codec. -func TestApi_v1(t *testing.T) { - _, etcdserver, config, assert := setUp(t) - defer etcdserver.Terminate(t) - - // config.KubeletClient = client.FakeKubeletClient{} - - config.ProxyDialer = func(network, addr string) (net.Conn, error) { return nil, nil } - config.ProxyTLSClientConfig = &tls.Config{} - - s := genericapiserver.New(config.Config) - master := &Master{ - GenericAPIServer: s, - tunneler: config.Tunneler, - } - - version := master.api_v1(&config) - assert.Equal(unversioned.GroupVersion{Version: "v1"}, version.GroupVersion, "Version was not v1: %s", version.GroupVersion) - assert.Equal(v1.Codec, version.Codec, "version.Codec was not for v1: %s", version.Codec) - // Verify that version storage has all the resources. - for k, v := range master.v1ResourcesStorage { - k = strings.ToLower(k) - val, ok := version.Storage[k] - assert.True(ok, "ok: %s", ok) - assert.Equal(val, v) - } -} - // TestNewBootstrapController verifies master fields are properly copied into controller func TestNewBootstrapController(t *testing.T) { // Tests a subset of inputs to ensure they are set properly in the controller @@ -248,36 +217,6 @@ func TestControllerServicePorts(t *testing.T) { assert.Equal(1010, controller.ExtraServicePorts[1].Port) } -// TestDefaultAPIGroupVersion verifies that the unexported defaultAPIGroupVersion -// creates the expected APIGroupVersion based off of master. -func TestDefaultAPIGroupVersion(t *testing.T) { - master, etcdserver, _, assert := setUp(t) - defer etcdserver.Terminate(t) - - apiGroup := master.defaultAPIGroupVersion() - - assert.Equal(apiGroup.Root, master.ApiPrefix) - assert.Equal(apiGroup.Admit, master.AdmissionControl) - assert.Equal(apiGroup.Context, master.RequestContextMapper) - assert.Equal(apiGroup.MinRequestTimeout, master.MinRequestTimeout) -} - -// TestExpapi verifies that the unexported exapi creates -// the an experimental unversioned.APIGroupVersion. -func TestExpapi(t *testing.T) { - master, etcdserver, config, assert := setUp(t) - defer etcdserver.Terminate(t) - - extensionsGroupMeta := latest.GroupOrDie(extensions.GroupName) - - expAPIGroup := master.experimental(&config) - assert.Equal(expAPIGroup.Root, master.ApiGroupPrefix) - assert.Equal(expAPIGroup.Mapper, extensionsGroupMeta.RESTMapper) - assert.Equal(expAPIGroup.Codec, extensionsGroupMeta.Codec) - assert.Equal(expAPIGroup.Linker, extensionsGroupMeta.SelfLinker) - assert.Equal(expAPIGroup.GroupVersion, extensionsGroupMeta.GroupVersion) -} - // TestGetNodeAddresses verifies that proper results are returned // when requesting node addresses. func TestGetNodeAddresses(t *testing.T) {