mirror of
				https://github.com/k3s-io/kubernetes.git
				synced 2025-11-03 23:40:03 +00:00 
			
		
		
		
	These packages deserve to live at the top level of `k8s.io/cli-runtime`, as they are potentially of wider use than genericclioptions.
		
			
				
	
	
		
			677 lines
		
	
	
		
			23 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			677 lines
		
	
	
		
			23 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
/*
 | 
						|
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")
 | 
						|
 | 
						|
func versionErrIfFalse(b bool) error {
 | 
						|
	if b {
 | 
						|
		return nil
 | 
						|
	}
 | 
						|
	return errInvalidVersion
 | 
						|
}
 | 
						|
 | 
						|
// 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"},
 | 
						|
				},
 | 
						|
			},
 | 
						|
		},
 | 
						|
	}
 | 
						|
}
 |