Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

federation: avoid double core group registration #42722

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 2 additions & 0 deletions federation/apis/core/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
7 changes: 2 additions & 5 deletions federation/apis/core/install/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -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",
],
)
Expand Down
136 changes: 26 additions & 110 deletions federation/apis/core/install/install.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
}
}
}
15 changes: 15 additions & 0 deletions federation/apis/core/register.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,28 @@ 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"
"k8s.io/apimachinery/pkg/runtime/serializer"
"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()

Expand Down