diff --git a/federation/apis/core/BUILD b/federation/apis/core/BUILD index bfea44162bd..45bb3ad0891 100644 --- a/federation/apis/core/BUILD +++ b/federation/apis/core/BUILD @@ -13,6 +13,8 @@ go_library( tags = ["automanaged"], deps = [ "//pkg/api:go_default_library", + "//vendor:k8s.io/apimachinery/pkg/apimachinery/announced", + "//vendor:k8s.io/apimachinery/pkg/apimachinery/registered", "//vendor:k8s.io/apimachinery/pkg/apis/meta/v1", "//vendor:k8s.io/apimachinery/pkg/runtime", "//vendor:k8s.io/apimachinery/pkg/runtime/schema", diff --git a/federation/apis/core/install/BUILD b/federation/apis/core/install/BUILD index 900bffa1338..54cf236ab55 100644 --- a/federation/apis/core/install/BUILD +++ b/federation/apis/core/install/BUILD @@ -14,12 +14,9 @@ go_library( deps = [ "//federation/apis/core:go_default_library", "//federation/apis/core/v1:go_default_library", - "//pkg/api:go_default_library", - "//vendor:github.com/golang/glog", - "//vendor:k8s.io/apimachinery/pkg/api/meta", - "//vendor:k8s.io/apimachinery/pkg/apimachinery", + "//vendor:k8s.io/apimachinery/pkg/apimachinery/announced", + "//vendor:k8s.io/apimachinery/pkg/apimachinery/registered", "//vendor:k8s.io/apimachinery/pkg/runtime", - "//vendor:k8s.io/apimachinery/pkg/runtime/schema", "//vendor:k8s.io/apimachinery/pkg/util/sets", ], ) diff --git a/federation/apis/core/install/install.go b/federation/apis/core/install/install.go index 1cd5e0a451a..cde0a187b56 100644 --- a/federation/apis/core/install/install.go +++ b/federation/apis/core/install/install.go @@ -17,123 +17,39 @@ limitations under the License. package install import ( - "fmt" - - "github.com/golang/glog" - - "k8s.io/apimachinery/pkg/api/meta" - "k8s.io/apimachinery/pkg/apimachinery" + "k8s.io/apimachinery/pkg/apimachinery/announced" + "k8s.io/apimachinery/pkg/apimachinery/registered" "k8s.io/apimachinery/pkg/runtime" - "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/util/sets" - core "k8s.io/kubernetes/federation/apis/core" - core_v1 "k8s.io/kubernetes/federation/apis/core/v1" - "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/federation/apis/core" + corev1 "k8s.io/kubernetes/federation/apis/core/v1" ) -const importPrefix = "k8s.io/kubernetes/pkg/api" - -var accessor = meta.NewAccessor() - -// availableVersions lists all known external versions for this group from most preferred to least preferred -var availableVersions = []schema.GroupVersion{core_v1.SchemeGroupVersion} - func init() { - api.Registry.RegisterVersions(availableVersions) - externalVersions := []schema.GroupVersion{} - for _, v := range availableVersions { - if api.Registry.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 := api.Registry.EnableVersions(externalVersions...); err != nil { - glog.V(4).Infof("%v", err) - return - } - if err := enableVersions(externalVersions); err != nil { - glog.V(4).Infof("%v", err) - return - } + Install(core.GroupFactoryRegistry, core.Registry, core.Scheme) } -// TODO: enableVersions should be centralized rather than spread in each API -// group. -// We can combine api.Registry.RegisterVersions, api.Registry.EnableVersions and -// api.Registry.RegisterGroup once we have moved enableVersions there. -func enableVersions(externalVersions []schema.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 := api.Registry.RegisterGroup(groupMeta); err != nil { - return err - } - return nil -} - -func newRESTMapper(externalVersions []schema.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( - "Namespace", - ) - - // these kinds should be excluded from the list of resources - ignoredKinds := sets.NewString( - "ListOptions", - "DeleteOptions", - "Status") - - mapper := meta.NewDefaultRESTMapperFromScheme(externalVersions, interfacesFor, importPrefix, ignoredKinds, rootScoped, core.Scheme) - - 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 schema.GroupVersion) (*meta.VersionInterfaces, error) { - switch version { - case core_v1.SchemeGroupVersion: - return &meta.VersionInterfaces{ - ObjectConvertor: core.Scheme, - MetadataAccessor: accessor, - }, nil - default: - g, _ := api.Registry.Group(core.GroupName) - return nil, fmt.Errorf("unsupported storage version: %s (valid: %v)", version, g.GroupVersions) - } -} - -func addVersionsToScheme(externalVersions ...schema.GroupVersion) { - // add the internal version to Scheme - if err := core.AddToScheme(core.Scheme); err != nil { - // Programmer error, detect immediately +// Install registers the API group and adds types to a scheme +func Install(groupFactoryRegistry announced.APIGroupFactoryRegistry, registry *registered.APIRegistrationManager, scheme *runtime.Scheme) { + if err := announced.NewGroupMetaFactory( + &announced.GroupMetaFactoryArgs{ + GroupName: core.GroupName, + VersionPreferenceOrder: []string{corev1.SchemeGroupVersion.Version}, + ImportPrefix: "k8s.io/kubernetes/federation/apis/core", + AddInternalObjectsToScheme: core.AddToScheme, + RootScopedKinds: sets.NewString( + "Namespace", + ), + IgnoredKinds: sets.NewString( + "ListOptions", + "DeleteOptions", + "Status", + ), + }, + announced.VersionToSchemeFunc{ + corev1.SchemeGroupVersion.Version: corev1.AddToScheme, + }, + ).Announce(groupFactoryRegistry).RegisterAndEnable(registry, scheme); err != nil { panic(err) } - // add the enabled external versions to Scheme - for _, v := range externalVersions { - if !api.Registry.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: - if err := core_v1.AddToScheme(core.Scheme); err != nil { - // Programmer error, detect immediately - panic(err) - } - } - } } diff --git a/federation/apis/core/register.go b/federation/apis/core/register.go index e68da277ec3..efb4dd5845a 100644 --- a/federation/apis/core/register.go +++ b/federation/apis/core/register.go @@ -17,6 +17,10 @@ limitations under the License. package core import ( + "os" + + "k8s.io/apimachinery/pkg/apimachinery/announced" + "k8s.io/apimachinery/pkg/apimachinery/registered" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" @@ -24,6 +28,17 @@ import ( "k8s.io/kubernetes/pkg/api" ) +// NOTE: the registry, scheme and codecs are created here to allow to install a federation core group +// that is completely independent from the Kubernetes core group. It's only used for the core group itself. +// The other apigroups in the federation apiserver use the Kubernetes registry, scheme and codecs. + +// GroupFactoryRegistry is the APIGroupFactoryRegistry (overlaps a bit with Registry, see comments in package for details) +var GroupFactoryRegistry = make(announced.APIGroupFactoryRegistry) + +// Registry is an instance of an API registry. This is an interim step to start removing the idea of a global +// API registry. +var Registry = registered.NewOrDie(os.Getenv("KUBE_API_VERSIONS")) + // Scheme is the default instance of runtime.Scheme to which types in the Kubernetes API are already registered. var Scheme = runtime.NewScheme()