Merge registered and latest and move to apimachinery

This commit is contained in:
nikhiljindal
2016-01-13 14:40:56 -08:00
parent a5dddfcb32
commit 2ad642d370
63 changed files with 378 additions and 387 deletions

View File

@@ -24,8 +24,8 @@ import (
"github.com/golang/glog"
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/latest"
"k8s.io/kubernetes/pkg/api/registered"
"k8s.io/kubernetes/pkg/apimachinery"
"k8s.io/kubernetes/pkg/apimachinery/registered"
"k8s.io/kubernetes/pkg/util/sets"
"k8s.io/kubernetes/pkg/api/meta"
@@ -42,8 +42,7 @@ var accessor = meta.NewAccessor()
var availableVersions = []unversioned.GroupVersion{v1.SchemeGroupVersion}
func init() {
registered.RegisterVersions(availableVersions...)
registered.RegisterVersions(availableVersions)
externalVersions := []unversioned.GroupVersion{}
for _, v := range availableVersions {
if registered.IsAllowedVersion(v) {
@@ -54,6 +53,7 @@ func init() {
glog.V(4).Infof("No version is registered for group %v", api.GroupName)
return
}
if err := registered.EnableVersions(externalVersions...); err != nil {
glog.V(4).Infof("%v", err)
return
@@ -66,11 +66,13 @@ func init() {
// 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 := latest.GroupMeta{
groupMeta := apimachinery.GroupMeta{
GroupVersion: preferredExternalVersion,
GroupVersions: externalVersions,
Codec: runtime.CodecFor(api.Scheme, preferredExternalVersion),
@@ -79,7 +81,7 @@ func enableVersions(externalVersions []unversioned.GroupVersion) error {
InterfacesFor: interfacesFor,
}
if err := latest.RegisterGroup(groupMeta); err != nil {
if err := registered.RegisterGroup(groupMeta); err != nil {
return err
}
api.RegisterRESTMapper(groupMeta.RESTMapper)
@@ -130,7 +132,7 @@ func interfacesFor(version unversioned.GroupVersion) (*meta.VersionInterfaces, e
MetadataAccessor: accessor,
}, nil
default:
g, _ := latest.Group(api.GroupName)
g, _ := registered.Group(api.GroupName)
return nil, fmt.Errorf("unsupported storage version: %s (valid: %v)", version, g.GroupVersions)
}
}

View File

@@ -21,8 +21,8 @@ import (
"testing"
internal "k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/latest"
"k8s.io/kubernetes/pkg/api/unversioned"
"k8s.io/kubernetes/pkg/apimachinery/registered"
)
func TestResourceVersioner(t *testing.T) {
@@ -47,9 +47,9 @@ func TestResourceVersioner(t *testing.T) {
func TestCodec(t *testing.T) {
pod := internal.Pod{}
// We do want to use package latest rather than testapi here, because we
// want to test if the package install and package latest work as expected.
data, err := latest.GroupOrDie(internal.GroupName).Codec.Encode(&pod)
// We do want to use package registered rather than testapi here, because we
// want to test if the package install and package registered work as expected.
data, err := registered.GroupOrDie(internal.GroupName).Codec.Encode(&pod)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
@@ -57,17 +57,17 @@ func TestCodec(t *testing.T) {
if err := json.Unmarshal(data, &other); err != nil {
t.Fatalf("unexpected error: %v", err)
}
if other.APIVersion != latest.GroupOrDie(internal.GroupName).GroupVersion.Version || other.Kind != "Pod" {
if other.APIVersion != registered.GroupOrDie(internal.GroupName).GroupVersion.Version || other.Kind != "Pod" {
t.Errorf("unexpected unmarshalled object %#v", other)
}
}
func TestInterfacesFor(t *testing.T) {
if _, err := latest.GroupOrDie(internal.GroupName).InterfacesFor(internal.SchemeGroupVersion); err == nil {
if _, err := registered.GroupOrDie(internal.GroupName).InterfacesFor(internal.SchemeGroupVersion); err == nil {
t.Fatalf("unexpected non-error: %v", err)
}
for i, version := range latest.GroupOrDie(internal.GroupName).GroupVersions {
if vi, err := latest.GroupOrDie(internal.GroupName).InterfacesFor(version); err != nil || vi == nil {
for i, version := range registered.GroupOrDie(internal.GroupName).GroupVersions {
if vi, err := registered.GroupOrDie(internal.GroupName).InterfacesFor(version); err != nil || vi == nil {
t.Fatalf("%d: unexpected result: %v", i, err)
}
}
@@ -78,16 +78,16 @@ func TestRESTMapper(t *testing.T) {
rcGVK := gv.WithKind("ReplicationController")
podTemplateGVK := gv.WithKind("PodTemplate")
if gvk, err := latest.GroupOrDie(internal.GroupName).RESTMapper.KindFor(internal.SchemeGroupVersion.WithResource("replicationcontrollers")); err != nil || gvk != rcGVK {
if gvk, err := registered.GroupOrDie(internal.GroupName).RESTMapper.KindFor(internal.SchemeGroupVersion.WithResource("replicationcontrollers")); err != nil || gvk != rcGVK {
t.Errorf("unexpected version mapping: %v %v", gvk, err)
}
if m, err := latest.GroupOrDie(internal.GroupName).RESTMapper.RESTMapping(podTemplateGVK.GroupKind(), ""); err != nil || m.GroupVersionKind != podTemplateGVK || m.Resource != "podtemplates" {
if m, err := registered.GroupOrDie(internal.GroupName).RESTMapper.RESTMapping(podTemplateGVK.GroupKind(), ""); err != nil || m.GroupVersionKind != podTemplateGVK || m.Resource != "podtemplates" {
t.Errorf("unexpected version mapping: %#v %v", m, err)
}
for _, version := range latest.GroupOrDie(internal.GroupName).GroupVersions {
mapping, err := latest.GroupOrDie(internal.GroupName).RESTMapper.RESTMapping(rcGVK.GroupKind(), version.Version)
for _, version := range registered.GroupOrDie(internal.GroupName).GroupVersions {
mapping, err := registered.GroupOrDie(internal.GroupName).RESTMapper.RESTMapping(rcGVK.GroupKind(), version.Version)
if err != nil {
t.Errorf("unexpected error: %v", err)
}
@@ -99,7 +99,7 @@ func TestRESTMapper(t *testing.T) {
t.Errorf("incorrect version: %v", mapping)
}
interfaces, _ := latest.GroupOrDie(internal.GroupName).InterfacesFor(version)
interfaces, _ := registered.GroupOrDie(internal.GroupName).InterfacesFor(version)
if mapping.Codec != interfaces.Codec {
t.Errorf("unexpected codec: %#v, expected: %#v", mapping, interfaces)
}

View File

@@ -1,21 +0,0 @@
/*
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 latest defines the default output serializations that code should
// use and imports the required schemas. It also ensures all previously known
// and supported API versions are available for conversion. Consumers may
// import this package in lieu of importing individual versions.
package latest

View File

@@ -1,140 +0,0 @@
/*
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 latest
import (
"fmt"
"sort"
"strings"
"k8s.io/kubernetes/pkg/api/meta"
"k8s.io/kubernetes/pkg/api/unversioned"
"k8s.io/kubernetes/pkg/runtime"
)
var (
allGroups = GroupMetaMap{}
// Group is a shortcut to allGroups.Group.
Group = allGroups.Group
// RegisterGroup is a shortcut to allGroups.RegisterGroup.
RegisterGroup = allGroups.RegisterGroup
// GroupOrDie is a shortcut to allGroups.GroupOrDie.
GroupOrDie = allGroups.GroupOrDie
// AllPreferredGroupVersions returns the preferred versions of all
// registered groups in the form of "group1/version1,group2/version2,..."
AllPreferredGroupVersions = allGroups.AllPreferredGroupVersions
// IsRegistered is a shortcut to allGroups.IsRegistered.
IsRegistered = allGroups.IsRegistered
)
// ExternalVersions is a list of all external versions for this API group in order of
// most preferred to least preferred
var ExternalVersions = []unversioned.GroupVersion{
{Group: "", Version: "v1"},
}
// GroupMetaMap is a map between group names and their metadata.
type GroupMetaMap map[string]*GroupMeta
// RegisterGroup registers a group to GroupMetaMap.
func (g GroupMetaMap) RegisterGroup(groupMeta GroupMeta) error {
groupName := groupMeta.GroupVersion.Group
if _, found := g[groupName]; found {
return fmt.Errorf("group %v is already registered", g)
}
g[groupName] = &groupMeta
return nil
}
// Group returns the metadata of a group if the gruop is registered, otherwise
// an erorr is returned.
func (g GroupMetaMap) Group(group string) (*GroupMeta, error) {
groupMeta, found := g[group]
if !found {
return nil, fmt.Errorf("no version is registered for group %v", group)
}
groupMetaCopy := *groupMeta
return &groupMetaCopy, nil
}
// IsRegistered takes a string and determines if it's one of the registered groups
func (g GroupMetaMap) IsRegistered(group string) bool {
_, found := g[group]
return found
}
// TODO: This is an expedient function, because we don't check if a Group is
// supported throughout the code base. We will abandon this function and
// checking the error returned by the Group() function.
func (g GroupMetaMap) GroupOrDie(group string) *GroupMeta {
groupMeta, found := g[group]
if !found {
const msg = "Please check the KUBE_API_VERSIONS environment variable."
if group == "" {
panic("The legacy v1 API is not registered. " + msg)
} else {
panic(fmt.Sprintf("No version is registered for group %s. ", group) + msg)
}
}
groupMetaCopy := *groupMeta
return &groupMetaCopy
}
// AllPreferredGroupVersions returns the preferred versions of all registered
// groups in the form of "group1/version1,group2/version2,..."
func (g GroupMetaMap) AllPreferredGroupVersions() string {
if len(g) == 0 {
return ""
}
var defaults []string
for _, groupMeta := range g {
defaults = append(defaults, groupMeta.GroupVersion.String())
}
sort.Strings(defaults)
return strings.Join(defaults, ",")
}
// GroupMeta stores the metadata of a group, such as the latest supported version.
type GroupMeta struct {
// GroupVersion represents the current external default version of the group.
GroupVersion unversioned.GroupVersion
// GroupVersions is Group + Versions. This is to avoid string concatenation
// in many places.
GroupVersions []unversioned.GroupVersion
// Codec is the default codec for serializing output that should use
// the latest supported version. Use this Codec when writing to
// disk, a data store that is not dynamically versioned, or in tests.
// This codec can decode any object that Kubernetes is aware of.
Codec runtime.Codec
// SelfLinker can set or get the SelfLink field of all API types.
// TODO: when versioning changes, make this part of each API definition.
// TODO(lavalamp): Combine SelfLinker & ResourceVersioner interfaces, force all uses
// to go through the InterfacesFor method below.
SelfLinker runtime.SelfLinker
// RESTMapper provides the default mapping between REST paths and the objects declared in api.Scheme and all known
// Kubernetes versions.
RESTMapper meta.RESTMapper
// InterfacesFor returns the default Codec and ResourceVersioner for a given version
// or an error if the version is not known.
InterfacesFor func(version unversioned.GroupVersion) (*meta.VersionInterfaces, error)
}

View File

@@ -1,63 +0,0 @@
/*
Copyright 2015 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 latest
import (
"testing"
"k8s.io/kubernetes/pkg/api/unversioned"
)
func TestAllPreferredGroupVersions(t *testing.T) {
testCases := []struct {
groupMetaMap GroupMetaMap
expect string
}{
{
groupMetaMap: GroupMetaMap{
"group1": &GroupMeta{
GroupVersion: unversioned.GroupVersion{"group1", "v1"},
},
"group2": &GroupMeta{
GroupVersion: unversioned.GroupVersion{"group2", "v2"},
},
"": &GroupMeta{
GroupVersion: unversioned.GroupVersion{"", "v1"},
},
},
expect: "group1/v1,group2/v2,v1",
},
{
groupMetaMap: GroupMetaMap{
"": &GroupMeta{
GroupVersion: unversioned.GroupVersion{"", "v1"},
},
},
expect: "v1",
},
{
groupMetaMap: GroupMetaMap{},
expect: "",
},
}
for _, testCase := range testCases {
output := testCase.groupMetaMap.AllPreferredGroupVersions()
if testCase.expect != output {
t.Errorf("Error. expect: %s, got: %s", testCase.expect, output)
}
}
}

View File

@@ -1,154 +0,0 @@
/*
Copyright 2015 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 to keep track of API Versions that should be registered in api.Scheme.
package registered
import (
"fmt"
"os"
"strings"
"github.com/golang/glog"
"k8s.io/kubernetes/pkg/api/unversioned"
)
var (
// registeredVersions represents all registered API versions. Please call
// RegisterVersions() to add registered versions.
registeredVersions = map[unversioned.GroupVersion]struct{}{}
// enabledVersions represents all enabled API versions. It should be a
// subset of registeredVersions. Please call EnableVersions() to add
// enabled versions.
enabledVersions = map[unversioned.GroupVersion]struct{}{}
// envRequestedVersions represents the versions requested via the
// KUBE_API_VERSIONS environment variable. The install package of each group
// checks this list before add their versions to the latest package and
// Scheme.
envRequestedVersions = map[unversioned.GroupVersion]struct{}{}
)
func init() {
// Env var KUBE_API_VERSIONS is a comma separated list of API versions that
// should be registered in the scheme.
kubeAPIVersions := os.Getenv("KUBE_API_VERSIONS")
if len(kubeAPIVersions) != 0 {
for _, version := range strings.Split(kubeAPIVersions, ",") {
gv, err := unversioned.ParseGroupVersion(version)
if err != nil {
glog.Fatalf("invalid api version: %s in KUBE_API_VERSIONS: %s.",
version, os.Getenv("KUBE_API_VERSIONS"))
}
envRequestedVersions[gv] = struct{}{}
}
}
}
// RegisterVersions add the versions the registeredVersions.
func RegisterVersions(versions ...unversioned.GroupVersion) {
for _, v := range versions {
registeredVersions[v] = struct{}{}
}
}
// EnableVersions add the versions to the enabledVersions. The caller of this
// function is responsible to add the version to 'latest' and 'Scheme'.
func EnableVersions(versions ...unversioned.GroupVersion) error {
var unregisteredVersions []unversioned.GroupVersion
for _, v := range versions {
if _, found := registeredVersions[v]; !found {
unregisteredVersions = append(unregisteredVersions, v)
}
enabledVersions[v] = struct{}{}
}
if len(unregisteredVersions) != 0 {
return fmt.Errorf("Please register versions before enabling them: %v", unregisteredVersions)
}
return nil
}
// IsAllowedVersion returns if the version is allowed by the KUBE_API_VERSIONS
// environment variable. If the environment variable is empty, then it always
// returns true.
func IsAllowedVersion(v unversioned.GroupVersion) bool {
if len(envRequestedVersions) == 0 {
return true
}
_, found := envRequestedVersions[v]
return found
}
// IsEnabledVersion returns if a version is enabled.
func IsEnabledVersion(v unversioned.GroupVersion) bool {
_, found := enabledVersions[v]
return found
}
// IsRegisteredVersion returns if a version is registered.
func IsRegisteredVersion(v unversioned.GroupVersion) bool {
_, found := registeredVersions[v]
return found
}
// EnabledVersions returns all enabled versions.
func EnabledVersions() (ret []unversioned.GroupVersion) {
for v := range enabledVersions {
ret = append(ret, v)
}
return
}
// RegisteredVersions returns all registered versions.
func RegisteredVersions() (ret []unversioned.GroupVersion) {
for v := range registeredVersions {
ret = append(ret, v)
}
return
}
// EnabledVersionsForGroup returns all enabled versions for a group.
func EnabledVersionsForGroup(group string) (ret []unversioned.GroupVersion) {
for v := range enabledVersions {
if v.Group == group {
ret = append(ret, v)
}
}
return
}
// RegisteredVersionsForGroup returns all registered versions for a group.
func RegisteredVersionsForGroup(group string) (ret []unversioned.GroupVersion) {
for v := range registeredVersions {
if v.Group == group {
ret = append(ret, v)
}
}
return
}
// ValidateEnvRequestedVersions returns a list of versions that are requested in
// the KUBE_API_VERSIONS environment variable, but not enabled.
func ValidateEnvRequestedVersions() []unversioned.GroupVersion {
var missingVersions []unversioned.GroupVersion
for v := range envRequestedVersions {
if _, found := enabledVersions[v]; !found {
missingVersions = append(missingVersions, v)
}
}
return missingVersions
}

View File

@@ -27,9 +27,9 @@ import (
_ "k8s.io/kubernetes/pkg/apis/extensions/install"
_ "k8s.io/kubernetes/pkg/apis/metrics/install"
"k8s.io/kubernetes/pkg/api/latest"
"k8s.io/kubernetes/pkg/api/meta"
"k8s.io/kubernetes/pkg/api/unversioned"
"k8s.io/kubernetes/pkg/apimachinery/registered"
"k8s.io/kubernetes/pkg/apis/extensions"
"k8s.io/kubernetes/pkg/runtime"
)
@@ -64,13 +64,13 @@ func init() {
if _, ok := Groups[api.GroupName]; !ok {
Groups[api.GroupName] = TestGroup{
externalGroupVersion: unversioned.GroupVersion{Group: api.GroupName, Version: latest.GroupOrDie(api.GroupName).GroupVersion.Version},
externalGroupVersion: unversioned.GroupVersion{Group: api.GroupName, Version: registered.GroupOrDie(api.GroupName).GroupVersion.Version},
internalGroupVersion: api.SchemeGroupVersion,
}
}
if _, ok := Groups[extensions.GroupName]; !ok {
Groups[extensions.GroupName] = TestGroup{
externalGroupVersion: unversioned.GroupVersion{Group: extensions.GroupName, Version: latest.GroupOrDie(extensions.GroupName).GroupVersion.Version},
externalGroupVersion: unversioned.GroupVersion{Group: extensions.GroupName, Version: registered.GroupOrDie(extensions.GroupName).GroupVersion.Version},
internalGroupVersion: extensions.SchemeGroupVersion,
}
}
@@ -93,8 +93,8 @@ func (g TestGroup) InternalGroupVersion() unversioned.GroupVersion {
// Codec returns the codec for the API version to test against, as set by the
// KUBE_TEST_API env var.
func (g TestGroup) Codec() runtime.Codec {
// TODO: caesarxuchao: Restructure the body once we have a central `latest`.
interfaces, err := latest.GroupOrDie(g.externalGroupVersion.Group).InterfacesFor(g.externalGroupVersion)
// TODO: caesarxuchao: Restructure the body once we have a central `registered`.
interfaces, err := registered.GroupOrDie(g.externalGroupVersion.Group).InterfacesFor(g.externalGroupVersion)
if err != nil {
panic(err)
}
@@ -104,7 +104,7 @@ func (g TestGroup) Codec() runtime.Codec {
// Converter returns the api.Scheme for the API version to test against, as set by the
// KUBE_TEST_API env var.
func (g TestGroup) Converter() runtime.ObjectConvertor {
interfaces, err := latest.GroupOrDie(g.externalGroupVersion.Group).InterfacesFor(g.externalGroupVersion)
interfaces, err := registered.GroupOrDie(g.externalGroupVersion.Group).InterfacesFor(g.externalGroupVersion)
if err != nil {
panic(err)
}
@@ -114,7 +114,7 @@ func (g TestGroup) Converter() runtime.ObjectConvertor {
// MetadataAccessor returns the MetadataAccessor for the API version to test against,
// as set by the KUBE_TEST_API env var.
func (g TestGroup) MetadataAccessor() meta.MetadataAccessor {
interfaces, err := latest.GroupOrDie(g.externalGroupVersion.Group).InterfacesFor(g.externalGroupVersion)
interfaces, err := registered.GroupOrDie(g.externalGroupVersion.Group).InterfacesFor(g.externalGroupVersion)
if err != nil {
panic(err)
}
@@ -178,7 +178,7 @@ func (g TestGroup) ResourcePath(resource, namespace, name string) string {
}
func (g TestGroup) RESTMapper() meta.RESTMapper {
return latest.GroupOrDie(g.externalGroupVersion.Group).RESTMapper
return registered.GroupOrDie(g.externalGroupVersion.Group).RESTMapper
}
// Get codec based on runtime.Object