From 5c4fb5bcbe67828fbcea46e92bdcd732c1103e2d Mon Sep 17 00:00:00 2001 From: deads2k Date: Mon, 16 Nov 2015 15:14:27 -0500 Subject: [PATCH] make RESTMapper.KindFor --- pkg/api/meta/interfaces.go | 7 ++-- pkg/api/meta/restmapper.go | 35 +++++-------------- pkg/client/unversioned/testclient/fixture.go | 7 +--- pkg/kubectl/cmd/explain.go | 4 +-- pkg/kubectl/cmd/util/factory.go | 12 +++---- pkg/kubectl/kubectl.go | 10 +++--- pkg/kubectl/resource/builder.go | 8 ++--- pkg/registry/thirdpartyresourcedata/codec.go | 15 +++----- .../namespace/autoprovision/admission.go | 4 +-- .../admission/namespace/exists/admission.go | 4 +-- .../namespace/lifecycle/admission.go | 4 +-- 11 files changed, 41 insertions(+), 69 deletions(-) diff --git a/pkg/api/meta/interfaces.go b/pkg/api/meta/interfaces.go index 0d12114d6b8..0606e0b861e 100644 --- a/pkg/api/meta/interfaces.go +++ b/pkg/api/meta/interfaces.go @@ -147,10 +147,9 @@ type RESTMapping struct { // TODO(caesarxuchao): Add proper multi-group support so that kinds & resources are // scoped to groups. See http://issues.k8s.io/12413 and http://issues.k8s.io/10009. type RESTMapper interface { - VersionAndKindForResource(resource string) (defaultVersion, kind string, err error) - // TODO(caesarxuchao): Remove GroupForResource when multi-group support is in (since - // group will be part of the version). - GroupForResource(resource string) (string, error) + // KindFor takes a resource and returns back the unambiguous Kind (GroupVersionKind) + KindFor(resource string) (unversioned.GroupVersionKind, error) + RESTMapping(kind string, versions ...string) (*RESTMapping, error) AliasesForResource(resource string) ([]string, bool) ResourceSingularizer(resource string) (singular string, err error) diff --git a/pkg/api/meta/restmapper.go b/pkg/api/meta/restmapper.go index 7beadbb773d..eac83250167 100644 --- a/pkg/api/meta/restmapper.go +++ b/pkg/api/meta/restmapper.go @@ -80,6 +80,8 @@ type DefaultRESTMapper struct { interfacesFunc VersionInterfacesFunc } +var _ RESTMapper = &DefaultRESTMapper{} + // VersionInterfacesFunc returns the appropriate codec, typer, and metadata accessor for a // given api version, or an error if no such api version exists. type VersionInterfacesFunc func(apiVersion string) (*VersionInterfaces, error) @@ -163,21 +165,12 @@ func (m *DefaultRESTMapper) ResourceSingularizer(resource string) (singular stri } // VersionAndKindForResource implements RESTMapper -func (m *DefaultRESTMapper) VersionAndKindForResource(resource string) (gvString, kind string, err error) { +func (m *DefaultRESTMapper) KindFor(resource string) (unversioned.GroupVersionKind, error) { gvk, ok := m.resourceToKind[strings.ToLower(resource)] if !ok { - return "", "", fmt.Errorf("in version and kind for resource, no resource %q has been defined", resource) + return gvk, fmt.Errorf("in version and kind for resource, no resource %q has been defined", resource) } - return gvk.GroupVersion().String(), gvk.Kind, nil -} - -func (m *DefaultRESTMapper) GroupForResource(resource string) (string, error) { - gvk, exists := m.resourceToKind[strings.ToLower(resource)] - if !exists { - return "", fmt.Errorf("in group for resource, no resource %q has been defined", resource) - } - - return gvk.Group, nil + return gvk, nil } // RESTMapping returns a struct representing the resource path and conversion interfaces a @@ -295,7 +288,7 @@ func (m *DefaultRESTMapper) AliasesForResource(alias string) ([]string, bool) { // ResourceIsValid takes a string (kind) and checks if it's a valid resource func (m *DefaultRESTMapper) ResourceIsValid(resource string) bool { - _, _, err := m.VersionAndKindForResource(resource) + _, err := m.KindFor(resource) return err == nil } @@ -317,21 +310,9 @@ func (m MultiRESTMapper) ResourceSingularizer(resource string) (singular string, // VersionAndKindForResource provides the Version and Kind mappings for the // REST resources. This implementation supports multiple REST schemas and return // the first match. -func (m MultiRESTMapper) VersionAndKindForResource(resource string) (defaultVersion, kind string, err error) { +func (m MultiRESTMapper) KindFor(resource string) (gvk unversioned.GroupVersionKind, err error) { for _, t := range m { - defaultVersion, kind, err = t.VersionAndKindForResource(resource) - if err == nil { - return - } - } - return -} - -// GroupForResource provides the Group mappings for the REST resources. This -// implementation supports multiple REST schemas and returns the first match. -func (m MultiRESTMapper) GroupForResource(resource string) (group string, err error) { - for _, t := range m { - group, err = t.GroupForResource(resource) + gvk, err = t.KindFor(resource) if err == nil { return } diff --git a/pkg/client/unversioned/testclient/fixture.go b/pkg/client/unversioned/testclient/fixture.go index 1a4e008a680..4f7a62e0bdb 100644 --- a/pkg/client/unversioned/testclient/fixture.go +++ b/pkg/client/unversioned/testclient/fixture.go @@ -59,15 +59,10 @@ type ObjectScheme interface { func ObjectReaction(o ObjectRetriever, mapper meta.RESTMapper) ReactionFunc { return func(action Action) (bool, runtime.Object, error) { - gvString, kind, err := mapper.VersionAndKindForResource(action.GetResource()) + gvk, err := mapper.KindFor(action.GetResource()) if err != nil { return false, nil, fmt.Errorf("unrecognized action %s: %v", action.GetResource(), err) } - gv, err := unversioned.ParseGroupVersion(gvString) - if err != nil { - return false, nil, err - } - gvk := gv.WithKind(kind) // TODO: have mapper return a Kind for a subresource? switch castAction := action.(type) { diff --git a/pkg/kubectl/cmd/explain.go b/pkg/kubectl/cmd/explain.go index 4b4a0a8c0dd..8eb4f021223 100644 --- a/pkg/kubectl/cmd/explain.go +++ b/pkg/kubectl/cmd/explain.go @@ -82,13 +82,13 @@ func RunExplain(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []st } // TODO: We should deduce the group for a resource by discovering the supported resources at server. - group, err := mapper.GroupForResource(inModel) + gvk, err := mapper.KindFor(inModel) if err != nil { return err } if len(apiV) == 0 { - groupMeta, err := latest.Group(group) + groupMeta, err := latest.Group(gvk.Group) if err != nil { return err } diff --git a/pkg/kubectl/cmd/util/factory.go b/pkg/kubectl/cmd/util/factory.go index 47df35c20a4..4e73ee79d53 100644 --- a/pkg/kubectl/cmd/util/factory.go +++ b/pkg/kubectl/cmd/util/factory.go @@ -151,7 +151,7 @@ func NewFactory(optionalClientConfig clientcmd.ClientConfig) *Factory { return clients.ClientConfigForVersion("") }, RESTClient: func(mapping *meta.RESTMapping) (resource.RESTClient, error) { - group, err := api.RESTMapper.GroupForResource(mapping.Resource) + gvk, err := api.RESTMapper.KindFor(mapping.Resource) if err != nil { return nil, err } @@ -159,7 +159,7 @@ func NewFactory(optionalClientConfig clientcmd.ClientConfig) *Factory { if err != nil { return nil, err } - switch group { + switch gvk.Group { case "": return client.RESTClient, nil case "extensions": @@ -168,7 +168,7 @@ func NewFactory(optionalClientConfig clientcmd.ClientConfig) *Factory { return nil, fmt.Errorf("unable to get RESTClient for resource '%s'", mapping.Resource) }, Describer: func(mapping *meta.RESTMapping) (kubectl.Describer, error) { - group, err := api.RESTMapper.GroupForResource(mapping.Resource) + gvk, err := api.RESTMapper.KindFor(mapping.Resource) if err != nil { return nil, err } @@ -176,7 +176,7 @@ func NewFactory(optionalClientConfig clientcmd.ClientConfig) *Factory { if err != nil { return nil, err } - if describer, ok := kubectl.DescriberFor(group, mapping.GroupVersionKind.Kind, client); ok { + if describer, ok := kubectl.DescriberFor(gvk.Group, mapping.GroupVersionKind.Kind, client); ok { return describer, nil } return nil, fmt.Errorf("no description has been implemented for %q", mapping.Kind) @@ -497,11 +497,11 @@ func (c *clientSwaggerSchema) ValidateBytes(data []byte) error { return fmt.Errorf("API version %q isn't supported, only supports API versions %q", version, registered.RegisteredGroupVersions) } resource, _ := meta.KindToResource(kind, false) - group, err := c.mapper.GroupForResource(resource) + gvk, err := c.mapper.KindFor(resource) if err != nil { return fmt.Errorf("could not find api group for %s: %v", kind, err) } - if group == "extensions" { + if gvk.Group == "extensions" { if c.c.ExtensionsClient == nil { return errors.New("unable to validate: no experimental client") } diff --git a/pkg/kubectl/kubectl.go b/pkg/kubectl/kubectl.go index 0cfe6e0dabe..a17a2dd8424 100644 --- a/pkg/kubectl/kubectl.go +++ b/pkg/kubectl/kubectl.go @@ -22,6 +22,7 @@ import ( "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/meta" + "k8s.io/kubernetes/pkg/api/unversioned" ) const kubectlAnnotationPrefix = "kubectl.kubernetes.io/" @@ -65,12 +66,13 @@ type ShortcutExpander struct { meta.RESTMapper } -// VersionAndKindForResource implements meta.RESTMapper. It expands the resource first, then invokes the wrapped +var _ meta.RESTMapper = &ShortcutExpander{} + +// KindFor implements meta.RESTMapper. It expands the resource first, then invokes the wrapped // mapper. -func (e ShortcutExpander) VersionAndKindForResource(resource string) (defaultVersion, kind string, err error) { +func (e ShortcutExpander) KindFor(resource string) (unversioned.GroupVersionKind, error) { resource = expandResourceShortcut(resource) - defaultVersion, kind, err = e.RESTMapper.VersionAndKindForResource(resource) - return defaultVersion, kind, err + return e.RESTMapper.KindFor(resource) } // ResourceIsValid takes a string (kind) and checks if it's a valid resource. diff --git a/pkg/kubectl/resource/builder.go b/pkg/kubectl/resource/builder.go index d4574ec1ddb..c874db9fcf6 100644 --- a/pkg/kubectl/resource/builder.go +++ b/pkg/kubectl/resource/builder.go @@ -426,11 +426,11 @@ func (b *Builder) resourceMappings() ([]*meta.RESTMapping, error) { } mappings := []*meta.RESTMapping{} for _, r := range b.resources { - version, kind, err := b.mapper.VersionAndKindForResource(r) + gvk, err := b.mapper.KindFor(r) if err != nil { return nil, err } - mapping, err := b.mapper.RESTMapping(kind, version) + mapping, err := b.mapper.RESTMapping(gvk.Kind, gvk.GroupVersion().String()) if err != nil { return nil, err } @@ -446,11 +446,11 @@ func (b *Builder) resourceTupleMappings() (map[string]*meta.RESTMapping, error) if _, ok := mappings[r.Resource]; ok { continue } - version, kind, err := b.mapper.VersionAndKindForResource(r.Resource) + gvk, err := b.mapper.KindFor(r.Resource) if err != nil { return nil, err } - mapping, err := b.mapper.RESTMapping(kind, version) + mapping, err := b.mapper.RESTMapping(gvk.Kind, gvk.GroupVersion().String()) if err != nil { return nil, err } diff --git a/pkg/registry/thirdpartyresourcedata/codec.go b/pkg/registry/thirdpartyresourcedata/codec.go index a9de614aae3..30d9ca30d84 100644 --- a/pkg/registry/thirdpartyresourcedata/codec.go +++ b/pkg/registry/thirdpartyresourcedata/codec.go @@ -39,15 +39,17 @@ type thirdPartyResourceDataMapper struct { group string } +var _ meta.RESTMapper = &thirdPartyResourceDataMapper{} + func (t *thirdPartyResourceDataMapper) isThirdPartyResource(resource string) bool { return resource == strings.ToLower(t.kind)+"s" } -func (t *thirdPartyResourceDataMapper) GroupForResource(resource string) (string, error) { +func (t *thirdPartyResourceDataMapper) KindFor(resource string) (unversioned.GroupVersionKind, error) { if t.isThirdPartyResource(resource) { - return t.group, nil + return unversioned.GroupVersionKind{Group: t.group, Version: t.version, Kind: t.kind}, nil } - return t.mapper.GroupForResource(resource) + return t.mapper.KindFor(resource) } func (t *thirdPartyResourceDataMapper) RESTMapping(kind string, groupVersions ...string) (*meta.RESTMapping, error) { @@ -76,13 +78,6 @@ func (t *thirdPartyResourceDataMapper) ResourceSingularizer(resource string) (si return t.mapper.ResourceSingularizer(resource) } -func (t *thirdPartyResourceDataMapper) VersionAndKindForResource(resource string) (defaultVersion, kind string, err error) { - if t.isThirdPartyResource(resource) { - return t.version, t.kind, nil - } - return t.mapper.VersionAndKindForResource(resource) -} - // ResourceIsValid takes a string (kind) and checks if it's a valid resource func (t *thirdPartyResourceDataMapper) ResourceIsValid(resource string) bool { return t.isThirdPartyResource(resource) || t.mapper.ResourceIsValid(resource) diff --git a/plugin/pkg/admission/namespace/autoprovision/admission.go b/plugin/pkg/admission/namespace/autoprovision/admission.go index 85940a8cef0..d9bf9da055a 100644 --- a/plugin/pkg/admission/namespace/autoprovision/admission.go +++ b/plugin/pkg/admission/namespace/autoprovision/admission.go @@ -48,11 +48,11 @@ type provision struct { } func (p *provision) Admit(a admission.Attributes) (err error) { - defaultVersion, kind, err := api.RESTMapper.VersionAndKindForResource(a.GetResource()) + gvk, err := api.RESTMapper.KindFor(a.GetResource()) if err != nil { return admission.NewForbidden(a, err) } - mapping, err := api.RESTMapper.RESTMapping(kind, defaultVersion) + mapping, err := api.RESTMapper.RESTMapping(gvk.Kind, gvk.GroupVersion().String()) if err != nil { return admission.NewForbidden(a, err) } diff --git a/plugin/pkg/admission/namespace/exists/admission.go b/plugin/pkg/admission/namespace/exists/admission.go index b0c194f362c..6606ec40839 100644 --- a/plugin/pkg/admission/namespace/exists/admission.go +++ b/plugin/pkg/admission/namespace/exists/admission.go @@ -49,11 +49,11 @@ type exists struct { } func (e *exists) Admit(a admission.Attributes) (err error) { - defaultVersion, kind, err := api.RESTMapper.VersionAndKindForResource(a.GetResource()) + gvk, err := api.RESTMapper.KindFor(a.GetResource()) if err != nil { return errors.NewInternalError(err) } - mapping, err := api.RESTMapper.RESTMapping(kind, defaultVersion) + mapping, err := api.RESTMapper.RESTMapping(gvk.Kind, gvk.GroupVersion().String()) if err != nil { return errors.NewInternalError(err) } diff --git a/plugin/pkg/admission/namespace/lifecycle/admission.go b/plugin/pkg/admission/namespace/lifecycle/admission.go index 798360d5886..2baf41e03d6 100644 --- a/plugin/pkg/admission/namespace/lifecycle/admission.go +++ b/plugin/pkg/admission/namespace/lifecycle/admission.go @@ -57,11 +57,11 @@ func (l *lifecycle) Admit(a admission.Attributes) (err error) { return errors.NewForbidden(a.GetKind(), a.GetName(), fmt.Errorf("this namespace may not be deleted")) } - defaultVersion, kind, err := api.RESTMapper.VersionAndKindForResource(a.GetResource()) + gvk, err := api.RESTMapper.KindFor(a.GetResource()) if err != nil { return errors.NewInternalError(err) } - mapping, err := api.RESTMapper.RESTMapping(kind, defaultVersion) + mapping, err := api.RESTMapper.RESTMapping(gvk.Kind, gvk.GroupVersion().String()) if err != nil { return errors.NewInternalError(err) }