diff --git a/federation/cmd/federated-apiserver/app/core.go b/federation/cmd/federated-apiserver/app/core.go new file mode 100644 index 00000000000..6ab735d19f7 --- /dev/null +++ b/federation/cmd/federated-apiserver/app/core.go @@ -0,0 +1,52 @@ +/* +Copyright 2016 The Kubernetes Authors All rights reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package app + +import ( + "github.com/golang/glog" + "k8s.io/kubernetes/pkg/apimachinery/registered" + "k8s.io/kubernetes/pkg/genericapiserver" + + "k8s.io/kubernetes/pkg/api" + _ "k8s.io/kubernetes/pkg/api/install" + "k8s.io/kubernetes/pkg/api/rest" + "k8s.io/kubernetes/pkg/api/v1" + serviceetcd "k8s.io/kubernetes/pkg/registry/service/etcd" +) + +func installCoreAPIs(s *genericapiserver.ServerRunOptions, g *genericapiserver.GenericAPIServer, f genericapiserver.StorageFactory) { + serviceStore, serviceStatusStorage := serviceetcd.NewREST(createRESTOptionsOrDie(s, g, f, api.Resource("service"))) + coreResources := map[string]rest.Storage{ + "services": serviceStore, + "services/status": serviceStatusStorage, + } + coreGroupMeta := registered.GroupOrDie(api.GroupName) + apiGroupInfo := genericapiserver.APIGroupInfo{ + GroupMeta: *coreGroupMeta, + VersionedResourcesStorageMap: map[string]map[string]rest.Storage{ + v1.SchemeGroupVersion.Version: coreResources, + }, + OptionsExternalVersion: ®istered.GroupOrDie(api.GroupName).GroupVersion, + IsLegacyGroup: true, + Scheme: api.Scheme, + ParameterCodec: api.ParameterCodec, + NegotiatedSerializer: api.Codecs, + } + if err := g.InstallAPIGroup(&apiGroupInfo); err != nil { + glog.Fatalf("Error in registering group versions: %v", err) + } +} diff --git a/federation/cmd/federated-apiserver/app/federation.go b/federation/cmd/federated-apiserver/app/federation.go index 0a4460721b0..5fcbd3ba10f 100644 --- a/federation/cmd/federated-apiserver/app/federation.go +++ b/federation/cmd/federated-apiserver/app/federation.go @@ -24,22 +24,13 @@ import ( "k8s.io/kubernetes/pkg/api/rest" "k8s.io/kubernetes/pkg/apimachinery/registered" "k8s.io/kubernetes/pkg/genericapiserver" - "k8s.io/kubernetes/pkg/registry/generic" _ "k8s.io/kubernetes/federation/apis/federation/install" clusteretcd "k8s.io/kubernetes/federation/registry/cluster/etcd" ) func installFederationAPIs(s *genericapiserver.ServerRunOptions, g *genericapiserver.GenericAPIServer, f genericapiserver.StorageFactory) { - storage, err := f.New(federation.Resource("clusters")) - if err != nil { - glog.Fatalf("Unable to find storage destination for %v, due to %v", "clusters", err.Error()) - } - clusterStorage, clusterStatusStorage := clusteretcd.NewREST(generic.RESTOptions{ - Storage: storage, - Decorator: g.StorageDecorator(), - DeleteCollectionWorkers: s.DeleteCollectionWorkers, - }) + clusterStorage, clusterStatusStorage := clusteretcd.NewREST(createRESTOptionsOrDie(s, g, f, federation.Resource("clusters"))) federationResources := map[string]rest.Storage{ "clusters": clusterStorage, "clusters/status": clusterStatusStorage, diff --git a/federation/cmd/federated-apiserver/app/server.go b/federation/cmd/federated-apiserver/app/server.go index 4990936dd3b..0bb0de8f64f 100644 --- a/federation/cmd/federated-apiserver/app/server.go +++ b/federation/cmd/federated-apiserver/app/server.go @@ -33,6 +33,7 @@ import ( "k8s.io/kubernetes/pkg/apiserver/authenticator" "k8s.io/kubernetes/pkg/genericapiserver" "k8s.io/kubernetes/pkg/registry/cachesize" + "k8s.io/kubernetes/pkg/registry/generic" ) // NewAPIServerCommand creates a *cobra.Command object with default parameters @@ -141,7 +142,20 @@ func Run(s *genericapiserver.ServerRunOptions) error { } installFederationAPIs(s, m, storageFactory) + installCoreAPIs(s, m, storageFactory) m.Run(s) return nil } + +func createRESTOptionsOrDie(s *genericapiserver.ServerRunOptions, g *genericapiserver.GenericAPIServer, f genericapiserver.StorageFactory, resource unversioned.GroupResource) generic.RESTOptions { + storage, err := f.New(resource) + if err != nil { + glog.Fatalf("Unable to find storage destination for %v, due to %v", resource, err.Error()) + } + return generic.RESTOptions{ + Storage: storage, + Decorator: g.StorageDecorator(), + DeleteCollectionWorkers: s.DeleteCollectionWorkers, + } +} diff --git a/federation/cmd/federated-apiserver/app/server_test.go b/federation/cmd/federated-apiserver/app/server_test.go index 07f469fa905..5b9ea45f831 100644 --- a/federation/cmd/federated-apiserver/app/server_test.go +++ b/federation/cmd/federated-apiserver/app/server_test.go @@ -30,6 +30,7 @@ import ( "github.com/stretchr/testify/assert" fed_v1a1 "k8s.io/kubernetes/federation/apis/federation/v1alpha1" "k8s.io/kubernetes/pkg/api/unversioned" + "k8s.io/kubernetes/pkg/api/v1" "k8s.io/kubernetes/pkg/genericapiserver" ) @@ -76,7 +77,9 @@ func TestLongRunningRequestRegexp(t *testing.T) { var insecurePort = 8082 var serverIP = fmt.Sprintf("http://localhost:%v", insecurePort) -var groupVersion = fed_v1a1.SchemeGroupVersion +var groupVersions = []unversioned.GroupVersion{ + fed_v1a1.SchemeGroupVersion, +} func TestRun(t *testing.T) { s := genericapiserver.NewServerRunOptions() @@ -151,9 +154,12 @@ func findGroup(groups []unversioned.APIGroup, groupName string) *unversioned.API } func testAPIGroupList(t *testing.T) { - var groupVersionForDiscovery = unversioned.GroupVersionForDiscovery{ - GroupVersion: groupVersion.String(), - Version: groupVersion.Version, + groupVersionForDiscoveryMap := make(map[string]unversioned.GroupVersionForDiscovery) + for _, groupVersion := range groupVersions { + groupVersionForDiscoveryMap[groupVersion.Group] = unversioned.GroupVersionForDiscovery{ + GroupVersion: groupVersion.String(), + Version: groupVersion.Version, + } } serverURL := serverIP + "/apis" @@ -167,31 +173,59 @@ func testAPIGroupList(t *testing.T) { t.Fatalf("Error in unmarshalling response from server %s: %v", serverURL, err) } - found := findGroup(apiGroupList.Groups, groupVersion.Group) - assert.NotNil(t, found) - assert.Equal(t, found.Name, groupVersion.Group) - assert.Equal(t, 1, len(found.Versions)) - assert.Equal(t, found.Versions[0], groupVersionForDiscovery) - assert.Equal(t, found.PreferredVersion, groupVersionForDiscovery) + for _, groupVersion := range groupVersions { + found := findGroup(apiGroupList.Groups, groupVersion.Group) + assert.NotNil(t, found) + assert.Equal(t, groupVersion.Group, found.Name) + assert.Equal(t, 1, len(found.Versions)) + groupVersionForDiscovery := groupVersionForDiscoveryMap[groupVersion.Group] + assert.Equal(t, groupVersionForDiscovery, found.Versions[0]) + assert.Equal(t, groupVersionForDiscovery, found.PreferredVersion) + } } func testAPIGroup(t *testing.T) { - serverURL := serverIP + "/apis/federation" + for _, groupVersion := range groupVersions { + serverURL := serverIP + "/apis/" + groupVersion.Group + contents, err := readResponse(serverURL) + if err != nil { + t.Fatalf("%v", err) + } + var apiGroup unversioned.APIGroup + err = json.Unmarshal(contents, &apiGroup) + if err != nil { + t.Fatalf("Error in unmarshalling response from server %s: %v", serverURL, err) + } + // empty APIVersion for extensions group + if groupVersion.Group == "extensions" { + assert.Equal(t, "", apiGroup.APIVersion) + } else { + assert.Equal(t, "v1", apiGroup.APIVersion) + } + assert.Equal(t, apiGroup.Name, groupVersion.Group) + assert.Equal(t, 1, len(apiGroup.Versions)) + assert.Equal(t, groupVersion.String(), apiGroup.Versions[0].GroupVersion) + assert.Equal(t, groupVersion.Version, apiGroup.Versions[0].Version) + assert.Equal(t, apiGroup.PreferredVersion, apiGroup.Versions[0]) + } + + testCoreAPIGroup(t) +} + +func testCoreAPIGroup(t *testing.T) { + serverURL := serverIP + "/api" contents, err := readResponse(serverURL) if err != nil { t.Fatalf("%v", err) } - var apiGroup unversioned.APIGroup - err = json.Unmarshal(contents, &apiGroup) + var apiVersions unversioned.APIVersions + err = json.Unmarshal(contents, &apiVersions) if err != nil { t.Fatalf("Error in unmarshalling response from server %s: %v", serverURL, err) } - assert.Equal(t, apiGroup.APIVersion, "v1") - assert.Equal(t, apiGroup.Name, groupVersion.Group) - assert.Equal(t, 1, len(apiGroup.Versions)) - assert.Equal(t, apiGroup.Versions[0].GroupVersion, groupVersion.String()) - assert.Equal(t, apiGroup.Versions[0].Version, groupVersion.Version) - assert.Equal(t, apiGroup.Versions[0], apiGroup.PreferredVersion) + assert.Equal(t, 1, len(apiVersions.Versions)) + assert.Equal(t, "v1", apiVersions.Versions[0]) + assert.NotEmpty(t, apiVersions.ServerAddressByClientCIDRs) } func findResource(resources []unversioned.APIResource, resourceName string) *unversioned.APIResource { @@ -204,7 +238,12 @@ func findResource(resources []unversioned.APIResource, resourceName string) *unv } func testAPIResourceList(t *testing.T) { - serverURL := serverIP + "/apis/federation/v1alpha1" + testFederationResourceList(t) + testCoreResourceList(t) +} + +func testFederationResourceList(t *testing.T) { + serverURL := serverIP + "/apis/" + fed_v1a1.SchemeGroupVersion.String() contents, err := readResponse(serverURL) if err != nil { t.Fatalf("%v", err) @@ -214,8 +253,8 @@ func testAPIResourceList(t *testing.T) { if err != nil { t.Fatalf("Error in unmarshalling response from server %s: %v", serverURL, err) } - assert.Equal(t, apiResourceList.APIVersion, "v1") - assert.Equal(t, apiResourceList.GroupVersion, groupVersion.String()) + assert.Equal(t, "v1", apiResourceList.APIVersion) + assert.Equal(t, fed_v1a1.SchemeGroupVersion.String(), apiResourceList.GroupVersion) found := findResource(apiResourceList.APIResources, "clusters") assert.NotNil(t, found) @@ -224,3 +263,25 @@ func testAPIResourceList(t *testing.T) { assert.NotNil(t, found) assert.False(t, found.Namespaced) } + +func testCoreResourceList(t *testing.T) { + serverURL := serverIP + "/api/" + v1.SchemeGroupVersion.String() + contents, err := readResponse(serverURL) + if err != nil { + t.Fatalf("%v", err) + } + var apiResourceList unversioned.APIResourceList + err = json.Unmarshal(contents, &apiResourceList) + if err != nil { + t.Fatalf("Error in unmarshalling response from server %s: %v", serverURL, err) + } + assert.Equal(t, "", apiResourceList.APIVersion) + assert.Equal(t, v1.SchemeGroupVersion.String(), apiResourceList.GroupVersion) + + found := findResource(apiResourceList.APIResources, "services") + assert.NotNil(t, found) + assert.True(t, found.Namespaced) + found = findResource(apiResourceList.APIResources, "services/status") + assert.NotNil(t, found) + assert.True(t, found.Namespaced) +}