Merge pull request #63602 from deads2k/cli-54-categories

Automatic merge from submit-queue (batch tested with PRs 59284, 63602). If you want to cherry-pick this change to another branch, please follow the instructions <a href="https://github.com/kubernetes/community/blob/master/contributors/devel/cherry-picks.md">here</a>.

 category expansion can only come from the server

A couple release ago we moved category expansion to the server instead of hardcoding it in the client.  Similar to restmappings, there is no valid client-side expansion anymore, so this removes the code that hardcoded the list and moves the category expansion to the same package as our discovery based restmappers.

@kubernetes/sig-cli-maintainers 

```release-note
NONE
```
pull/8/head
Kubernetes Submit Queue 2018-05-09 13:51:13 -07:00 committed by GitHub
commit ca92b73a65
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 96 additions and 219 deletions

View File

@ -134,7 +134,6 @@ pkg/kubeapiserver/authorizer/modes
pkg/kubeapiserver/options
pkg/kubeapiserver/server
pkg/kubectl
pkg/kubectl/categories
pkg/kubectl/cmd
pkg/kubectl/cmd/auth
pkg/kubectl/cmd/config

View File

@ -200,7 +200,6 @@ filegroup(
":package-srcs",
"//pkg/kubectl/apply:all-srcs",
"//pkg/kubectl/apps:all-srcs",
"//pkg/kubectl/categories:all-srcs",
"//pkg/kubectl/cmd:all-srcs",
"//pkg/kubectl/explain:all-srcs",
"//pkg/kubectl/genericclioptions:all-srcs",

View File

@ -1,41 +0,0 @@
load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
go_library(
name = "go_default_library",
srcs = ["categories.go"],
importpath = "k8s.io/kubernetes/pkg/kubectl/categories",
visibility = ["//visibility:public"],
deps = [
"//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
"//vendor/k8s.io/client-go/discovery:go_default_library",
],
)
go_test(
name = "go_default_test",
srcs = ["categories_test.go"],
embed = [":go_default_library"],
deps = [
"//vendor/github.com/googleapis/gnostic/OpenAPIv2:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/version:go_default_library",
"//vendor/k8s.io/client-go/discovery:go_default_library",
"//vendor/k8s.io/client-go/rest:go_default_library",
"//vendor/k8s.io/client-go/rest/fake:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@ -13,7 +13,6 @@ go_library(
"//pkg/apis/core:go_default_library",
"//pkg/client/clientset_generated/internalclientset:go_default_library",
"//pkg/kubectl:go_default_library",
"//pkg/kubectl/categories:go_default_library",
"//pkg/kubectl/cmd/util:go_default_library",
"//pkg/kubectl/cmd/util/openapi:go_default_library",
"//pkg/kubectl/cmd/util/openapi/testing:go_default_library",

View File

@ -47,7 +47,6 @@ import (
api "k8s.io/kubernetes/pkg/apis/core"
"k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
"k8s.io/kubernetes/pkg/kubectl"
"k8s.io/kubernetes/pkg/kubectl/categories"
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
"k8s.io/kubernetes/pkg/kubectl/cmd/util/openapi"
openapitesting "k8s.io/kubernetes/pkg/kubectl/cmd/util/openapi/testing"
@ -287,8 +286,8 @@ func (f *TestFactory) Cleanup() {
os.Remove(f.tempConfigFile.Name())
}
func (f *TestFactory) CategoryExpander() categories.CategoryExpander {
return categories.LegacyCategoryExpander
func (f *TestFactory) CategoryExpander() (restmapper.CategoryExpander, error) {
return resource.FakeCategoryExpander, nil
}
func (f *TestFactory) ClientConfig() (*restclient.Config, error) {
@ -335,6 +334,7 @@ func (f *TestFactory) Command(*cobra.Command, bool) string {
func (f *TestFactory) NewBuilder() *resource.Builder {
mapper, err := f.RESTMapper()
categoryExpander, err2 := f.CategoryExpander()
return resource.NewFakeBuilder(
func(version schema.GroupVersion) (resource.RESTClient, error) {
@ -347,8 +347,8 @@ func (f *TestFactory) NewBuilder() *resource.Builder {
return f.Client, nil
},
mapper,
f.CategoryExpander(),
).AddError(err)
categoryExpander,
).AddError(err).AddError(err2)
}
func (f *TestFactory) KubernetesClientSet() (*kubernetes.Clientset, error) {

View File

@ -26,7 +26,6 @@ go_library(
"//pkg/client/clientset_generated/internalclientset/typed/core/internalversion:go_default_library",
"//pkg/controller:go_default_library",
"//pkg/kubectl:go_default_library",
"//pkg/kubectl/categories:go_default_library",
"//pkg/kubectl/cmd/templates:go_default_library",
"//pkg/kubectl/cmd/util/openapi:go_default_library",
"//pkg/kubectl/cmd/util/openapi/validation:go_default_library",
@ -97,7 +96,6 @@ go_test(
"//pkg/client/clientset_generated/internalclientset/fake:go_default_library",
"//pkg/controller:go_default_library",
"//pkg/kubectl:go_default_library",
"//pkg/kubectl/categories:go_default_library",
"//pkg/kubectl/resource:go_default_library",
"//vendor/github.com/googleapis/gnostic/OpenAPIv2:go_default_library",
"//vendor/github.com/stretchr/testify/assert:go_default_library",

View File

@ -36,13 +36,13 @@ import (
"k8s.io/client-go/dynamic"
"k8s.io/client-go/kubernetes"
restclient "k8s.io/client-go/rest"
"k8s.io/client-go/restmapper"
scaleclient "k8s.io/client-go/scale"
api "k8s.io/kubernetes/pkg/apis/core"
apiv1 "k8s.io/kubernetes/pkg/apis/core/v1"
"k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
coreclient "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/core/internalversion"
"k8s.io/kubernetes/pkg/kubectl"
"k8s.io/kubernetes/pkg/kubectl/categories"
"k8s.io/kubernetes/pkg/kubectl/cmd/util/openapi"
"k8s.io/kubernetes/pkg/kubectl/plugins"
"k8s.io/kubernetes/pkg/kubectl/resource"
@ -169,7 +169,7 @@ type ClientAccessFactory interface {
// Generally they provide object typing and functions that build requests based on the negotiated clients.
type ObjectMappingFactory interface {
// Returns interface for expanding categories like `all`.
CategoryExpander() categories.CategoryExpander
CategoryExpander() (restmapper.CategoryExpander, error)
// Returns a RESTClient for working with the specified RESTMapping or an error. This is intended
// for working with arbitrary resources and is not guaranteed to point to a Kubernetes APIServer.
ClientForMapping(mapping *meta.RESTMapping) (resource.RESTClient, error)

View File

@ -46,13 +46,15 @@ func NewBuilderFactory(clientAccessFactory ClientAccessFactory, objectMappingFac
// NewBuilder returns a new resource builder for structured api objects.
func (f *ring2Factory) NewBuilder() *resource.Builder {
mapper, mapperErr := f.clientAccessFactory.RESTMapper()
categoryExpander, categoryExpanderError := f.objectMappingFactory.CategoryExpander()
categoryExpander := f.objectMappingFactory.CategoryExpander()
return resource.NewBuilder(
f.clientAccessFactory.ClientConfig,
mapper,
categoryExpander,
).AddError(mapperErr)
).
AddError(mapperErr).
AddError(categoryExpanderError)
}
// PluginLoader loads plugins from a path set by the KUBECTL_PLUGINS_PATH env var.

View File

@ -40,6 +40,7 @@ import (
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/client-go/dynamic"
restclient "k8s.io/client-go/rest"
"k8s.io/client-go/restmapper"
"k8s.io/kubernetes/pkg/apis/apps"
"k8s.io/kubernetes/pkg/apis/batch"
api "k8s.io/kubernetes/pkg/apis/core"
@ -47,7 +48,6 @@ import (
"k8s.io/kubernetes/pkg/apis/extensions"
"k8s.io/kubernetes/pkg/controller"
"k8s.io/kubernetes/pkg/kubectl"
"k8s.io/kubernetes/pkg/kubectl/categories"
"k8s.io/kubernetes/pkg/kubectl/cmd/util/openapi"
openapivalidation "k8s.io/kubernetes/pkg/kubectl/cmd/util/openapi/validation"
"k8s.io/kubernetes/pkg/kubectl/resource"
@ -75,23 +75,13 @@ func NewObjectMappingFactory(clientAccessFactory ClientAccessFactory) ObjectMapp
return f
}
func (f *ring1Factory) CategoryExpander() categories.CategoryExpander {
legacyExpander := categories.LegacyCategoryExpander
func (f *ring1Factory) CategoryExpander() (restmapper.CategoryExpander, error) {
discoveryClient, err := f.clientAccessFactory.DiscoveryClient()
if err == nil {
// fallback is the legacy expander wrapped with discovery based filtering
fallbackExpander, err := categories.NewDiscoveryFilteredExpander(legacyExpander, discoveryClient)
CheckErr(err)
// by default use the expander that discovers based on "categories" field from the API
discoveryCategoryExpander, err := categories.NewDiscoveryCategoryExpander(fallbackExpander, discoveryClient)
CheckErr(err)
return discoveryCategoryExpander
if err != nil {
return nil, err
}
return legacyExpander
return restmapper.NewDiscoveryCategoryExpander(discoveryClient)
}
func (f *ring1Factory) ClientForMapping(mapping *meta.RESTMapping) (resource.RESTClient, error) {

View File

@ -40,7 +40,6 @@ import (
"k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/fake"
"k8s.io/kubernetes/pkg/controller"
"k8s.io/kubernetes/pkg/kubectl"
"k8s.io/kubernetes/pkg/kubectl/categories"
"k8s.io/kubernetes/pkg/kubectl/resource"
)
@ -472,7 +471,7 @@ func TestDiscoveryReplaceAliases(t *testing.T) {
ds := &fakeDiscoveryClient{}
mapper := restmapper.NewShortcutExpander(testrestmapper.TestOnlyStaticRESTMapper(legacyscheme.Scheme), ds)
b := resource.NewFakeBuilder(fakeClient(), mapper, categories.LegacyCategoryExpander)
b := resource.NewFakeBuilder(fakeClient(), mapper, resource.FakeCategoryExpander)
for _, test := range tests {
replaced := b.ReplaceAliases(test.arg)

View File

@ -10,6 +10,7 @@ go_library(
"builder.go",
"client.go",
"doc.go",
"fake.go",
"helper.go",
"interfaces.go",
"mapper.go",
@ -22,7 +23,6 @@ go_library(
"//build/visible_to:pkg_kubectl_resource_CONSUMERS",
],
deps = [
"//pkg/kubectl/categories:go_default_library",
"//pkg/kubectl/validation:go_default_library",
"//vendor/golang.org/x/text/encoding/unicode:go_default_library",
"//vendor/golang.org/x/text/transform:go_default_library",
@ -44,6 +44,7 @@ go_library(
"//vendor/k8s.io/apimachinery/pkg/watch:go_default_library",
"//vendor/k8s.io/client-go/dynamic:go_default_library",
"//vendor/k8s.io/client-go/rest:go_default_library",
"//vendor/k8s.io/client-go/restmapper:go_default_library",
],
)
@ -61,7 +62,6 @@ go_test(
embed = [":go_default_library"],
deps = [
"//pkg/apis/core/install:go_default_library",
"//pkg/kubectl/categories:go_default_library",
"//pkg/kubectl/scheme:go_default_library",
"//vendor/github.com/davecgh/go-spew/spew:go_default_library",
"//vendor/github.com/ghodss/yaml:go_default_library",

View File

@ -34,7 +34,7 @@ import (
"k8s.io/apimachinery/pkg/runtime/serializer"
utilerrors "k8s.io/apimachinery/pkg/util/errors"
"k8s.io/apimachinery/pkg/util/sets"
"k8s.io/kubernetes/pkg/kubectl/categories"
"k8s.io/client-go/restmapper"
"k8s.io/kubernetes/pkg/kubectl/validation"
)
@ -47,7 +47,7 @@ const defaultHttpGetAttempts int = 3
// from the command line and converting them to a list of resources to iterate
// over using the Visitor interface.
type Builder struct {
categoryExpander categories.CategoryExpander
categoryExpander restmapper.CategoryExpander
// mapper is set explicitly by resource builders
mapper *mapper
@ -143,7 +143,7 @@ type resourceTuple struct {
type FakeClientFunc func(version schema.GroupVersion) (RESTClient, error)
func NewFakeBuilder(fakeClientFn FakeClientFunc, restMapper meta.RESTMapper, categoryExpander categories.CategoryExpander) *Builder {
func NewFakeBuilder(fakeClientFn FakeClientFunc, restMapper meta.RESTMapper, categoryExpander restmapper.CategoryExpander) *Builder {
ret := NewBuilder(nil, restMapper, categoryExpander)
ret.fakeClientFn = fakeClientFn
return ret
@ -153,7 +153,7 @@ func NewFakeBuilder(fakeClientFn FakeClientFunc, restMapper meta.RESTMapper, cat
// internal or unstructured must be specified.
// TODO: Add versioned client (although versioned is still lossy)
// TODO remove internal and unstructured mapper and instead have them set the negotiated serializer for use in the client
func NewBuilder(clientConfigFn ClientConfigFunc, restMapper meta.RESTMapper, categoryExpander categories.CategoryExpander) *Builder {
func NewBuilder(clientConfigFn ClientConfigFunc, restMapper meta.RESTMapper, categoryExpander restmapper.CategoryExpander) *Builder {
return &Builder{
clientConfigFn: clientConfigFn,
restMapper: restMapper,
@ -543,6 +543,9 @@ func (b *Builder) ResourceTypeOrNameArgs(allowEmptySelector bool, args ...string
func (b *Builder) ReplaceAliases(input string) string {
replaced := []string{}
for _, arg := range strings.Split(input, ",") {
if b.categoryExpander == nil {
continue
}
if resources, ok := b.categoryExpander.Expand(arg); ok {
asStrings := []string{}
for _, resource := range resources {

View File

@ -47,7 +47,6 @@ import (
"k8s.io/client-go/rest/fake"
restclientwatch "k8s.io/client-go/rest/watch"
utiltesting "k8s.io/client-go/util/testing"
"k8s.io/kubernetes/pkg/kubectl/categories"
"k8s.io/kubernetes/pkg/kubectl/scheme"
// install the pod scheme into the legacy scheme for test typer resolution
@ -59,7 +58,6 @@ var (
corev1GV = schema.GroupVersion{Version: "v1"}
corev1Codec = scheme.Codecs.CodecForVersions(scheme.Codecs.LegacyCodec(corev1GV), scheme.Codecs.UniversalDecoder(corev1GV), corev1GV, corev1GV)
metaAccessor = meta.NewAccessor()
restmapper = testrestmapper.TestOnlyStaticRESTMapper(scheme.Scheme)
)
func stringBody(body string) io.ReadCloser {
@ -273,7 +271,7 @@ func newDefaultBuilder() *Builder {
}
func newDefaultBuilderWith(fakeClientFn FakeClientFunc) *Builder {
return NewFakeBuilder(fakeClientFn, restmapper, categories.LegacyCategoryExpander).
return NewFakeBuilder(fakeClientFn, testrestmapper.TestOnlyStaticRESTMapper(scheme.Scheme), FakeCategoryExpander).
WithScheme(scheme.Scheme, scheme.Scheme.PrioritizedVersionsAllGroups()...)
}

View File

@ -0,0 +1,40 @@
/*
Copyright 2017 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 resource
import (
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/client-go/restmapper"
)
// FakeCategoryExpander is for testing only
var FakeCategoryExpander restmapper.CategoryExpander = restmapper.SimpleCategoryExpander{
Expansions: map[string][]schema.GroupResource{
"all": {
{Group: "", Resource: "pods"},
{Group: "", Resource: "replicationcontrollers"},
{Group: "", Resource: "services"},
{Group: "apps", Resource: "statefulsets"},
{Group: "autoscaling", Resource: "horizontalpodautoscalers"},
{Group: "batch", Resource: "jobs"},
{Group: "batch", Resource: "cronjobs"},
{Group: "extensions", Resource: "daemonsets"},
{Group: "extensions", Resource: "deployments"},
{Group: "extensions", Resource: "replicasets"},
},
},
}

View File

@ -3,6 +3,7 @@ load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
go_library(
name = "go_default_library",
srcs = [
"category_expansion.go",
"discovery.go",
"shortcut.go",
],
@ -20,6 +21,7 @@ go_library(
go_test(
name = "go_default_test",
srcs = [
"category_expansion_test.go",
"discovery_test.go",
"shortcut_test.go",
],

View File

@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package categories
package restmapper
import (
"k8s.io/apimachinery/pkg/runtime/schema"
@ -33,6 +33,7 @@ type SimpleCategoryExpander struct {
Expansions map[string][]schema.GroupResource
}
// Expand fulfills CategoryExpander
func (e SimpleCategoryExpander) Expand(category string) ([]schema.GroupResource, bool) {
ret, ok := e.Expansions[category]
return ret, ok
@ -41,33 +42,32 @@ func (e SimpleCategoryExpander) Expand(category string) ([]schema.GroupResource,
// discoveryCategoryExpander struct lets a REST Client wrapper (discoveryClient) to retrieve list of APIResourceList,
// and then convert to fallbackExpander
type discoveryCategoryExpander struct {
fallbackExpander CategoryExpander
discoveryClient discovery.DiscoveryInterface
discoveryClient discovery.DiscoveryInterface
}
// NewDiscoveryCategoryExpander returns a category expander that makes use of the "categories" fields from
// the API, found through the discovery client. In case of any error or no category found (which likely
// means we're at a cluster prior to categories support, fallback to the expander provided.
func NewDiscoveryCategoryExpander(fallbackExpander CategoryExpander, client discovery.DiscoveryInterface) (discoveryCategoryExpander, error) {
func NewDiscoveryCategoryExpander(client discovery.DiscoveryInterface) (CategoryExpander, error) {
if client == nil {
panic("Please provide discovery client to shortcut expander")
}
return discoveryCategoryExpander{fallbackExpander: fallbackExpander, discoveryClient: client}, nil
return discoveryCategoryExpander{discoveryClient: client}, nil
}
// Expand fulfills CategoryExpander
func (e discoveryCategoryExpander) Expand(category string) ([]schema.GroupResource, bool) {
// Get all supported resources for groups and versions from server, if no resource found, fallback anyway.
apiResourceLists, _ := e.discoveryClient.ServerResources()
if len(apiResourceLists) == 0 {
return e.fallbackExpander.Expand(category)
return nil, false
}
discoveredExpansions := map[string][]schema.GroupResource{}
for _, apiResourceList := range apiResourceLists {
gv, err := schema.ParseGroupVersion(apiResourceList.GroupVersion)
if err != nil {
return e.fallbackExpander.Expand(category)
continue
}
// Collect GroupVersions by categories
for _, apiResource := range apiResourceList.APIResources {
@ -83,64 +83,15 @@ func (e discoveryCategoryExpander) Expand(category string) ([]schema.GroupResour
}
}
if len(discoveredExpansions) == 0 {
// We don't know if the server really don't have any resource with categories,
// or we're on a cluster version prior to categories support. Anyways, fallback.
return e.fallbackExpander.Expand(category)
}
ret, ok := discoveredExpansions[category]
return ret, ok
}
// discoveryFilteredExpander expands the given CategoryExpander (delegate) to filter group and resource returned from server
type discoveryFilteredExpander struct {
delegate CategoryExpander
discoveryClient discovery.DiscoveryInterface
}
// NewDiscoveryFilteredExpander returns a category expander that filters the returned groupresources
// by what the server has available
func NewDiscoveryFilteredExpander(delegate CategoryExpander, client discovery.DiscoveryInterface) (discoveryFilteredExpander, error) {
if client == nil {
panic("Please provide discovery client to shortcut expander")
}
return discoveryFilteredExpander{delegate: delegate, discoveryClient: client}, nil
}
func (e discoveryFilteredExpander) Expand(category string) ([]schema.GroupResource, bool) {
delegateExpansion, ok := e.delegate.Expand(category)
// Check if we have access to server resources
apiResources, err := e.discoveryClient.ServerResources()
if err != nil {
return delegateExpansion, ok
}
availableResources, err := discovery.GroupVersionResources(apiResources)
if err != nil {
return delegateExpansion, ok
}
available := []schema.GroupResource{}
for _, requestedResource := range delegateExpansion {
for availableResource := range availableResources {
if requestedResource.Group == availableResource.Group &&
requestedResource.Resource == availableResource.Resource {
available = append(available, requestedResource)
break
}
}
}
return available, ok
}
// UnionCategoryExpander implements CategoryExpander interface.
// It maps given category string to union of expansions returned by all the CategoryExpanders in the list.
type UnionCategoryExpander []CategoryExpander
// Expand fulfills CategoryExpander
func (u UnionCategoryExpander) Expand(category string) ([]schema.GroupResource, bool) {
ret := []schema.GroupResource{}
ok := false
@ -166,27 +117,3 @@ func (u UnionCategoryExpander) Expand(category string) ([]schema.GroupResource,
return ret, ok
}
// legacyUserResources 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.
// Should remain exported in order to expose a current list of resources to downstream
// composition that wants to build on the concept of 'all' for their CLIs.
var legacyUserResources = []schema.GroupResource{
{Group: "", Resource: "pods"},
{Group: "", Resource: "replicationcontrollers"},
{Group: "", Resource: "services"},
{Group: "apps", Resource: "statefulsets"},
{Group: "autoscaling", Resource: "horizontalpodautoscalers"},
{Group: "batch", Resource: "jobs"},
{Group: "batch", Resource: "cronjobs"},
{Group: "extensions", Resource: "daemonsets"},
{Group: "extensions", Resource: "deployments"},
{Group: "extensions", Resource: "replicasets"},
}
// LegacyCategoryExpander is the old hardcoded expansion
var LegacyCategoryExpander CategoryExpander = SimpleCategoryExpander{
Expansions: map[string][]schema.GroupResource{
"all": legacyUserResources,
},
}

View File

@ -14,19 +14,14 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package categories
package restmapper
import (
"reflect"
"testing"
"github.com/googleapis/gnostic/OpenAPIv2"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/version"
"k8s.io/client-go/discovery"
restclient "k8s.io/client-go/rest"
"k8s.io/client-go/rest/fake"
)
func TestCategoryExpansion(t *testing.T) {
@ -46,23 +41,28 @@ func TestCategoryExpansion(t *testing.T) {
name: "all-replacement",
arg: "all",
expected: []schema.GroupResource{
{Resource: "pods"},
{Resource: "replicationcontrollers"},
{Resource: "services"},
{Resource: "statefulsets", Group: "apps"},
{Resource: "horizontalpodautoscalers", Group: "autoscaling"},
{Resource: "jobs", Group: "batch"},
{Resource: "cronjobs", Group: "batch"},
{Resource: "daemonsets", Group: "extensions"},
{Resource: "deployments", Group: "extensions"},
{Resource: "replicasets", Group: "extensions"},
{Resource: "one"},
{Resource: "two"},
{Resource: "three", Group: "alpha"},
{Resource: "four", Group: "bravo"},
},
expectedOk: true,
},
}
for _, test := range tests {
actual, actualOk := LegacyCategoryExpander.Expand(test.arg)
simpleCategoryExpander := SimpleCategoryExpander{
Expansions: map[string][]schema.GroupResource{
"all": {
{Group: "", Resource: "one"},
{Group: "", Resource: "two"},
{Group: "alpha", Resource: "three"},
{Group: "bravo", Resource: "four"},
},
},
}
actual, actualOk := simpleCategoryExpander.Expand(test.arg)
if e, a := test.expected, actual; !reflect.DeepEqual(e, a) {
t.Errorf("%s: expected %s, got %s", test.name, e, a)
}
@ -135,7 +135,7 @@ func TestDiscoveryCategoryExpander(t *testing.T) {
dc.serverResourcesHandler = func() ([]*metav1.APIResourceList, error) {
return test.serverResponse, nil
}
expander, err := NewDiscoveryCategoryExpander(SimpleCategoryExpander{}, dc)
expander, err := NewDiscoveryCategoryExpander(dc)
if err != nil {
t.Fatalf("unexpected error %v", err)
}
@ -146,41 +146,3 @@ func TestDiscoveryCategoryExpander(t *testing.T) {
}
}
type fakeDiscoveryClient struct {
serverResourcesHandler func() ([]*metav1.APIResourceList, error)
}
var _ discovery.DiscoveryInterface = &fakeDiscoveryClient{}
func (c *fakeDiscoveryClient) RESTClient() restclient.Interface {
return &fake.RESTClient{}
}
func (c *fakeDiscoveryClient) ServerGroups() (*metav1.APIGroupList, error) {
return nil, nil
}
func (c *fakeDiscoveryClient) ServerResourcesForGroupVersion(groupVersion string) (*metav1.APIResourceList, error) {
return &metav1.APIResourceList{}, nil
}
func (c *fakeDiscoveryClient) ServerResources() ([]*metav1.APIResourceList, error) {
return c.serverResourcesHandler()
}
func (c *fakeDiscoveryClient) ServerPreferredResources() ([]*metav1.APIResourceList, error) {
return nil, nil
}
func (c *fakeDiscoveryClient) ServerPreferredNamespacedResources() ([]*metav1.APIResourceList, error) {
return nil, nil
}
func (c *fakeDiscoveryClient) ServerVersion() (*version.Info, error) {
return &version.Info{}, nil
}
func (c *fakeDiscoveryClient) OpenAPISchema() (*openapi_v2.Document, error) {
return &openapi_v2.Document{}, nil
}