make shortcut expanding restmapper handle all

pull/6/head
deads2k 2016-09-15 08:52:42 -04:00
parent 4359c79f53
commit 771915c6c4
7 changed files with 159 additions and 97 deletions

View File

@ -86,9 +86,6 @@ func enableVersions(externalVersions []unversioned.GroupVersion) error {
return nil
}
// userResources is a group of resources mostly used by a kubectl user
var userResources = []string{"rc", "svc", "pods", "pvc"}
func newRESTMapper(externalVersions []unversioned.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
@ -115,8 +112,6 @@ func newRESTMapper(externalVersions []unversioned.GroupVersion) meta.RESTMapper
"ThirdPartyResourceList")
mapper := api.NewDefaultRESTMapper(externalVersions, interfacesFor, importPrefix, ignoredKinds, rootScoped)
// setup aliases for groups of resources
mapper.AddResourceAlias("all", userResources...)
return mapper
}

View File

@ -299,7 +299,7 @@ func NewAPIFactory() (*cmdutil.Factory, *testFactory, runtime.Codec, runtime.Neg
mapper := discovery.NewRESTMapper(groupResources, meta.InterfacesForUnstructured)
typer := discovery.NewUnstructuredObjectTyper(groupResources)
return kubectl.ShortcutExpander{RESTMapper: mapper}, typer, nil
return cmdutil.NewShortcutExpander(mapper), typer, nil
},
ClientSet: func() (*internalclientset.Clientset, error) {
// Swap out the HTTP client out of the client with the fake's version.

View File

@ -326,7 +326,7 @@ func NewFactory(optionalClientConfig clientcmd.ClientConfig) *Factory {
}
// wrap with shortcuts
mapper = kubectl.ShortcutExpander{RESTMapper: mapper}
mapper = NewShortcutExpander(mapper)
// wrap with output preferences
mapper = kubectl.OutputVersionMapper{RESTMapper: mapper, OutputVersions: []unversioned.GroupVersion{cmdApiVersion}}
return mapper, api.Scheme
@ -363,7 +363,7 @@ func NewFactory(optionalClientConfig clientcmd.ClientConfig) *Factory {
typer := discovery.NewUnstructuredObjectTyper(groupResources)
return kubectl.ShortcutExpander{RESTMapper: mapper}, typer, nil
return NewShortcutExpander(mapper), typer, nil
},
RESTClient: func() (*restclient.RESTClient, error) {
clientConfig, err := clients.ClientConfigForVersion(nil)

View File

@ -0,0 +1,89 @@
/*
Copyright 2016 The Kubernetes Authors.
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 util
import (
"k8s.io/kubernetes/pkg/api/meta"
"k8s.io/kubernetes/pkg/api/unversioned"
"k8s.io/kubernetes/pkg/kubectl"
)
// ShortcutExpander is a RESTMapper that can be used for OpenShift resources. It expands the resource first, then invokes the wrapped
type ShortcutExpander struct {
RESTMapper meta.RESTMapper
All []string
}
var _ meta.RESTMapper = &ShortcutExpander{}
func NewShortcutExpander(delegate meta.RESTMapper) ShortcutExpander {
return ShortcutExpander{All: userResources, RESTMapper: delegate}
}
func (e ShortcutExpander) KindFor(resource unversioned.GroupVersionResource) (unversioned.GroupVersionKind, error) {
return e.RESTMapper.KindFor(expandResourceShortcut(resource))
}
func (e ShortcutExpander) KindsFor(resource unversioned.GroupVersionResource) ([]unversioned.GroupVersionKind, error) {
return e.RESTMapper.KindsFor(expandResourceShortcut(resource))
}
func (e ShortcutExpander) ResourcesFor(resource unversioned.GroupVersionResource) ([]unversioned.GroupVersionResource, error) {
return e.RESTMapper.ResourcesFor(expandResourceShortcut(resource))
}
func (e ShortcutExpander) ResourceFor(resource unversioned.GroupVersionResource) (unversioned.GroupVersionResource, error) {
return e.RESTMapper.ResourceFor(expandResourceShortcut(resource))
}
func (e ShortcutExpander) ResourceSingularizer(resource string) (string, error) {
return e.RESTMapper.ResourceSingularizer(expandResourceShortcut(unversioned.GroupVersionResource{Resource: resource}).Resource)
}
func (e ShortcutExpander) RESTMapping(gk unversioned.GroupKind, versions ...string) (*meta.RESTMapping, error) {
return e.RESTMapper.RESTMapping(gk, versions...)
}
func (e ShortcutExpander) RESTMappings(gk unversioned.GroupKind) ([]*meta.RESTMapping, error) {
return e.RESTMapper.RESTMappings(gk)
}
// userResources are the resource names that apply to the primary, user facing resources used by
// client tools. They are in deletion-first order - dependent resources should be last.
var userResources = []string{"rc", "svc", "pods", "pvc"}
// AliasesForResource returns whether a resource has an alias or not
func (e ShortcutExpander) AliasesForResource(resource string) ([]string, bool) {
if resource == "all" {
return e.All, true
}
expanded := expandResourceShortcut(unversioned.GroupVersionResource{Resource: resource}).Resource
return []string{expanded}, (expanded != resource)
}
// expandResourceShortcut will return the expanded version of resource
// (something that a pkg/api/meta.RESTMapper can understand), if it is
// indeed a shortcut. Otherwise, will return resource unmodified.
func expandResourceShortcut(resource unversioned.GroupVersionResource) unversioned.GroupVersionResource {
if expanded, ok := kubectl.ShortForms[resource.Resource]; ok {
resource.Resource = expanded
return resource
}
return resource
}

View File

@ -0,0 +1,61 @@
/*
Copyright 2016 The Kubernetes Authors.
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 util
import (
"strings"
"testing"
"k8s.io/kubernetes/pkg/api/testapi"
)
func TestReplaceAliases(t *testing.T) {
tests := []struct {
name string
arg string
expected string
}{
{
name: "no-replacement",
arg: "service",
expected: "service",
},
{
name: "all-replacement",
arg: "all",
expected: "rc,svc,pods,pvc",
},
{
name: "alias-in-comma-separated-arg",
arg: "all,secrets",
expected: "rc,svc,pods,pvc,secrets",
},
}
mapper := NewShortcutExpander(testapi.Default.RESTMapper())
for _, test := range tests {
resources := []string{}
for _, arg := range strings.Split(test.arg, ",") {
curr, _ := mapper.AliasesForResource(arg)
resources = append(resources, curr...)
}
if strings.Join(resources, ",") != test.expected {
t.Errorf("%s: unexpected argument: expected %s, got %s", test.name, test.expected, resources)
}
}
}

View File

@ -97,48 +97,8 @@ func (m OutputVersionMapper) RESTMapping(gk unversioned.GroupKind, versions ...s
return m.RESTMapper.RESTMapping(gk, versions...)
}
// ShortcutExpander is a RESTMapper that can be used for Kubernetes
// resources. It expands the resource first, then invokes the wrapped RESTMapper
type ShortcutExpander struct {
RESTMapper meta.RESTMapper
}
var _ meta.RESTMapper = &ShortcutExpander{}
func (e ShortcutExpander) KindFor(resource unversioned.GroupVersionResource) (unversioned.GroupVersionKind, error) {
return e.RESTMapper.KindFor(expandResourceShortcut(resource))
}
func (e ShortcutExpander) KindsFor(resource unversioned.GroupVersionResource) ([]unversioned.GroupVersionKind, error) {
return e.RESTMapper.KindsFor(expandResourceShortcut(resource))
}
func (e ShortcutExpander) ResourcesFor(resource unversioned.GroupVersionResource) ([]unversioned.GroupVersionResource, error) {
return e.RESTMapper.ResourcesFor(expandResourceShortcut(resource))
}
func (e ShortcutExpander) ResourceFor(resource unversioned.GroupVersionResource) (unversioned.GroupVersionResource, error) {
return e.RESTMapper.ResourceFor(expandResourceShortcut(resource))
}
func (e ShortcutExpander) RESTMapping(gk unversioned.GroupKind, versions ...string) (*meta.RESTMapping, error) {
return e.RESTMapper.RESTMapping(gk, versions...)
}
func (e ShortcutExpander) RESTMappings(gk unversioned.GroupKind) ([]*meta.RESTMapping, error) {
return e.RESTMapper.RESTMappings(gk)
}
func (e ShortcutExpander) ResourceSingularizer(resource string) (string, error) {
return e.RESTMapper.ResourceSingularizer(expandResourceShortcut(unversioned.GroupVersionResource{Resource: resource}).Resource)
}
func (e ShortcutExpander) AliasesForResource(resource string) ([]string, bool) {
return e.RESTMapper.AliasesForResource(expandResourceShortcut(unversioned.GroupVersionResource{Resource: resource}).Resource)
}
// shortForms is the list of short names to their expanded names
var shortForms = map[string]string{
// ShortForms is the list of short names to their expanded names
var ShortForms = map[string]string{
// Please keep this alphabetized
// If you add an entry here, please also take a look at pkg/kubectl/cmd/cmd.go
// and add an entry to valid_resources when appropriate.
@ -165,30 +125,20 @@ var shortForms = map[string]string{
"svc": "services",
}
// Look-up for resource short forms by value
// ResourceShortFormFor looks up for a short form of resource names.
func ResourceShortFormFor(resource string) (string, bool) {
var alias string
exists := false
for k, val := range shortForms {
for k, val := range ShortForms {
if val == resource {
alias = k
exists = true
break
}
}
return alias, exists
}
// expandResourceShortcut will return the expanded version of resource
// (something that a pkg/api/meta.RESTMapper can understand), if it is
// indeed a shortcut. Otherwise, will return resource unmodified.
func expandResourceShortcut(resource unversioned.GroupVersionResource) unversioned.GroupVersionResource {
if expanded, ok := shortForms[resource.Resource]; ok {
// don't change the group or version that's already been specified
resource.Resource = expanded
}
return resource
}
// ResourceAliases returns the resource shortcuts and plural forms for the given resources.
func ResourceAliases(rs []string) []string {
as := make([]string, 0, len(rs))
@ -210,7 +160,7 @@ func ResourceAliases(rs []string) []string {
plurals[plural] = struct{}{}
}
for sf, r := range shortForms {
for sf, r := range ShortForms {
if _, found := plurals[r]; found {
as = append(as, sf)
}

View File

@ -1177,39 +1177,6 @@ func TestReceiveMultipleErrors(t *testing.T) {
}
}
func TestReplaceAliases(t *testing.T) {
tests := []struct {
name string
arg string
expected string
}{
{
name: "no-replacement",
arg: "service",
expected: "service",
},
{
name: "all-replacement",
arg: "all",
expected: "rc,svc,pods,pvc",
},
{
name: "alias-in-comma-separated-arg",
arg: "all,secrets",
expected: "rc,svc,pods,pvc,secrets",
},
}
b := NewBuilder(testapi.Default.RESTMapper(), api.Scheme, fakeClient(), testapi.Default.Codec())
for _, test := range tests {
replaced := b.replaceAliases(test.arg)
if replaced != test.expected {
t.Errorf("%s: unexpected argument: expected %s, got %s", test.name, test.expected, replaced)
}
}
}
func TestHasNames(t *testing.T) {
tests := []struct {
args []string