Commit 3e56ce64 authored by k8s-merge-robot's avatar k8s-merge-robot

Merge pull request #17327 from deads2k/gv-restmapper

Auto commit by PR queue bot
parents 431c6771 c40dd033
...@@ -30,7 +30,7 @@ import ( ...@@ -30,7 +30,7 @@ import (
"k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/meta" "k8s.io/kubernetes/pkg/api/meta"
"k8s.io/kubernetes/pkg/api/registered" "k8s.io/kubernetes/pkg/api/registered"
apiutil "k8s.io/kubernetes/pkg/api/util" "k8s.io/kubernetes/pkg/api/unversioned"
"k8s.io/kubernetes/pkg/api/v1" "k8s.io/kubernetes/pkg/api/v1"
"k8s.io/kubernetes/pkg/runtime" "k8s.io/kubernetes/pkg/runtime"
) )
...@@ -48,20 +48,24 @@ func init() { ...@@ -48,20 +48,24 @@ func init() {
glog.V(4).Infof("%v", err) glog.V(4).Infof("%v", err)
return return
} }
worstToBestGroupVersions := []unversioned.GroupVersion{}
// Use the first API version in the list of registered versions as the latest. // Use the first API version in the list of registered versions as the latest.
registeredGroupVersions := registered.GroupVersionsForGroup("") registeredGroupVersions := registered.GroupVersionsForGroup("")
groupVersion := registeredGroupVersions[0] groupVersion := registeredGroupVersions[0]
*groupMeta = latest.GroupMeta{ *groupMeta = latest.GroupMeta{
GroupVersion: groupVersion, GroupVersion: groupVersion.String(),
Group: apiutil.GetGroup(groupVersion), Group: groupVersion.Group,
Version: apiutil.GetVersion(groupVersion), Version: groupVersion.Version,
Codec: runtime.CodecFor(api.Scheme, groupVersion), Codec: runtime.CodecFor(api.Scheme, groupVersion.String()),
} }
var versions []string var versions []string
var groupVersions []string var groupVersions []string
for i := len(registeredGroupVersions) - 1; i >= 0; i-- { for i := len(registeredGroupVersions) - 1; i >= 0; i-- {
versions = append(versions, apiutil.GetVersion(registeredGroupVersions[i])) versions = append(versions, registeredGroupVersions[i].Version)
groupVersions = append(groupVersions, registeredGroupVersions[i]) groupVersions = append(groupVersions, registeredGroupVersions[i].String())
worstToBestGroupVersions = append(worstToBestGroupVersions, registeredGroupVersions[i])
} }
groupMeta.Versions = versions groupMeta.Versions = versions
groupMeta.GroupVersions = groupVersions groupMeta.GroupVersions = groupVersions
...@@ -90,7 +94,7 @@ func init() { ...@@ -90,7 +94,7 @@ func init() {
"ThirdPartyResourceData", "ThirdPartyResourceData",
"ThirdPartyResourceList") "ThirdPartyResourceList")
mapper := api.NewDefaultRESTMapper("", versions, interfacesFor, importPrefix, ignoredKinds, rootScoped) mapper := api.NewDefaultRESTMapper(worstToBestGroupVersions, interfacesFor, importPrefix, ignoredKinds, rootScoped)
// setup aliases for groups of resources // setup aliases for groups of resources
mapper.AddResourceAlias("all", userResources...) mapper.AddResourceAlias("all", userResources...)
groupMeta.RESTMapper = mapper groupMeta.RESTMapper = mapper
......
...@@ -17,7 +17,6 @@ limitations under the License. ...@@ -17,7 +17,6 @@ limitations under the License.
package api package api
import ( import (
"fmt"
"strings" "strings"
"k8s.io/kubernetes/pkg/api/meta" "k8s.io/kubernetes/pkg/api/meta"
...@@ -35,23 +34,16 @@ func RegisterRESTMapper(m meta.RESTMapper) { ...@@ -35,23 +34,16 @@ func RegisterRESTMapper(m meta.RESTMapper) {
RESTMapper = append(RESTMapper.(meta.MultiRESTMapper), m) RESTMapper = append(RESTMapper.(meta.MultiRESTMapper), m)
} }
func NewDefaultRESTMapper(group string, groupVersionStrings []string, interfacesFunc meta.VersionInterfacesFunc, func NewDefaultRESTMapper(defaultGroupVersions []unversioned.GroupVersion, interfacesFunc meta.VersionInterfacesFunc,
importPathPrefix string, ignoredKinds, rootScoped sets.String) *meta.DefaultRESTMapper { importPathPrefix string, ignoredKinds, rootScoped sets.String) *meta.DefaultRESTMapper {
mapper := meta.NewDefaultRESTMapper(group, groupVersionStrings, interfacesFunc) mapper := meta.NewDefaultRESTMapper(defaultGroupVersions, interfacesFunc)
// enumerate all supported versions, get the kinds, and register with the mapper how to address // enumerate all supported versions, get the kinds, and register with the mapper how to address
// our resources. // our resources.
for _, gvString := range groupVersionStrings { for _, gv := range defaultGroupVersions {
gv, err := unversioned.ParseGroupVersion(gvString)
// TODO stop panicing when the types are fixed
if err != nil {
panic(err)
}
if gv.Group != group {
panic(fmt.Sprintf("%q does not match the expect %q", gv.Group, group))
}
for kind, oType := range Scheme.KnownTypes(gv.String()) { for kind, oType := range Scheme.KnownTypes(gv.String()) {
gvk := gv.WithKind(kind)
// TODO: Remove import path prefix check. // TODO: Remove import path prefix check.
// We check the import path prefix because we currently stuff both "api" and "extensions" objects // We check the import path prefix because we currently stuff both "api" and "extensions" objects
// into the same group within Scheme since Scheme has no notion of groups yet. // into the same group within Scheme since Scheme has no notion of groups yet.
...@@ -62,7 +54,7 @@ func NewDefaultRESTMapper(group string, groupVersionStrings []string, interfaces ...@@ -62,7 +54,7 @@ func NewDefaultRESTMapper(group string, groupVersionStrings []string, interfaces
if rootScoped.Has(kind) { if rootScoped.Has(kind) {
scope = meta.RESTScopeRoot scope = meta.RESTScopeRoot
} }
mapper.Add(scope, kind, gv.String(), false) mapper.Add(gvk, scope, false)
} }
} }
return mapper return mapper
......
...@@ -56,13 +56,6 @@ var RESTScopeRoot = &restScope{ ...@@ -56,13 +56,6 @@ var RESTScopeRoot = &restScope{
name: RESTScopeNameRoot, name: RESTScopeNameRoot,
} }
// typeMeta is used as a key for lookup in the mapping between REST path and
// API object.
type typeMeta struct {
APIVersion string
Kind string
}
// DefaultRESTMapper exposes mappings between the types defined in a // DefaultRESTMapper exposes mappings between the types defined in a
// runtime.Scheme. It assumes that all types defined the provided scheme // runtime.Scheme. It assumes that all types defined the provided scheme
// can be mapped with the provided MetadataAccessor and Codec interfaces. // can be mapped with the provided MetadataAccessor and Codec interfaces.
...@@ -76,12 +69,14 @@ type typeMeta struct { ...@@ -76,12 +69,14 @@ type typeMeta struct {
// (`get pod bar` vs `get pods bar`) // (`get pod bar` vs `get pods bar`)
// TODO these maps should be keyed based on GroupVersionKinds // TODO these maps should be keyed based on GroupVersionKinds
type DefaultRESTMapper struct { type DefaultRESTMapper struct {
mapping map[string]typeMeta defaultGroupVersions []unversioned.GroupVersion
reverse map[typeMeta]string
scopes map[typeMeta]RESTScope resourceToKind map[string]unversioned.GroupVersionKind
groupVersions []unversioned.GroupVersion kindToPluralResource map[unversioned.GroupVersionKind]string
plurals map[string]string kindToScope map[unversioned.GroupVersionKind]RESTScope
singulars map[string]string singularToPlural map[string]string
pluralToSingular map[string]string
interfacesFunc VersionInterfacesFunc interfacesFunc VersionInterfacesFunc
} }
...@@ -94,54 +89,41 @@ type VersionInterfacesFunc func(apiVersion string) (*VersionInterfaces, error) ...@@ -94,54 +89,41 @@ type VersionInterfacesFunc func(apiVersion string) (*VersionInterfaces, error)
// and the Kubernetes API conventions. Takes a group name, a priority list of the versions // and the Kubernetes API conventions. Takes a group name, a priority list of the versions
// to search when an object has no default version (set empty to return an error), // to search when an object has no default version (set empty to return an error),
// and a function that retrieves the correct codec and metadata for a given version. // and a function that retrieves the correct codec and metadata for a given version.
// TODO remove group when this API is fixed. It is no longer used. func NewDefaultRESTMapper(defaultGroupVersions []unversioned.GroupVersion, f VersionInterfacesFunc) *DefaultRESTMapper {
// The external API for a RESTMapper is cross-version and this is currently called using resourceToKind := make(map[string]unversioned.GroupVersionKind)
// group/version tuples. In the end, the structure may be easier to understand with kindToPluralResource := make(map[unversioned.GroupVersionKind]string)
// a GroupRESTMapper and CrossGroupRESTMapper, but for now, this one is constructed and kindToScope := make(map[unversioned.GroupVersionKind]RESTScope)
// used a CrossGroupRESTMapper. singularToPlural := make(map[string]string)
func NewDefaultRESTMapper(group string, gvStrings []string, f VersionInterfacesFunc) *DefaultRESTMapper { pluralToSingular := make(map[string]string)
mapping := make(map[string]typeMeta)
reverse := make(map[typeMeta]string)
scopes := make(map[typeMeta]RESTScope)
plurals := make(map[string]string)
singulars := make(map[string]string)
// TODO: verify name mappings work correctly when versions differ // TODO: verify name mappings work correctly when versions differ
gvs := []unversioned.GroupVersion{}
for _, gvString := range gvStrings {
gvs = append(gvs, unversioned.ParseGroupVersionOrDie(gvString))
}
return &DefaultRESTMapper{ return &DefaultRESTMapper{
mapping: mapping, resourceToKind: resourceToKind,
reverse: reverse, kindToPluralResource: kindToPluralResource,
scopes: scopes, kindToScope: kindToScope,
groupVersions: gvs, defaultGroupVersions: defaultGroupVersions,
plurals: plurals, singularToPlural: singularToPlural,
singulars: singulars, pluralToSingular: pluralToSingular,
interfacesFunc: f, interfacesFunc: f,
} }
} }
func (m *DefaultRESTMapper) Add(scope RESTScope, kind string, gvString string, mixedCase bool) { func (m *DefaultRESTMapper) Add(gvk unversioned.GroupVersionKind, scope RESTScope, mixedCase bool) {
gv := unversioned.ParseGroupVersionOrDie(gvString) plural, singular := KindToResource(gvk.Kind, mixedCase)
m.singularToPlural[singular] = plural
plural, singular := KindToResource(kind, mixedCase) m.pluralToSingular[plural] = singular
m.plurals[singular] = plural _, ok1 := m.resourceToKind[plural]
m.singulars[plural] = singular _, ok2 := m.resourceToKind[strings.ToLower(plural)]
meta := typeMeta{APIVersion: gv.String(), Kind: kind}
_, ok1 := m.mapping[plural]
_, ok2 := m.mapping[strings.ToLower(plural)]
if !ok1 && !ok2 { if !ok1 && !ok2 {
m.mapping[plural] = meta m.resourceToKind[plural] = gvk
m.mapping[singular] = meta m.resourceToKind[singular] = gvk
if strings.ToLower(plural) != plural { if strings.ToLower(plural) != plural {
m.mapping[strings.ToLower(plural)] = meta m.resourceToKind[strings.ToLower(plural)] = gvk
m.mapping[strings.ToLower(singular)] = meta m.resourceToKind[strings.ToLower(singular)] = gvk
} }
} }
m.reverse[meta] = plural m.kindToPluralResource[gvk] = plural
m.scopes[meta] = scope m.kindToScope[gvk] = scope
} }
// KindToResource converts Kind to a resource name. // KindToResource converts Kind to a resource name.
...@@ -173,7 +155,7 @@ func KindToResource(kind string, mixedCase bool) (plural, singular string) { ...@@ -173,7 +155,7 @@ func KindToResource(kind string, mixedCase bool) (plural, singular string) {
// ResourceSingularizer implements RESTMapper // ResourceSingularizer implements RESTMapper
// It converts a resource name from plural to singular (e.g., from pods to pod) // It converts a resource name from plural to singular (e.g., from pods to pod)
func (m *DefaultRESTMapper) ResourceSingularizer(resource string) (singular string, err error) { func (m *DefaultRESTMapper) ResourceSingularizer(resource string) (singular string, err error) {
singular, ok := m.singulars[resource] singular, ok := m.pluralToSingular[resource]
if !ok { if !ok {
return resource, fmt.Errorf("no singular of resource %q has been defined", resource) return resource, fmt.Errorf("no singular of resource %q has been defined", resource)
} }
...@@ -181,25 +163,21 @@ func (m *DefaultRESTMapper) ResourceSingularizer(resource string) (singular stri ...@@ -181,25 +163,21 @@ func (m *DefaultRESTMapper) ResourceSingularizer(resource string) (singular stri
} }
// VersionAndKindForResource implements RESTMapper // VersionAndKindForResource implements RESTMapper
func (m *DefaultRESTMapper) VersionAndKindForResource(resource string) (defaultVersion, kind string, err error) { func (m *DefaultRESTMapper) VersionAndKindForResource(resource string) (gvString, kind string, err error) {
meta, ok := m.mapping[strings.ToLower(resource)] gvk, ok := m.resourceToKind[strings.ToLower(resource)]
if !ok { if !ok {
return "", "", fmt.Errorf("in version and kind for resource, no resource %q has been defined", resource) return "", "", fmt.Errorf("in version and kind for resource, no resource %q has been defined", resource)
} }
return meta.APIVersion, meta.Kind, nil return gvk.GroupVersion().String(), gvk.Kind, nil
} }
func (m *DefaultRESTMapper) GroupForResource(resource string) (string, error) { func (m *DefaultRESTMapper) GroupForResource(resource string) (string, error) {
typemeta, exists := m.mapping[strings.ToLower(resource)] gvk, exists := m.resourceToKind[strings.ToLower(resource)]
if !exists { if !exists {
return "", fmt.Errorf("in group for resource, no resource %q has been defined", resource) return "", fmt.Errorf("in group for resource, no resource %q has been defined", resource)
} }
gv, err := unversioned.ParseGroupVersion(typemeta.APIVersion) return gvk.Group, nil
if err != nil {
return "", err
}
return gv.Group, nil
} }
// RESTMapping returns a struct representing the resource path and conversion interfaces a // RESTMapping returns a struct representing the resource path and conversion interfaces a
...@@ -223,16 +201,18 @@ func (m *DefaultRESTMapper) RESTMapping(kind string, versions ...string) (*RESTM ...@@ -223,16 +201,18 @@ func (m *DefaultRESTMapper) RESTMapping(kind string, versions ...string) (*RESTM
return nil, err return nil, err
} }
currGVK := currGroupVersion.WithKind(kind)
hadVersion = true hadVersion = true
if _, ok := m.reverse[typeMeta{APIVersion: currGroupVersion.String(), Kind: kind}]; ok { if _, ok := m.kindToPluralResource[currGVK]; ok {
groupVersion = &currGroupVersion groupVersion = &currGroupVersion
break break
} }
} }
// Use the default preferred versions // Use the default preferred versions
if !hadVersion && (groupVersion == nil) { if !hadVersion && (groupVersion == nil) {
for _, currGroupVersion := range m.groupVersions { for _, currGroupVersion := range m.defaultGroupVersions {
if _, ok := m.reverse[typeMeta{APIVersion: currGroupVersion.String(), Kind: kind}]; ok { currGVK := currGroupVersion.WithKind(kind)
if _, ok := m.kindToPluralResource[currGVK]; ok {
groupVersion = &currGroupVersion groupVersion = &currGroupVersion
break break
} }
...@@ -242,14 +222,14 @@ func (m *DefaultRESTMapper) RESTMapping(kind string, versions ...string) (*RESTM ...@@ -242,14 +222,14 @@ func (m *DefaultRESTMapper) RESTMapping(kind string, versions ...string) (*RESTM
return nil, fmt.Errorf("no kind named %q is registered in versions %q", kind, versions) return nil, fmt.Errorf("no kind named %q is registered in versions %q", kind, versions)
} }
gvk := unversioned.NewGroupVersionKind(*groupVersion, kind) gvk := groupVersion.WithKind(kind)
// Ensure we have a REST mapping // Ensure we have a REST mapping
resource, ok := m.reverse[typeMeta{APIVersion: gvk.GroupVersion().String(), Kind: gvk.Kind}] resource, ok := m.kindToPluralResource[gvk]
if !ok { if !ok {
found := []unversioned.GroupVersion{} found := []unversioned.GroupVersion{}
for _, gv := range m.groupVersions { for _, gv := range m.defaultGroupVersions {
if _, ok := m.reverse[typeMeta{APIVersion: gv.String(), Kind: kind}]; ok { if _, ok := m.kindToPluralResource[gvk]; ok {
found = append(found, gv) found = append(found, gv)
} }
} }
...@@ -260,7 +240,7 @@ func (m *DefaultRESTMapper) RESTMapping(kind string, versions ...string) (*RESTM ...@@ -260,7 +240,7 @@ func (m *DefaultRESTMapper) RESTMapping(kind string, versions ...string) (*RESTM
} }
// Ensure we have a REST scope // Ensure we have a REST scope
scope, ok := m.scopes[typeMeta{APIVersion: gvk.GroupVersion().String(), Kind: gvk.Kind}] scope, ok := m.kindToScope[gvk]
if !ok { if !ok {
return nil, fmt.Errorf("the provided version %q and kind %q cannot be mapped to a supported scope", gvk.GroupVersion().String(), gvk.Kind) return nil, fmt.Errorf("the provided version %q and kind %q cannot be mapped to a supported scope", gvk.GroupVersion().String(), gvk.Kind)
} }
......
...@@ -22,46 +22,60 @@ import ( ...@@ -22,46 +22,60 @@ import (
"strings" "strings"
"github.com/golang/glog" "github.com/golang/glog"
apiutil "k8s.io/kubernetes/pkg/api/util" "k8s.io/kubernetes/pkg/api/unversioned"
) )
// List of registered API versions. // List of registered API versions.
// The list is in the order of most preferred to the least. // The list is in the order of most preferred to the least.
var RegisteredVersions []string var RegisteredGroupVersions []unversioned.GroupVersion
func init() { func init() {
validGroupVersions := map[string]bool{ validGroupVersions := map[unversioned.GroupVersion]bool{
"v1": true, unversioned.GroupVersion{Group: "", Version: "v1"}: true,
"extensions/v1beta1": true, unversioned.GroupVersion{Group: "extensions", Version: "v1beta1"}: true,
"componentconfig/v1alpha1": true, unversioned.GroupVersion{Group: "componentconfig", Version: "v1alpha1"}: true,
"metrics/v1alpha1": true, unversioned.GroupVersion{Group: "metrics", Version: "v1alpha1"}: true,
} }
// The default list of supported api versions, in order of most preferred to the least. // The default list of supported api versions, in order of most preferred to the least.
defaultSupportedVersions := "v1,extensions/v1beta1,componentconfig/v1alpha1" supportedVersions := []unversioned.GroupVersion{
{Group: "", Version: "v1"},
{Group: "extensions", Version: "v1beta1"},
{Group: "componentconfig", Version: "v1alpha1"},
}
// Env var KUBE_API_VERSIONS is a comma separated list of API versions that should be registered in the scheme. // Env var KUBE_API_VERSIONS is a comma separated list of API versions that should be registered in the scheme.
// The versions should be in the order of most preferred to the least. // The versions should be in the order of most preferred to the least.
supportedVersions := os.Getenv("KUBE_API_VERSIONS") userRequestedVersions := os.Getenv("KUBE_API_VERSIONS")
if supportedVersions == "" { if len(userRequestedVersions) != 0 {
supportedVersions = defaultSupportedVersions // reset the supported versions
} supportedVersions = []unversioned.GroupVersion{}
versions := strings.Split(supportedVersions, ",") for _, version := range strings.Split(userRequestedVersions, ",") {
for _, version := range versions { gv, err := unversioned.ParseGroupVersion(version)
// Verify that the version is valid. if err != nil {
valid, ok := validGroupVersions[version] glog.Fatalf("invalid api version: %s in KUBE_API_VERSIONS: %s. List of valid API versions: %v",
if !ok || !valid { version, os.Getenv("KUBE_API_VERSIONS"), validGroupVersions)
// Not a valid API version. }
glog.Fatalf("invalid api version: %s in KUBE_API_VERSIONS: %s. List of valid API versions: %v",
version, os.Getenv("KUBE_API_VERSIONS"), validGroupVersions) // Verify that the version is valid.
valid, ok := validGroupVersions[gv]
if !ok || !valid {
// Not a valid API version.
glog.Fatalf("invalid api version: %s in KUBE_API_VERSIONS: %s. List of valid API versions: %v",
version, os.Getenv("KUBE_API_VERSIONS"), validGroupVersions)
}
supportedVersions = append(supportedVersions, gv)
} }
RegisteredVersions = append(RegisteredVersions, version)
} }
RegisteredGroupVersions = supportedVersions
} }
// Returns true if the given api version is one of the registered api versions. // Returns true if the given api version is one of the registered api versions.
func IsRegisteredAPIVersion(version string) bool { func IsRegisteredAPIGroupVersion(gv unversioned.GroupVersion) bool {
for _, apiVersion := range RegisteredVersions { for _, currGV := range RegisteredGroupVersions {
if apiVersion == version { if currGV == gv {
return true return true
} }
} }
...@@ -70,10 +84,10 @@ func IsRegisteredAPIVersion(version string) bool { ...@@ -70,10 +84,10 @@ func IsRegisteredAPIVersion(version string) bool {
// GroupVersionsForGroup returns the registered versions of a group in the form // GroupVersionsForGroup returns the registered versions of a group in the form
// of "group/version". // of "group/version".
func GroupVersionsForGroup(group string) []string { func GroupVersionsForGroup(group string) []unversioned.GroupVersion {
ret := []string{} ret := []unversioned.GroupVersion{}
for _, v := range RegisteredVersions { for _, v := range RegisteredGroupVersions {
if apiutil.GetGroup(v) == group { if v.Group == group {
ret = append(ret, v) ret = append(ret, v)
} }
} }
......
...@@ -291,9 +291,9 @@ func FuzzerFor(t *testing.T, version string, src rand.Source) *fuzz.Fuzzer { ...@@ -291,9 +291,9 @@ func FuzzerFor(t *testing.T, version string, src rand.Source) *fuzz.Fuzzer {
ev.ValueFrom = &api.EnvVarSource{} ev.ValueFrom = &api.EnvVarSource{}
ev.ValueFrom.FieldRef = &api.ObjectFieldSelector{} ev.ValueFrom.FieldRef = &api.ObjectFieldSelector{}
versions := registered.RegisteredVersions versions := registered.RegisteredGroupVersions
ev.ValueFrom.FieldRef.APIVersion = versions[c.Rand.Intn(len(versions))] ev.ValueFrom.FieldRef.APIVersion = versions[c.Rand.Intn(len(versions))].String()
ev.ValueFrom.FieldRef.FieldPath = c.RandString() ev.ValueFrom.FieldRef.FieldPath = c.RandString()
} }
}, },
......
...@@ -30,6 +30,7 @@ type GroupVersionKind struct { ...@@ -30,6 +30,7 @@ type GroupVersionKind struct {
Kind string Kind string
} }
// TODO remove this
func NewGroupVersionKind(gv GroupVersion, kind string) GroupVersionKind { func NewGroupVersionKind(gv GroupVersion, kind string) GroupVersionKind {
return GroupVersionKind{Group: gv.Group, Version: gv.Version, Kind: kind} return GroupVersionKind{Group: gv.Group, Version: gv.Version, Kind: kind}
} }
...@@ -84,6 +85,10 @@ func ParseGroupVersionOrDie(gv string) GroupVersion { ...@@ -84,6 +85,10 @@ func ParseGroupVersionOrDie(gv string) GroupVersion {
return ret return ret
} }
func (gv GroupVersion) WithKind(kind string) GroupVersionKind {
return GroupVersionKind{Group: gv.Group, Version: gv.Version, Kind: kind}
}
// MarshalJSON implements the json.Marshaller interface. // MarshalJSON implements the json.Marshaller interface.
func (gv GroupVersion) MarshalJSON() ([]byte, error) { func (gv GroupVersion) MarshalJSON() ([]byte, error) {
s := gv.String() s := gv.String()
......
...@@ -28,7 +28,7 @@ var Codec = runtime.CodecFor(api.Scheme, "v1") ...@@ -28,7 +28,7 @@ var Codec = runtime.CodecFor(api.Scheme, "v1")
func init() { func init() {
// Check if v1 is in the list of supported API versions. // Check if v1 is in the list of supported API versions.
if !registered.IsRegisteredAPIVersion("v1") { if !registered.IsRegisteredAPIGroupVersion(unversioned.GroupVersion{Group: "", Version: "v1"}) {
return return
} }
......
...@@ -28,7 +28,7 @@ import ( ...@@ -28,7 +28,7 @@ import (
"k8s.io/kubernetes/pkg/api/latest" "k8s.io/kubernetes/pkg/api/latest"
"k8s.io/kubernetes/pkg/api/meta" "k8s.io/kubernetes/pkg/api/meta"
"k8s.io/kubernetes/pkg/api/registered" "k8s.io/kubernetes/pkg/api/registered"
apiutil "k8s.io/kubernetes/pkg/api/util" "k8s.io/kubernetes/pkg/api/unversioned"
_ "k8s.io/kubernetes/pkg/apis/componentconfig" _ "k8s.io/kubernetes/pkg/apis/componentconfig"
"k8s.io/kubernetes/pkg/apis/componentconfig/v1alpha1" "k8s.io/kubernetes/pkg/apis/componentconfig/v1alpha1"
"k8s.io/kubernetes/pkg/runtime" "k8s.io/kubernetes/pkg/runtime"
...@@ -45,19 +45,23 @@ func init() { ...@@ -45,19 +45,23 @@ func init() {
glog.V(4).Infof("%v", err) glog.V(4).Infof("%v", err)
return return
} }
worstToBestGroupVersions := []unversioned.GroupVersion{}
registeredGroupVersions := registered.GroupVersionsForGroup("componentconfig") registeredGroupVersions := registered.GroupVersionsForGroup("componentconfig")
groupVersion := registeredGroupVersions[0] groupVersion := registeredGroupVersions[0]
*groupMeta = latest.GroupMeta{ *groupMeta = latest.GroupMeta{
GroupVersion: groupVersion, GroupVersion: groupVersion.String(),
Group: apiutil.GetGroup(groupVersion), Group: groupVersion.Group,
Version: apiutil.GetVersion(groupVersion), Version: groupVersion.Version,
Codec: runtime.CodecFor(api.Scheme, groupVersion), Codec: runtime.CodecFor(api.Scheme, groupVersion.String()),
} }
var versions []string var versions []string
var groupVersions []string var groupVersions []string
for i := len(registeredGroupVersions) - 1; i >= 0; i-- { for i := len(registeredGroupVersions) - 1; i >= 0; i-- {
versions = append(versions, apiutil.GetVersion(registeredGroupVersions[i])) versions = append(versions, registeredGroupVersions[i].Version)
groupVersions = append(groupVersions, registeredGroupVersions[i]) groupVersions = append(groupVersions, registeredGroupVersions[i].String())
worstToBestGroupVersions = append(worstToBestGroupVersions, registeredGroupVersions[i])
} }
groupMeta.Versions = versions groupMeta.Versions = versions
groupMeta.GroupVersions = groupVersions groupMeta.GroupVersions = groupVersions
...@@ -70,7 +74,7 @@ func init() { ...@@ -70,7 +74,7 @@ func init() {
ignoredKinds := sets.NewString() ignoredKinds := sets.NewString()
groupMeta.RESTMapper = api.NewDefaultRESTMapper("componentconfig", groupVersions, interfacesFor, importPrefix, ignoredKinds, rootScoped) groupMeta.RESTMapper = api.NewDefaultRESTMapper(worstToBestGroupVersions, interfacesFor, importPrefix, ignoredKinds, rootScoped)
api.RegisterRESTMapper(groupMeta.RESTMapper) api.RegisterRESTMapper(groupMeta.RESTMapper)
groupMeta.InterfacesFor = interfacesFor groupMeta.InterfacesFor = interfacesFor
} }
......
...@@ -28,7 +28,7 @@ import ( ...@@ -28,7 +28,7 @@ import (
"k8s.io/kubernetes/pkg/api/latest" "k8s.io/kubernetes/pkg/api/latest"
"k8s.io/kubernetes/pkg/api/meta" "k8s.io/kubernetes/pkg/api/meta"
"k8s.io/kubernetes/pkg/api/registered" "k8s.io/kubernetes/pkg/api/registered"
apiutil "k8s.io/kubernetes/pkg/api/util" "k8s.io/kubernetes/pkg/api/unversioned"
_ "k8s.io/kubernetes/pkg/apis/extensions" _ "k8s.io/kubernetes/pkg/apis/extensions"
"k8s.io/kubernetes/pkg/apis/extensions/v1beta1" "k8s.io/kubernetes/pkg/apis/extensions/v1beta1"
"k8s.io/kubernetes/pkg/runtime" "k8s.io/kubernetes/pkg/runtime"
...@@ -45,19 +45,23 @@ func init() { ...@@ -45,19 +45,23 @@ func init() {
glog.V(4).Infof("%v", err) glog.V(4).Infof("%v", err)
return return
} }
worstToBestGroupVersions := []unversioned.GroupVersion{}
registeredGroupVersions := registered.GroupVersionsForGroup("extensions") registeredGroupVersions := registered.GroupVersionsForGroup("extensions")
groupVersion := registeredGroupVersions[0] groupVersion := registeredGroupVersions[0]
*groupMeta = latest.GroupMeta{ *groupMeta = latest.GroupMeta{
GroupVersion: groupVersion, GroupVersion: groupVersion.String(),
Group: apiutil.GetGroup(groupVersion), Group: groupVersion.Group,
Version: apiutil.GetVersion(groupVersion), Version: groupVersion.Version,
Codec: runtime.CodecFor(api.Scheme, groupVersion), Codec: runtime.CodecFor(api.Scheme, groupVersion.String()),
} }
var versions []string var versions []string
var groupVersions []string var groupVersions []string
for i := len(registeredGroupVersions) - 1; i >= 0; i-- { for i := len(registeredGroupVersions) - 1; i >= 0; i-- {
versions = append(versions, apiutil.GetVersion(registeredGroupVersions[i])) versions = append(versions, registeredGroupVersions[i].Version)
groupVersions = append(groupVersions, registeredGroupVersions[i]) groupVersions = append(groupVersions, registeredGroupVersions[i].String())
worstToBestGroupVersions = append(worstToBestGroupVersions, registeredGroupVersions[i])
} }
groupMeta.Versions = versions groupMeta.Versions = versions
groupMeta.GroupVersions = groupVersions groupMeta.GroupVersions = groupVersions
...@@ -70,7 +74,7 @@ func init() { ...@@ -70,7 +74,7 @@ func init() {
ignoredKinds := sets.NewString() ignoredKinds := sets.NewString()
groupMeta.RESTMapper = api.NewDefaultRESTMapper("extensions", groupVersions, interfacesFor, importPrefix, ignoredKinds, rootScoped) groupMeta.RESTMapper = api.NewDefaultRESTMapper(worstToBestGroupVersions, interfacesFor, importPrefix, ignoredKinds, rootScoped)
api.RegisterRESTMapper(groupMeta.RESTMapper) api.RegisterRESTMapper(groupMeta.RESTMapper)
groupMeta.InterfacesFor = interfacesFor groupMeta.InterfacesFor = interfacesFor
} }
......
...@@ -28,7 +28,7 @@ import ( ...@@ -28,7 +28,7 @@ import (
"k8s.io/kubernetes/pkg/api/latest" "k8s.io/kubernetes/pkg/api/latest"
"k8s.io/kubernetes/pkg/api/meta" "k8s.io/kubernetes/pkg/api/meta"
"k8s.io/kubernetes/pkg/api/registered" "k8s.io/kubernetes/pkg/api/registered"
apiutil "k8s.io/kubernetes/pkg/api/util" "k8s.io/kubernetes/pkg/api/unversioned"
_ "k8s.io/kubernetes/pkg/apis/metrics" _ "k8s.io/kubernetes/pkg/apis/metrics"
"k8s.io/kubernetes/pkg/apis/metrics/v1alpha1" "k8s.io/kubernetes/pkg/apis/metrics/v1alpha1"
"k8s.io/kubernetes/pkg/runtime" "k8s.io/kubernetes/pkg/runtime"
...@@ -45,19 +45,23 @@ func init() { ...@@ -45,19 +45,23 @@ func init() {
glog.V(4).Infof("%v", err) glog.V(4).Infof("%v", err)
return return
} }
worstToBestGroupVersions := []unversioned.GroupVersion{}
registeredGroupVersions := registered.GroupVersionsForGroup("metrics") registeredGroupVersions := registered.GroupVersionsForGroup("metrics")
groupVersion := registeredGroupVersions[0] groupVersion := registeredGroupVersions[0]
*groupMeta = latest.GroupMeta{ *groupMeta = latest.GroupMeta{
GroupVersion: groupVersion, GroupVersion: groupVersion.String(),
Group: apiutil.GetGroup(groupVersion), Group: groupVersion.Group,
Version: apiutil.GetVersion(groupVersion), Version: groupVersion.Version,
Codec: runtime.CodecFor(api.Scheme, groupVersion), Codec: runtime.CodecFor(api.Scheme, groupVersion.String()),
} }
var versions []string var versions []string
var groupVersions []string var groupVersions []string
for i := len(registeredGroupVersions) - 1; i >= 0; i-- { for i := len(registeredGroupVersions) - 1; i >= 0; i-- {
versions = append(versions, apiutil.GetVersion(registeredGroupVersions[i])) versions = append(versions, registeredGroupVersions[i].Version)
groupVersions = append(groupVersions, registeredGroupVersions[i]) groupVersions = append(groupVersions, registeredGroupVersions[i].String())
worstToBestGroupVersions = append(worstToBestGroupVersions, registeredGroupVersions[i])
} }
groupMeta.Versions = versions groupMeta.Versions = versions
groupMeta.GroupVersions = groupVersions groupMeta.GroupVersions = groupVersions
...@@ -70,7 +74,7 @@ func init() { ...@@ -70,7 +74,7 @@ func init() {
ignoredKinds := sets.NewString() ignoredKinds := sets.NewString()
groupMeta.RESTMapper = api.NewDefaultRESTMapper("metrics", groupVersions, interfacesFor, importPrefix, ignoredKinds, rootScoped) groupMeta.RESTMapper = api.NewDefaultRESTMapper(worstToBestGroupVersions, interfacesFor, importPrefix, ignoredKinds, rootScoped)
api.RegisterRESTMapper(groupMeta.RESTMapper) api.RegisterRESTMapper(groupMeta.RESTMapper)
groupMeta.InterfacesFor = interfacesFor groupMeta.InterfacesFor = interfacesFor
} }
......
...@@ -107,8 +107,7 @@ func interfacesFor(version string) (*meta.VersionInterfaces, error) { ...@@ -107,8 +107,7 @@ func interfacesFor(version string) (*meta.VersionInterfaces, error) {
} }
func newMapper() *meta.DefaultRESTMapper { func newMapper() *meta.DefaultRESTMapper {
gvStrings := []string{testGroupVersion.String(), newGroupVersion.String()} return meta.NewDefaultRESTMapper([]unversioned.GroupVersion{testGroupVersion, newGroupVersion}, interfacesFor)
return meta.NewDefaultRESTMapper(testAPIGroup, gvStrings, interfacesFor)
} }
func addGrouplessTypes() { func addGrouplessTypes() {
...@@ -149,11 +148,13 @@ func init() { ...@@ -149,11 +148,13 @@ func init() {
// the mapper how to address our resources // the mapper how to address our resources
for _, gv := range groupVersions { for _, gv := range groupVersions {
for kind := range api.Scheme.KnownTypes(gv.String()) { for kind := range api.Scheme.KnownTypes(gv.String()) {
gvk := gv.WithKind(kind)
root := bool(kind == "SimpleRoot") root := bool(kind == "SimpleRoot")
if root { if root {
nsMapper.Add(meta.RESTScopeRoot, kind, gv.String(), false) nsMapper.Add(gvk, meta.RESTScopeRoot, false)
} else { } else {
nsMapper.Add(meta.RESTScopeNamespace, kind, gv.String(), false) nsMapper.Add(gvk, meta.RESTScopeNamespace, false)
} }
} }
} }
......
...@@ -294,7 +294,11 @@ func (c *Fake) ServerAPIVersions() (*unversioned.APIVersions, error) { ...@@ -294,7 +294,11 @@ func (c *Fake) ServerAPIVersions() (*unversioned.APIVersions, error) {
action.Resource = "apiversions" action.Resource = "apiversions"
c.Invokes(action, nil) c.Invokes(action, nil)
return &unversioned.APIVersions{Versions: registered.RegisteredVersions}, nil gvStrings := []string{}
for _, gv := range registered.RegisteredGroupVersions {
gvStrings = append(gvStrings, gv.String())
}
return &unversioned.APIVersions{Versions: gvStrings}, nil
} }
func (c *Fake) ComponentStatuses() client.ComponentStatusInterface { func (c *Fake) ComponentStatuses() client.ComponentStatusInterface {
......
...@@ -90,18 +90,20 @@ func newExternalScheme() (*runtime.Scheme, meta.RESTMapper, runtime.Codec) { ...@@ -90,18 +90,20 @@ func newExternalScheme() (*runtime.Scheme, meta.RESTMapper, runtime.Codec) {
scheme.AddKnownTypeWithName(validVersionGV.String(), "Type", &ExternalType2{}) scheme.AddKnownTypeWithName(validVersionGV.String(), "Type", &ExternalType2{})
codec := runtime.CodecFor(scheme, unlikelyGV.String()) codec := runtime.CodecFor(scheme, unlikelyGV.String())
mapper := meta.NewDefaultRESTMapper("apitest", []string{unlikelyGV.String(), validVersionGV.String()}, func(version string) (*meta.VersionInterfaces, error) { mapper := meta.NewDefaultRESTMapper([]unversioned.GroupVersion{unlikelyGV, validVersionGV}, func(version string) (*meta.VersionInterfaces, error) {
return &meta.VersionInterfaces{ return &meta.VersionInterfaces{
Codec: runtime.CodecFor(scheme, version), Codec: runtime.CodecFor(scheme, version),
ObjectConvertor: scheme, ObjectConvertor: scheme,
MetadataAccessor: meta.NewAccessor(), MetadataAccessor: meta.NewAccessor(),
}, versionErrIfFalse(version == validVersionGV.String() || version == unlikelyGV.String()) }, versionErrIfFalse(version == validVersionGV.String() || version == unlikelyGV.String())
}) })
for _, version := range []string{unlikelyGV.String(), validVersionGV.String()} { for _, gv := range []unversioned.GroupVersion{unlikelyGV, validVersionGV} {
for kind := range scheme.KnownTypes(version) { for kind := range scheme.KnownTypes(gv.String()) {
gvk := gv.WithKind(kind)
mixedCase := false mixedCase := false
scope := meta.RESTScopeNamespace scope := meta.RESTScopeNamespace
mapper.Add(scope, kind, version, mixedCase) mapper.Add(gvk, scope, mixedCase)
} }
} }
......
...@@ -22,6 +22,7 @@ import ( ...@@ -22,6 +22,7 @@ import (
"k8s.io/kubernetes/pkg/api/latest" "k8s.io/kubernetes/pkg/api/latest"
"k8s.io/kubernetes/pkg/api/registered" "k8s.io/kubernetes/pkg/api/registered"
"k8s.io/kubernetes/pkg/api/unversioned"
"k8s.io/kubernetes/pkg/kubectl" "k8s.io/kubernetes/pkg/kubectl"
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
"k8s.io/kubernetes/pkg/kubectl/resource" "k8s.io/kubernetes/pkg/kubectl/resource"
...@@ -95,7 +96,11 @@ type ConvertOptions struct { ...@@ -95,7 +96,11 @@ type ConvertOptions struct {
// Complete collects information required to run Convert command from command line. // Complete collects information required to run Convert command from command line.
func (o *ConvertOptions) Complete(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []string) (err error) { func (o *ConvertOptions) Complete(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []string) (err error) {
o.outputVersion = cmdutil.OutputVersion(cmd, latest.GroupOrDie("").Version) o.outputVersion = cmdutil.OutputVersion(cmd, latest.GroupOrDie("").Version)
if !registered.IsRegisteredAPIVersion(o.outputVersion) { outputGV, err := unversioned.ParseGroupVersion(o.outputVersion)
if err != nil {
return fmt.Errorf("unable to parse group/version from %q: %v", o.outputVersion, err)
}
if !registered.IsRegisteredAPIGroupVersion(outputGV) {
cmdutil.UsageError(cmd, "'%s' is not a registered version.", o.outputVersion) cmdutil.UsageError(cmd, "'%s' is not a registered version.", o.outputVersion)
} }
......
...@@ -71,16 +71,8 @@ func (c *ClientCache) ClientConfigForVersion(version string) (*client.Config, er ...@@ -71,16 +71,8 @@ func (c *ClientCache) ClientConfigForVersion(version string) (*client.Config, er
} }
preferredGV = &gv preferredGV = &gv
} }
registeredGVs := []unversioned.GroupVersion{}
for _, gvString := range registered.RegisteredVersions {
gv, err := unversioned.ParseGroupVersion(gvString)
if err != nil {
return nil, err
}
registeredGVs = append(registeredGVs, gv)
}
negotiatedVersion, err := client.NegotiateVersion(c.defaultClient, &config, preferredGV, registeredGVs) negotiatedVersion, err := client.NegotiateVersion(c.defaultClient, &config, preferredGV, registered.RegisteredGroupVersions)
if err != nil { if err != nil {
return nil, err return nil, err
} }
......
...@@ -35,6 +35,7 @@ import ( ...@@ -35,6 +35,7 @@ import (
"k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/meta" "k8s.io/kubernetes/pkg/api/meta"
"k8s.io/kubernetes/pkg/api/registered" "k8s.io/kubernetes/pkg/api/registered"
"k8s.io/kubernetes/pkg/api/unversioned"
"k8s.io/kubernetes/pkg/api/validation" "k8s.io/kubernetes/pkg/api/validation"
"k8s.io/kubernetes/pkg/apis/extensions" "k8s.io/kubernetes/pkg/apis/extensions"
client "k8s.io/kubernetes/pkg/client/unversioned" client "k8s.io/kubernetes/pkg/client/unversioned"
...@@ -488,8 +489,12 @@ func (c *clientSwaggerSchema) ValidateBytes(data []byte) error { ...@@ -488,8 +489,12 @@ func (c *clientSwaggerSchema) ValidateBytes(data []byte) error {
if err != nil { if err != nil {
return err return err
} }
if ok := registered.IsRegisteredAPIVersion(version); !ok { gv, err := unversioned.ParseGroupVersion(version)
return fmt.Errorf("API version %q isn't supported, only supports API versions %q", version, registered.RegisteredVersions) if err != nil {
return fmt.Errorf("unable to parse group/version from %q: %v", version, err)
}
if ok := registered.IsRegisteredAPIGroupVersion(gv); !ok {
return fmt.Errorf("API version %q isn't supported, only supports API versions %q", version, registered.RegisteredGroupVersions)
} }
resource, _ := meta.KindToResource(kind, false) resource, _ := meta.KindToResource(kind, false)
group, err := c.mapper.GroupForResource(resource) group, err := c.mapper.GroupForResource(resource)
......
...@@ -23,6 +23,7 @@ import ( ...@@ -23,6 +23,7 @@ import (
"k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/meta" "k8s.io/kubernetes/pkg/api/meta"
"k8s.io/kubernetes/pkg/api/registered" "k8s.io/kubernetes/pkg/api/registered"
"k8s.io/kubernetes/pkg/api/unversioned"
"k8s.io/kubernetes/pkg/runtime" "k8s.io/kubernetes/pkg/runtime"
"k8s.io/kubernetes/pkg/util/yaml" "k8s.io/kubernetes/pkg/util/yaml"
) )
...@@ -48,8 +49,12 @@ func (m *Mapper) InfoForData(data []byte, source string) (*Info, error) { ...@@ -48,8 +49,12 @@ func (m *Mapper) InfoForData(data []byte, source string) (*Info, error) {
if err != nil { if err != nil {
return nil, fmt.Errorf("unable to get type info from %q: %v", source, err) return nil, fmt.Errorf("unable to get type info from %q: %v", source, err)
} }
if ok := registered.IsRegisteredAPIVersion(version); !ok { gv, err := unversioned.ParseGroupVersion(version)
return nil, fmt.Errorf("API version %q in %q isn't supported, only supports API versions %q", version, source, registered.RegisteredVersions) if err != nil {
return nil, fmt.Errorf("unable to parse group/version from %q: %v", version, err)
}
if ok := registered.IsRegisteredAPIGroupVersion(gv); !ok {
return nil, fmt.Errorf("API version %q in %q isn't supported, only supports API versions %q", version, source, registered.RegisteredGroupVersions)
} }
if kind == "" { if kind == "" {
return nil, fmt.Errorf("kind not set in %q", source) return nil, fmt.Errorf("kind not set in %q", source)
......
...@@ -71,8 +71,8 @@ func TestDecodeSinglePod(t *testing.T) { ...@@ -71,8 +71,8 @@ func TestDecodeSinglePod(t *testing.T) {
t.Errorf("expected:\n%#v\ngot:\n%#v\n%s", pod, podOut, string(json)) t.Errorf("expected:\n%#v\ngot:\n%#v\n%s", pod, podOut, string(json))
} }
for _, version := range registered.GroupVersionsForGroup("") { for _, gv := range registered.GroupVersionsForGroup("") {
externalPod, err := testapi.Default.Converter().ConvertToVersion(pod, version) externalPod, err := testapi.Default.Converter().ConvertToVersion(pod, gv.String())
if err != nil { if err != nil {
t.Errorf("unexpected error: %v", err) t.Errorf("unexpected error: %v", err)
} }
...@@ -137,8 +137,8 @@ func TestDecodePodList(t *testing.T) { ...@@ -137,8 +137,8 @@ func TestDecodePodList(t *testing.T) {
t.Errorf("expected:\n%#v\ngot:\n%#v\n%s", podList, &podListOut, string(json)) t.Errorf("expected:\n%#v\ngot:\n%#v\n%s", podList, &podListOut, string(json))
} }
for _, version := range registered.GroupVersionsForGroup("") { for _, gv := range registered.GroupVersionsForGroup("") {
externalPodList, err := testapi.Default.Converter().ConvertToVersion(podList, version) externalPodList, err := testapi.Default.Converter().ConvertToVersion(podList, gv.String())
if err != nil { if err != nil {
t.Errorf("unexpected error: %v", err) t.Errorf("unexpected error: %v", err)
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment