123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670 |
- /*
- 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 testing
- import (
- "bytes"
- "errors"
- "fmt"
- "io/ioutil"
- "os"
- "path/filepath"
- "time"
- "k8s.io/apimachinery/pkg/api/meta"
- "k8s.io/apimachinery/pkg/api/meta/testrestmapper"
- metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
- "k8s.io/apimachinery/pkg/runtime"
- "k8s.io/apimachinery/pkg/runtime/schema"
- "k8s.io/apimachinery/pkg/runtime/serializer"
- "k8s.io/cli-runtime/pkg/genericclioptions"
- "k8s.io/cli-runtime/pkg/resource"
- "k8s.io/client-go/discovery"
- diskcached "k8s.io/client-go/discovery/cached/disk"
- "k8s.io/client-go/dynamic"
- fakedynamic "k8s.io/client-go/dynamic/fake"
- "k8s.io/client-go/kubernetes"
- restclient "k8s.io/client-go/rest"
- "k8s.io/client-go/rest/fake"
- "k8s.io/client-go/restmapper"
- scaleclient "k8s.io/client-go/scale"
- "k8s.io/client-go/tools/clientcmd"
- clientcmdapi "k8s.io/client-go/tools/clientcmd/api"
- "k8s.io/kubernetes/pkg/kubectl"
- 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"
- "k8s.io/kubernetes/pkg/kubectl/scheme"
- "k8s.io/kubernetes/pkg/kubectl/validation"
- )
- // InternalType is the schema for internal type
- // +k8s:deepcopy-gen=true
- // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
- type InternalType struct {
- Kind string
- APIVersion string
- Name string
- }
- // ExternalType is the schema for external type
- // +k8s:deepcopy-gen=true
- // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
- type ExternalType struct {
- Kind string `json:"kind"`
- APIVersion string `json:"apiVersion"`
- Name string `json:"name"`
- }
- // ExternalType2 is another schema for external type
- // +k8s:deepcopy-gen=true
- // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
- type ExternalType2 struct {
- Kind string `json:"kind"`
- APIVersion string `json:"apiVersion"`
- Name string `json:"name"`
- }
- // GetObjectKind returns the ObjectKind schema
- func (obj *InternalType) GetObjectKind() schema.ObjectKind { return obj }
- // SetGroupVersionKind sets the version and kind
- func (obj *InternalType) SetGroupVersionKind(gvk schema.GroupVersionKind) {
- obj.APIVersion, obj.Kind = gvk.ToAPIVersionAndKind()
- }
- // GroupVersionKind returns GroupVersionKind schema
- func (obj *InternalType) GroupVersionKind() schema.GroupVersionKind {
- return schema.FromAPIVersionAndKind(obj.APIVersion, obj.Kind)
- }
- // GetObjectKind returns the ObjectKind schema
- func (obj *ExternalType) GetObjectKind() schema.ObjectKind { return obj }
- // SetGroupVersionKind returns the GroupVersionKind schema
- func (obj *ExternalType) SetGroupVersionKind(gvk schema.GroupVersionKind) {
- obj.APIVersion, obj.Kind = gvk.ToAPIVersionAndKind()
- }
- // GroupVersionKind returns the GroupVersionKind schema
- func (obj *ExternalType) GroupVersionKind() schema.GroupVersionKind {
- return schema.FromAPIVersionAndKind(obj.APIVersion, obj.Kind)
- }
- // GetObjectKind returns the ObjectKind schema
- func (obj *ExternalType2) GetObjectKind() schema.ObjectKind { return obj }
- // SetGroupVersionKind sets the API version and obj kind from schema
- func (obj *ExternalType2) SetGroupVersionKind(gvk schema.GroupVersionKind) {
- obj.APIVersion, obj.Kind = gvk.ToAPIVersionAndKind()
- }
- // GroupVersionKind returns the FromAPIVersionAndKind schema
- func (obj *ExternalType2) GroupVersionKind() schema.GroupVersionKind {
- return schema.FromAPIVersionAndKind(obj.APIVersion, obj.Kind)
- }
- // NewInternalType returns an initialized InternalType instance
- func NewInternalType(kind, apiversion, name string) *InternalType {
- item := InternalType{Kind: kind,
- APIVersion: apiversion,
- Name: name}
- return &item
- }
- // InternalNamespacedType schema for internal namespaced types
- // +k8s:deepcopy-gen=true
- // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
- type InternalNamespacedType struct {
- Kind string
- APIVersion string
- Name string
- Namespace string
- }
- // ExternalNamespacedType schema for external namespaced types
- // +k8s:deepcopy-gen=true
- // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
- type ExternalNamespacedType struct {
- Kind string `json:"kind"`
- APIVersion string `json:"apiVersion"`
- Name string `json:"name"`
- Namespace string `json:"namespace"`
- }
- // ExternalNamespacedType2 schema for external namespaced types
- // +k8s:deepcopy-gen=true
- // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
- type ExternalNamespacedType2 struct {
- Kind string `json:"kind"`
- APIVersion string `json:"apiVersion"`
- Name string `json:"name"`
- Namespace string `json:"namespace"`
- }
- // GetObjectKind returns the ObjectKind schema
- func (obj *InternalNamespacedType) GetObjectKind() schema.ObjectKind { return obj }
- // SetGroupVersionKind sets the API group and kind from schema
- func (obj *InternalNamespacedType) SetGroupVersionKind(gvk schema.GroupVersionKind) {
- obj.APIVersion, obj.Kind = gvk.ToAPIVersionAndKind()
- }
- // GroupVersionKind returns the GroupVersionKind schema
- func (obj *InternalNamespacedType) GroupVersionKind() schema.GroupVersionKind {
- return schema.FromAPIVersionAndKind(obj.APIVersion, obj.Kind)
- }
- // GetObjectKind returns the ObjectKind schema
- func (obj *ExternalNamespacedType) GetObjectKind() schema.ObjectKind { return obj }
- // SetGroupVersionKind sets the API version and kind from schema
- func (obj *ExternalNamespacedType) SetGroupVersionKind(gvk schema.GroupVersionKind) {
- obj.APIVersion, obj.Kind = gvk.ToAPIVersionAndKind()
- }
- // GroupVersionKind returns the GroupVersionKind schema
- func (obj *ExternalNamespacedType) GroupVersionKind() schema.GroupVersionKind {
- return schema.FromAPIVersionAndKind(obj.APIVersion, obj.Kind)
- }
- // GetObjectKind returns the ObjectKind schema
- func (obj *ExternalNamespacedType2) GetObjectKind() schema.ObjectKind { return obj }
- // SetGroupVersionKind sets the API version and kind from schema
- func (obj *ExternalNamespacedType2) SetGroupVersionKind(gvk schema.GroupVersionKind) {
- obj.APIVersion, obj.Kind = gvk.ToAPIVersionAndKind()
- }
- // GroupVersionKind returns the GroupVersionKind schema
- func (obj *ExternalNamespacedType2) GroupVersionKind() schema.GroupVersionKind {
- return schema.FromAPIVersionAndKind(obj.APIVersion, obj.Kind)
- }
- // NewInternalNamespacedType returns an initialized instance of InternalNamespacedType
- func NewInternalNamespacedType(kind, apiversion, name, namespace string) *InternalNamespacedType {
- item := InternalNamespacedType{Kind: kind,
- APIVersion: apiversion,
- Name: name,
- Namespace: namespace}
- return &item
- }
- var errInvalidVersion = errors.New("not a version")
- // ValidVersion of API
- var ValidVersion = "v1"
- // InternalGV is the internal group version object
- var InternalGV = schema.GroupVersion{Group: "apitest", Version: runtime.APIVersionInternal}
- // UnlikelyGV is a group version object for unrecognised version
- var UnlikelyGV = schema.GroupVersion{Group: "apitest", Version: "unlikelyversion"}
- // ValidVersionGV is the valid group version object
- var ValidVersionGV = schema.GroupVersion{Group: "apitest", Version: ValidVersion}
- // NewExternalScheme returns required objects for ExternalScheme
- func NewExternalScheme() (*runtime.Scheme, meta.RESTMapper, runtime.Codec) {
- scheme := runtime.NewScheme()
- mapper, codec := AddToScheme(scheme)
- return scheme, mapper, codec
- }
- // AddToScheme adds required objects into scheme
- func AddToScheme(scheme *runtime.Scheme) (meta.RESTMapper, runtime.Codec) {
- scheme.AddKnownTypeWithName(InternalGV.WithKind("Type"), &InternalType{})
- scheme.AddKnownTypeWithName(UnlikelyGV.WithKind("Type"), &ExternalType{})
- //This tests that kubectl will not confuse the external scheme with the internal scheme, even when they accidentally have versions of the same name.
- scheme.AddKnownTypeWithName(ValidVersionGV.WithKind("Type"), &ExternalType2{})
- scheme.AddKnownTypeWithName(InternalGV.WithKind("NamespacedType"), &InternalNamespacedType{})
- scheme.AddKnownTypeWithName(UnlikelyGV.WithKind("NamespacedType"), &ExternalNamespacedType{})
- //This tests that kubectl will not confuse the external scheme with the internal scheme, even when they accidentally have versions of the same name.
- scheme.AddKnownTypeWithName(ValidVersionGV.WithKind("NamespacedType"), &ExternalNamespacedType2{})
- codecs := serializer.NewCodecFactory(scheme)
- codec := codecs.LegacyCodec(UnlikelyGV)
- mapper := meta.NewDefaultRESTMapper([]schema.GroupVersion{UnlikelyGV, ValidVersionGV})
- for _, gv := range []schema.GroupVersion{UnlikelyGV, ValidVersionGV} {
- for kind := range scheme.KnownTypes(gv) {
- gvk := gv.WithKind(kind)
- scope := meta.RESTScopeNamespace
- mapper.Add(gvk, scope)
- }
- }
- return mapper, codec
- }
- type fakeCachedDiscoveryClient struct {
- discovery.DiscoveryInterface
- }
- func (d *fakeCachedDiscoveryClient) Fresh() bool {
- return true
- }
- func (d *fakeCachedDiscoveryClient) Invalidate() {
- }
- // Deprecated: use ServerGroupsAndResources instead.
- func (d *fakeCachedDiscoveryClient) ServerResources() ([]*metav1.APIResourceList, error) {
- return []*metav1.APIResourceList{}, nil
- }
- func (d *fakeCachedDiscoveryClient) ServerGroupsAndResources() ([]*metav1.APIGroup, []*metav1.APIResourceList, error) {
- return []*metav1.APIGroup{}, []*metav1.APIResourceList{}, nil
- }
- // TestFactory extends cmdutil.Factory
- type TestFactory struct {
- cmdutil.Factory
- kubeConfigFlags *genericclioptions.TestConfigFlags
- Client kubectl.RESTClient
- ScaleGetter scaleclient.ScalesGetter
- UnstructuredClient kubectl.RESTClient
- ClientConfigVal *restclient.Config
- FakeDynamicClient *fakedynamic.FakeDynamicClient
- tempConfigFile *os.File
- UnstructuredClientForMappingFunc resource.FakeClientFunc
- OpenAPISchemaFunc func() (openapi.Resources, error)
- }
- // NewTestFactory returns an initialized TestFactory instance
- func NewTestFactory() *TestFactory {
- // specify an optionalClientConfig to explicitly use in testing
- // to avoid polluting an existing user config.
- tmpFile, err := ioutil.TempFile("", "cmdtests_temp")
- if err != nil {
- panic(fmt.Sprintf("unable to create a fake client config: %v", err))
- }
- loadingRules := &clientcmd.ClientConfigLoadingRules{
- Precedence: []string{tmpFile.Name()},
- MigrationRules: map[string]string{},
- }
- overrides := &clientcmd.ConfigOverrides{ClusterDefaults: clientcmdapi.Cluster{Server: "http://localhost:8080"}}
- fallbackReader := bytes.NewBuffer([]byte{})
- clientConfig := clientcmd.NewInteractiveDeferredLoadingClientConfig(loadingRules, overrides, fallbackReader)
- configFlags := genericclioptions.NewTestConfigFlags().
- WithClientConfig(clientConfig).
- WithRESTMapper(testRESTMapper())
- restConfig, err := clientConfig.ClientConfig()
- if err != nil {
- panic(fmt.Sprintf("unable to create a fake restclient config: %v", err))
- }
- return &TestFactory{
- Factory: cmdutil.NewFactory(configFlags),
- kubeConfigFlags: configFlags,
- FakeDynamicClient: fakedynamic.NewSimpleDynamicClient(scheme.Scheme),
- tempConfigFile: tmpFile,
- ClientConfigVal: restConfig,
- }
- }
- // WithNamespace is used to mention namespace reactively
- func (f *TestFactory) WithNamespace(ns string) *TestFactory {
- f.kubeConfigFlags.WithNamespace(ns)
- return f
- }
- // Cleanup cleans up TestFactory temp config file
- func (f *TestFactory) Cleanup() {
- if f.tempConfigFile == nil {
- return
- }
- os.Remove(f.tempConfigFile.Name())
- }
- // ToRESTConfig is used to get ClientConfigVal from a TestFactory
- func (f *TestFactory) ToRESTConfig() (*restclient.Config, error) {
- return f.ClientConfigVal, nil
- }
- // ClientForMapping is used to Client from a TestFactory
- func (f *TestFactory) ClientForMapping(mapping *meta.RESTMapping) (resource.RESTClient, error) {
- return f.Client, nil
- }
- // UnstructuredClientForMapping is used to get UnstructuredClient from a TestFactory
- func (f *TestFactory) UnstructuredClientForMapping(mapping *meta.RESTMapping) (resource.RESTClient, error) {
- if f.UnstructuredClientForMappingFunc != nil {
- return f.UnstructuredClientForMappingFunc(mapping.GroupVersionKind.GroupVersion())
- }
- return f.UnstructuredClient, nil
- }
- // Validator returns a validation schema
- func (f *TestFactory) Validator(validate bool) (validation.Schema, error) {
- return validation.NullSchema{}, nil
- }
- // OpenAPISchema returns openapi resources
- func (f *TestFactory) OpenAPISchema() (openapi.Resources, error) {
- if f.OpenAPISchemaFunc != nil {
- return f.OpenAPISchemaFunc()
- }
- return openapitesting.EmptyResources{}, nil
- }
- // NewBuilder returns an initialized resource.Builder instance
- func (f *TestFactory) NewBuilder() *resource.Builder {
- return resource.NewFakeBuilder(
- func(version schema.GroupVersion) (resource.RESTClient, error) {
- if f.UnstructuredClientForMappingFunc != nil {
- return f.UnstructuredClientForMappingFunc(version)
- }
- if f.UnstructuredClient != nil {
- return f.UnstructuredClient, nil
- }
- return f.Client, nil
- },
- f.ToRESTMapper,
- func() (restmapper.CategoryExpander, error) {
- return resource.FakeCategoryExpander, nil
- },
- )
- }
- // KubernetesClientSet initializes and returns the Clientset using TestFactory
- func (f *TestFactory) KubernetesClientSet() (*kubernetes.Clientset, error) {
- fakeClient := f.Client.(*fake.RESTClient)
- clientset := kubernetes.NewForConfigOrDie(f.ClientConfigVal)
- clientset.CoreV1().RESTClient().(*restclient.RESTClient).Client = fakeClient.Client
- clientset.AuthorizationV1().RESTClient().(*restclient.RESTClient).Client = fakeClient.Client
- clientset.AuthorizationV1beta1().RESTClient().(*restclient.RESTClient).Client = fakeClient.Client
- clientset.AuthorizationV1().RESTClient().(*restclient.RESTClient).Client = fakeClient.Client
- clientset.AuthorizationV1beta1().RESTClient().(*restclient.RESTClient).Client = fakeClient.Client
- clientset.AutoscalingV1().RESTClient().(*restclient.RESTClient).Client = fakeClient.Client
- clientset.AutoscalingV2beta1().RESTClient().(*restclient.RESTClient).Client = fakeClient.Client
- clientset.BatchV1().RESTClient().(*restclient.RESTClient).Client = fakeClient.Client
- clientset.BatchV2alpha1().RESTClient().(*restclient.RESTClient).Client = fakeClient.Client
- clientset.CertificatesV1beta1().RESTClient().(*restclient.RESTClient).Client = fakeClient.Client
- clientset.ExtensionsV1beta1().RESTClient().(*restclient.RESTClient).Client = fakeClient.Client
- clientset.RbacV1alpha1().RESTClient().(*restclient.RESTClient).Client = fakeClient.Client
- clientset.RbacV1beta1().RESTClient().(*restclient.RESTClient).Client = fakeClient.Client
- clientset.StorageV1().RESTClient().(*restclient.RESTClient).Client = fakeClient.Client
- clientset.StorageV1beta1().RESTClient().(*restclient.RESTClient).Client = fakeClient.Client
- clientset.AppsV1beta1().RESTClient().(*restclient.RESTClient).Client = fakeClient.Client
- clientset.AppsV1beta2().RESTClient().(*restclient.RESTClient).Client = fakeClient.Client
- clientset.AppsV1().RESTClient().(*restclient.RESTClient).Client = fakeClient.Client
- clientset.PolicyV1beta1().RESTClient().(*restclient.RESTClient).Client = fakeClient.Client
- clientset.DiscoveryClient.RESTClient().(*restclient.RESTClient).Client = fakeClient.Client
- return clientset, nil
- }
- // DynamicClient returns a dynamic client from TestFactory
- func (f *TestFactory) DynamicClient() (dynamic.Interface, error) {
- if f.FakeDynamicClient != nil {
- return f.FakeDynamicClient, nil
- }
- return f.Factory.DynamicClient()
- }
- // RESTClient returns a REST client from TestFactory
- func (f *TestFactory) RESTClient() (*restclient.RESTClient, error) {
- // Swap out the HTTP client out of the client with the fake's version.
- fakeClient := f.Client.(*fake.RESTClient)
- restClient, err := restclient.RESTClientFor(f.ClientConfigVal)
- if err != nil {
- panic(err)
- }
- restClient.Client = fakeClient.Client
- return restClient, nil
- }
- // DiscoveryClient returns a discovery client from TestFactory
- func (f *TestFactory) DiscoveryClient() (discovery.CachedDiscoveryInterface, error) {
- fakeClient := f.Client.(*fake.RESTClient)
- cacheDir := filepath.Join("", ".kube", "cache", "discovery")
- cachedClient, err := diskcached.NewCachedDiscoveryClientForConfig(f.ClientConfigVal, cacheDir, "", time.Duration(10*time.Minute))
- if err != nil {
- return nil, err
- }
- cachedClient.RESTClient().(*restclient.RESTClient).Client = fakeClient.Client
- return cachedClient, nil
- }
- func testRESTMapper() meta.RESTMapper {
- groupResources := testDynamicResources()
- mapper := restmapper.NewDiscoveryRESTMapper(groupResources)
- // for backwards compatibility with existing tests, allow rest mappings from the scheme to show up
- // TODO: make this opt-in?
- mapper = meta.FirstHitRESTMapper{
- MultiRESTMapper: meta.MultiRESTMapper{
- mapper,
- testrestmapper.TestOnlyStaticRESTMapper(scheme.Scheme),
- },
- }
- fakeDs := &fakeCachedDiscoveryClient{}
- expander := restmapper.NewShortcutExpander(mapper, fakeDs)
- return expander
- }
- // ScaleClient returns the ScalesGetter from a TestFactory
- func (f *TestFactory) ScaleClient() (scaleclient.ScalesGetter, error) {
- return f.ScaleGetter, nil
- }
- func testDynamicResources() []*restmapper.APIGroupResources {
- return []*restmapper.APIGroupResources{
- {
- Group: metav1.APIGroup{
- Versions: []metav1.GroupVersionForDiscovery{
- {Version: "v1"},
- },
- PreferredVersion: metav1.GroupVersionForDiscovery{Version: "v1"},
- },
- VersionedResources: map[string][]metav1.APIResource{
- "v1": {
- {Name: "pods", Namespaced: true, Kind: "Pod"},
- {Name: "services", Namespaced: true, Kind: "Service"},
- {Name: "replicationcontrollers", Namespaced: true, Kind: "ReplicationController"},
- {Name: "componentstatuses", Namespaced: false, Kind: "ComponentStatus"},
- {Name: "nodes", Namespaced: false, Kind: "Node"},
- {Name: "secrets", Namespaced: true, Kind: "Secret"},
- {Name: "configmaps", Namespaced: true, Kind: "ConfigMap"},
- {Name: "namespacedtype", Namespaced: true, Kind: "NamespacedType"},
- {Name: "namespaces", Namespaced: false, Kind: "Namespace"},
- {Name: "resourcequotas", Namespaced: true, Kind: "ResourceQuota"},
- },
- },
- },
- {
- Group: metav1.APIGroup{
- Name: "extensions",
- Versions: []metav1.GroupVersionForDiscovery{
- {Version: "v1beta1"},
- },
- PreferredVersion: metav1.GroupVersionForDiscovery{Version: "v1beta1"},
- },
- VersionedResources: map[string][]metav1.APIResource{
- "v1beta1": {
- {Name: "deployments", Namespaced: true, Kind: "Deployment"},
- {Name: "replicasets", Namespaced: true, Kind: "ReplicaSet"},
- },
- },
- },
- {
- Group: metav1.APIGroup{
- Name: "apps",
- Versions: []metav1.GroupVersionForDiscovery{
- {Version: "v1beta1"},
- {Version: "v1beta2"},
- {Version: "v1"},
- },
- PreferredVersion: metav1.GroupVersionForDiscovery{Version: "v1"},
- },
- VersionedResources: map[string][]metav1.APIResource{
- "v1beta1": {
- {Name: "deployments", Namespaced: true, Kind: "Deployment"},
- {Name: "replicasets", Namespaced: true, Kind: "ReplicaSet"},
- },
- "v1beta2": {
- {Name: "deployments", Namespaced: true, Kind: "Deployment"},
- },
- "v1": {
- {Name: "deployments", Namespaced: true, Kind: "Deployment"},
- {Name: "replicasets", Namespaced: true, Kind: "ReplicaSet"},
- },
- },
- },
- {
- Group: metav1.APIGroup{
- Name: "batch",
- Versions: []metav1.GroupVersionForDiscovery{
- {Version: "v1beta1"},
- {Version: "v1"},
- },
- PreferredVersion: metav1.GroupVersionForDiscovery{Version: "v1"},
- },
- VersionedResources: map[string][]metav1.APIResource{
- "v1beta1": {
- {Name: "cronjobs", Namespaced: true, Kind: "CronJob"},
- },
- "v1": {
- {Name: "jobs", Namespaced: true, Kind: "Job"},
- },
- },
- },
- {
- Group: metav1.APIGroup{
- Name: "autoscaling",
- Versions: []metav1.GroupVersionForDiscovery{
- {Version: "v1"},
- {Version: "v2beta1"},
- },
- PreferredVersion: metav1.GroupVersionForDiscovery{Version: "v2beta1"},
- },
- VersionedResources: map[string][]metav1.APIResource{
- "v1": {
- {Name: "horizontalpodautoscalers", Namespaced: true, Kind: "HorizontalPodAutoscaler"},
- },
- "v2beta1": {
- {Name: "horizontalpodautoscalers", Namespaced: true, Kind: "HorizontalPodAutoscaler"},
- },
- },
- },
- {
- Group: metav1.APIGroup{
- Name: "storage.k8s.io",
- Versions: []metav1.GroupVersionForDiscovery{
- {Version: "v1beta1"},
- {Version: "v0"},
- },
- PreferredVersion: metav1.GroupVersionForDiscovery{Version: "v1beta1"},
- },
- VersionedResources: map[string][]metav1.APIResource{
- "v1beta1": {
- {Name: "storageclasses", Namespaced: false, Kind: "StorageClass"},
- },
- // bogus version of a known group/version/resource to make sure kubectl falls back to generic object mode
- "v0": {
- {Name: "storageclasses", Namespaced: false, Kind: "StorageClass"},
- },
- },
- },
- {
- Group: metav1.APIGroup{
- Name: "rbac.authorization.k8s.io",
- Versions: []metav1.GroupVersionForDiscovery{
- {Version: "v1beta1"},
- {Version: "v1"},
- },
- PreferredVersion: metav1.GroupVersionForDiscovery{Version: "v1"},
- },
- VersionedResources: map[string][]metav1.APIResource{
- "v1": {
- {Name: "clusterroles", Namespaced: false, Kind: "ClusterRole"},
- },
- "v1beta1": {
- {Name: "clusterrolebindings", Namespaced: false, Kind: "ClusterRoleBinding"},
- },
- },
- },
- {
- Group: metav1.APIGroup{
- Name: "company.com",
- Versions: []metav1.GroupVersionForDiscovery{
- {Version: "v1"},
- },
- PreferredVersion: metav1.GroupVersionForDiscovery{Version: "v1"},
- },
- VersionedResources: map[string][]metav1.APIResource{
- "v1": {
- {Name: "bars", Namespaced: true, Kind: "Bar"},
- },
- },
- },
- {
- Group: metav1.APIGroup{
- Name: "unit-test.test.com",
- Versions: []metav1.GroupVersionForDiscovery{
- {GroupVersion: "unit-test.test.com/v1", Version: "v1"},
- },
- PreferredVersion: metav1.GroupVersionForDiscovery{
- GroupVersion: "unit-test.test.com/v1",
- Version: "v1"},
- },
- VersionedResources: map[string][]metav1.APIResource{
- "v1": {
- {Name: "widgets", Namespaced: true, Kind: "Widget"},
- },
- },
- },
- {
- Group: metav1.APIGroup{
- Name: "apitest",
- Versions: []metav1.GroupVersionForDiscovery{
- {GroupVersion: "apitest/unlikelyversion", Version: "unlikelyversion"},
- },
- PreferredVersion: metav1.GroupVersionForDiscovery{
- GroupVersion: "apitest/unlikelyversion",
- Version: "unlikelyversion"},
- },
- VersionedResources: map[string][]metav1.APIResource{
- "unlikelyversion": {
- {Name: "types", SingularName: "type", Namespaced: false, Kind: "Type"},
- },
- },
- },
- }
- }
|