From cf0c1fee445bed82bcc4081d5c1cec15052bea19 Mon Sep 17 00:00:00 2001 From: jianhuiz Date: Mon, 9 May 2016 17:08:28 -0700 Subject: [PATCH] register service object only --- federation/apis/core/install/install.go | 160 ++++++++++++++++++ federation/apis/core/register.go | 75 ++++++++ federation/apis/core/v1/conversion.go | 58 +++++++ federation/apis/core/v1/defaults.go | 28 +++ federation/apis/core/v1/register.go | 53 ++++++ .../cmd/federated-apiserver/app/core.go | 17 +- 6 files changed, 383 insertions(+), 8 deletions(-) create mode 100644 federation/apis/core/install/install.go create mode 100644 federation/apis/core/register.go create mode 100644 federation/apis/core/v1/conversion.go create mode 100644 federation/apis/core/v1/defaults.go create mode 100644 federation/apis/core/v1/register.go diff --git a/federation/apis/core/install/install.go b/federation/apis/core/install/install.go new file mode 100644 index 00000000000..5659821109c --- /dev/null +++ b/federation/apis/core/install/install.go @@ -0,0 +1,160 @@ +/* +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 install + +import ( + "fmt" + + "github.com/golang/glog" + + core "k8s.io/kubernetes/federation/apis/core" + core_v1 "k8s.io/kubernetes/federation/apis/core/v1" + "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/api/meta" + "k8s.io/kubernetes/pkg/api/unversioned" + "k8s.io/kubernetes/pkg/api/v1" + "k8s.io/kubernetes/pkg/apimachinery" + "k8s.io/kubernetes/pkg/apimachinery/registered" + "k8s.io/kubernetes/pkg/conversion" + "k8s.io/kubernetes/pkg/runtime" + "k8s.io/kubernetes/pkg/util/sets" +) + +const importPrefix = "k8s.io/kubernetes/federation/api" + +var accessor = meta.NewAccessor() + +// availableVersions lists all known external versions for this group from most preferred to least preferred +var availableVersions = []unversioned.GroupVersion{core_v1.SchemeGroupVersion} + +func init() { + registered.RegisterVersions(availableVersions) + externalVersions := []unversioned.GroupVersion{} + for _, v := range availableVersions { + if registered.IsAllowedVersion(v) { + externalVersions = append(externalVersions, v) + } + } + if len(externalVersions) == 0 { + glog.V(4).Infof("No version is registered for group %v", core.GroupName) + return + } + + if err := registered.EnableVersions(externalVersions...); err != nil { + glog.V(4).Infof("%v", err) + return + } + if err := enableVersions(externalVersions); err != nil { + glog.V(4).Infof("%v", err) + return + } +} + +// TODO: enableVersions should be centralized rather than spread in each API +// group. +// We can combine registered.RegisterVersions, registered.EnableVersions and +// registered.RegisterGroup once we have moved enableVersions there. +func enableVersions(externalVersions []unversioned.GroupVersion) error { + addVersionsToScheme(externalVersions...) + preferredExternalVersion := externalVersions[0] + + groupMeta := apimachinery.GroupMeta{ + GroupVersion: preferredExternalVersion, + GroupVersions: externalVersions, + RESTMapper: newRESTMapper(externalVersions), + SelfLinker: runtime.SelfLinker(accessor), + InterfacesFor: interfacesFor, + } + + if err := registered.RegisterGroup(groupMeta); err != nil { + return err + } + api.RegisterRESTMapper(groupMeta.RESTMapper) + return nil +} + +// userResources is a group of resources mostly used by a kubectl user +var userResources = []string{"svc"} + +func newRESTMapper(externalVersions []unversioned.GroupVersion) meta.RESTMapper { + // the list of kinds that are scoped at the root of the api hierarchy + // if a kind is not enumerated here, it is assumed to have a namespace scope + rootScoped := sets.NewString() + + // these kinds should be excluded from the list of resources + ignoredKinds := sets.NewString( + "ListOptions", + "DeleteOptions", + "Status") + + mapper := api.NewDefaultRESTMapper(externalVersions, interfacesFor, importPrefix, ignoredKinds, rootScoped) + // setup aliases for groups of resources + mapper.AddResourceAlias("all", userResources...) + + return mapper +} + +// InterfacesFor returns the default Codec and ResourceVersioner for a given version +// string, or an error if the version is not known. +func interfacesFor(version unversioned.GroupVersion) (*meta.VersionInterfaces, error) { + switch version { + case core_v1.SchemeGroupVersion: + return &meta.VersionInterfaces{ + ObjectConvertor: core.Scheme, + MetadataAccessor: accessor, + }, nil + default: + g, _ := registered.Group(core.GroupName) + return nil, fmt.Errorf("unsupported storage version: %s (valid: %v)", version, g.GroupVersions) + } +} + +func addVersionsToScheme(externalVersions ...unversioned.GroupVersion) { + // add the internal version to Scheme + core.AddToScheme(core.Scheme) + // add the enabled external versions to Scheme + for _, v := range externalVersions { + if !registered.IsEnabledVersion(v) { + glog.Errorf("Version %s is not enabled, so it will not be added to the Scheme.", v) + continue + } + switch v { + case core_v1.SchemeGroupVersion: + core_v1.AddToScheme(core.Scheme) + } + } + + // This is a "fast-path" that avoids reflection for common types. It focuses on the objects that are + // converted the most in the cluster. + // TODO: generate one of these for every external API group - this is to prove the impact + core.Scheme.AddGenericConversionFunc(func(objA, objB interface{}, s conversion.Scope) (bool, error) { + switch a := objA.(type) { + case *v1.Service: + switch b := objB.(type) { + case *api.Service: + return true, v1.Convert_v1_Service_To_api_Service(a, b, s) + } + case *api.Service: + switch b := objB.(type) { + case *v1.Service: + return true, v1.Convert_api_Service_To_v1_Service(a, b, s) + } + + } + return false, nil + }) +} diff --git a/federation/apis/core/register.go b/federation/apis/core/register.go new file mode 100644 index 00000000000..609a4dbbfdd --- /dev/null +++ b/federation/apis/core/register.go @@ -0,0 +1,75 @@ +/* +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 core + +import ( + "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/api/unversioned" + "k8s.io/kubernetes/pkg/runtime" + "k8s.io/kubernetes/pkg/runtime/serializer" +) + +// Scheme is the default instance of runtime.Scheme to which types in the Kubernetes API are already registered. +var Scheme = runtime.NewScheme() + +// Codecs provides access to encoding and decoding for the scheme +var Codecs = serializer.NewCodecFactory(Scheme) + +// GroupName is the group name use in this package +const GroupName = "" + +// SchemeGroupVersion is group version used to register these objects +var SchemeGroupVersion = unversioned.GroupVersion{Group: GroupName, Version: runtime.APIVersionInternal} + +// Unversiond is group version for unversioned API objects +// TODO: this should be v1 probably +var Unversioned = unversioned.GroupVersion{Group: "", Version: "v1"} + +// ParameterCodec handles versioning of objects that are converted to query parameters. +var ParameterCodec = runtime.NewParameterCodec(Scheme) + +// Kind takes an unqualified kind and returns back a Group qualified GroupKind +func Kind(kind string) unversioned.GroupKind { + return SchemeGroupVersion.WithKind(kind).GroupKind() +} + +// Resource takes an unqualified resource and returns back a Group qualified GroupResource +func Resource(resource string) unversioned.GroupResource { + return SchemeGroupVersion.WithResource(resource).GroupResource() +} + +func AddToScheme(scheme *runtime.Scheme) { + if err := Scheme.AddIgnoredConversionType(&unversioned.TypeMeta{}, &unversioned.TypeMeta{}); err != nil { + panic(err) + } + scheme.AddKnownTypes(SchemeGroupVersion, + &api.ServiceList{}, + &api.Service{}, + &api.ListOptions{}, + &api.DeleteOptions{}, + ) + + // Register Unversioned types under their own special group + Scheme.AddUnversionedTypes(Unversioned, + &unversioned.ExportOptions{}, + &unversioned.Status{}, + &unversioned.APIVersions{}, + &unversioned.APIGroupList{}, + &unversioned.APIGroup{}, + &unversioned.APIResourceList{}, + ) +} diff --git a/federation/apis/core/v1/conversion.go b/federation/apis/core/v1/conversion.go new file mode 100644 index 00000000000..e04cdd97f8a --- /dev/null +++ b/federation/apis/core/v1/conversion.go @@ -0,0 +1,58 @@ +/* +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 v1 + +import ( + "fmt" + + "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/api/v1" + "k8s.io/kubernetes/pkg/runtime" +) + +func addConversionFuncs(scheme *runtime.Scheme) { + // Add non-generated conversion functions + err := scheme.AddConversionFuncs( + v1.Convert_api_ServiceSpec_To_v1_ServiceSpec, + v1.Convert_v1_ServiceSpec_To_api_ServiceSpec, + ) + if err != nil { + // If one of the conversion functions is malformed, detect it immediately. + panic(err) + } + + // Add field label conversions for kinds having selectable nothing but ObjectMeta fields. + for _, kind := range []string{ + "Service", + } { + err = api.Scheme.AddFieldLabelConversionFunc("v1", kind, + func(label, value string) (string, string, error) { + switch label { + case "metadata.namespace", + "metadata.name": + return label, value, nil + default: + return "", "", fmt.Errorf("field label %q not supported for %q", label, kind) + } + }) + if err != nil { + // If one of the conversion functions is malformed, detect it immediately. + panic(err) + } + } + +} diff --git a/federation/apis/core/v1/defaults.go b/federation/apis/core/v1/defaults.go new file mode 100644 index 00000000000..5e03961883c --- /dev/null +++ b/federation/apis/core/v1/defaults.go @@ -0,0 +1,28 @@ +/* +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 v1 + +import ( + "k8s.io/kubernetes/pkg/api/v1" + "k8s.io/kubernetes/pkg/runtime" +) + +func addDefaultingFuncs(scheme *runtime.Scheme) { + scheme.AddDefaultingFuncs( + v1.SetDefaults_ServiceSpec, + ) +} diff --git a/federation/apis/core/v1/register.go b/federation/apis/core/v1/register.go new file mode 100644 index 00000000000..d942d976d83 --- /dev/null +++ b/federation/apis/core/v1/register.go @@ -0,0 +1,53 @@ +/* +Copyright 2014 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 v1 + +import ( + "k8s.io/kubernetes/pkg/api/unversioned" + "k8s.io/kubernetes/pkg/api/v1" + "k8s.io/kubernetes/pkg/runtime" + versionedwatch "k8s.io/kubernetes/pkg/watch/versioned" +) + +// GroupName is the group name use in this package +const GroupName = "" + +// SchemeGroupVersion is group version used to register these objects +var SchemeGroupVersion = unversioned.GroupVersion{Group: GroupName, Version: "v1"} + +func AddToScheme(scheme *runtime.Scheme) { + // Add the API to Scheme. + addKnownTypes(scheme) + addConversionFuncs(scheme) + addDefaultingFuncs(scheme) +} + +// Adds the list of known types to api.Scheme. +func addKnownTypes(scheme *runtime.Scheme) { + scheme.AddKnownTypes(SchemeGroupVersion, + &v1.Service{}, + &v1.ServiceList{}, + &v1.ListOptions{}, + &v1.DeleteOptions{}, + ) + + // Add common types + scheme.AddKnownTypes(SchemeGroupVersion, &unversioned.Status{}) + + // Add the watch version that applies + versionedwatch.AddToGroupVersion(scheme, SchemeGroupVersion) +} diff --git a/federation/cmd/federated-apiserver/app/core.go b/federation/cmd/federated-apiserver/app/core.go index 6ab735d19f7..f91884b36ad 100644 --- a/federation/cmd/federated-apiserver/app/core.go +++ b/federation/cmd/federated-apiserver/app/core.go @@ -21,10 +21,11 @@ import ( "k8s.io/kubernetes/pkg/apimachinery/registered" "k8s.io/kubernetes/pkg/genericapiserver" + "k8s.io/kubernetes/federation/apis/core" + _ "k8s.io/kubernetes/federation/apis/core/install" + "k8s.io/kubernetes/federation/apis/core/v1" "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" ) @@ -34,19 +35,19 @@ func installCoreAPIs(s *genericapiserver.ServerRunOptions, g *genericapiserver.G "services": serviceStore, "services/status": serviceStatusStorage, } - coreGroupMeta := registered.GroupOrDie(api.GroupName) + coreGroupMeta := registered.GroupOrDie(core.GroupName) apiGroupInfo := genericapiserver.APIGroupInfo{ GroupMeta: *coreGroupMeta, VersionedResourcesStorageMap: map[string]map[string]rest.Storage{ v1.SchemeGroupVersion.Version: coreResources, }, - OptionsExternalVersion: ®istered.GroupOrDie(api.GroupName).GroupVersion, + OptionsExternalVersion: ®istered.GroupOrDie(core.GroupName).GroupVersion, IsLegacyGroup: true, - Scheme: api.Scheme, - ParameterCodec: api.ParameterCodec, - NegotiatedSerializer: api.Codecs, + Scheme: core.Scheme, + ParameterCodec: core.ParameterCodec, + NegotiatedSerializer: core.Codecs, } if err := g.InstallAPIGroup(&apiGroupInfo); err != nil { - glog.Fatalf("Error in registering group versions: %v", err) + glog.Fatalf("Error in registering group version: %v", err) } }