1
16
17 package testing
18
19 import (
20 "bytes"
21 "fmt"
22 "os"
23 "path/filepath"
24 "time"
25
26 "k8s.io/apimachinery/pkg/api/meta"
27 "k8s.io/apimachinery/pkg/api/meta/testrestmapper"
28 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
29 "k8s.io/apimachinery/pkg/conversion"
30 "k8s.io/apimachinery/pkg/runtime"
31 "k8s.io/apimachinery/pkg/runtime/schema"
32 "k8s.io/apimachinery/pkg/runtime/serializer"
33 utilruntime "k8s.io/apimachinery/pkg/util/runtime"
34 "k8s.io/cli-runtime/pkg/genericclioptions"
35 "k8s.io/cli-runtime/pkg/resource"
36 "k8s.io/client-go/discovery"
37 diskcached "k8s.io/client-go/discovery/cached/disk"
38 "k8s.io/client-go/dynamic"
39 fakedynamic "k8s.io/client-go/dynamic/fake"
40 "k8s.io/client-go/kubernetes"
41 openapiclient "k8s.io/client-go/openapi"
42 "k8s.io/client-go/openapi/openapitest"
43 restclient "k8s.io/client-go/rest"
44 "k8s.io/client-go/rest/fake"
45 "k8s.io/client-go/restmapper"
46 scaleclient "k8s.io/client-go/scale"
47 "k8s.io/client-go/tools/clientcmd"
48 clientcmdapi "k8s.io/client-go/tools/clientcmd/api"
49 cmdutil "k8s.io/kubectl/pkg/cmd/util"
50 "k8s.io/kubectl/pkg/scheme"
51 "k8s.io/kubectl/pkg/util/openapi"
52 openapitesting "k8s.io/kubectl/pkg/util/openapi/testing"
53 "k8s.io/kubectl/pkg/validation"
54 )
55
56
57
58
59 type InternalType struct {
60 Kind string
61 APIVersion string
62
63 Name string
64 }
65
66
67
68
69 type ExternalType struct {
70 Kind string `json:"kind"`
71 APIVersion string `json:"apiVersion"`
72
73 Name string `json:"name"`
74 }
75
76
77
78
79 type ExternalType2 struct {
80 Kind string `json:"kind"`
81 APIVersion string `json:"apiVersion"`
82
83 Name string `json:"name"`
84 }
85
86
87 func (obj *InternalType) GetObjectKind() schema.ObjectKind { return obj }
88
89
90 func (obj *InternalType) SetGroupVersionKind(gvk schema.GroupVersionKind) {
91 obj.APIVersion, obj.Kind = gvk.ToAPIVersionAndKind()
92 }
93
94
95 func (obj *InternalType) GroupVersionKind() schema.GroupVersionKind {
96 return schema.FromAPIVersionAndKind(obj.APIVersion, obj.Kind)
97 }
98
99
100 func (obj *ExternalType) GetObjectKind() schema.ObjectKind { return obj }
101
102
103 func (obj *ExternalType) SetGroupVersionKind(gvk schema.GroupVersionKind) {
104 obj.APIVersion, obj.Kind = gvk.ToAPIVersionAndKind()
105 }
106
107
108 func (obj *ExternalType) GroupVersionKind() schema.GroupVersionKind {
109 return schema.FromAPIVersionAndKind(obj.APIVersion, obj.Kind)
110 }
111
112
113 func (obj *ExternalType2) GetObjectKind() schema.ObjectKind { return obj }
114
115
116 func (obj *ExternalType2) SetGroupVersionKind(gvk schema.GroupVersionKind) {
117 obj.APIVersion, obj.Kind = gvk.ToAPIVersionAndKind()
118 }
119
120
121 func (obj *ExternalType2) GroupVersionKind() schema.GroupVersionKind {
122 return schema.FromAPIVersionAndKind(obj.APIVersion, obj.Kind)
123 }
124
125
126 func NewInternalType(kind, apiversion, name string) *InternalType {
127 item := InternalType{Kind: kind,
128 APIVersion: apiversion,
129 Name: name}
130 return &item
131 }
132
133 func convertInternalTypeToExternalType(in *InternalType, out *ExternalType, s conversion.Scope) error {
134 out.Kind = in.Kind
135 out.APIVersion = in.APIVersion
136 out.Name = in.Name
137 return nil
138 }
139
140 func convertInternalTypeToExternalType2(in *InternalType, out *ExternalType2, s conversion.Scope) error {
141 out.Kind = in.Kind
142 out.APIVersion = in.APIVersion
143 out.Name = in.Name
144 return nil
145 }
146
147 func convertExternalTypeToInternalType(in *ExternalType, out *InternalType, s conversion.Scope) error {
148 out.Kind = in.Kind
149 out.APIVersion = in.APIVersion
150 out.Name = in.Name
151 return nil
152 }
153
154 func convertExternalType2ToInternalType(in *ExternalType2, out *InternalType, s conversion.Scope) error {
155 out.Kind = in.Kind
156 out.APIVersion = in.APIVersion
157 out.Name = in.Name
158 return nil
159 }
160
161
162
163
164 type InternalNamespacedType struct {
165 Kind string
166 APIVersion string
167
168 Name string
169 Namespace string
170 }
171
172
173
174
175 type ExternalNamespacedType struct {
176 Kind string `json:"kind"`
177 APIVersion string `json:"apiVersion"`
178
179 Name string `json:"name"`
180 Namespace string `json:"namespace"`
181 }
182
183
184
185
186 type ExternalNamespacedType2 struct {
187 Kind string `json:"kind"`
188 APIVersion string `json:"apiVersion"`
189
190 Name string `json:"name"`
191 Namespace string `json:"namespace"`
192 }
193
194
195 func (obj *InternalNamespacedType) GetObjectKind() schema.ObjectKind { return obj }
196
197
198 func (obj *InternalNamespacedType) SetGroupVersionKind(gvk schema.GroupVersionKind) {
199 obj.APIVersion, obj.Kind = gvk.ToAPIVersionAndKind()
200 }
201
202
203 func (obj *InternalNamespacedType) GroupVersionKind() schema.GroupVersionKind {
204 return schema.FromAPIVersionAndKind(obj.APIVersion, obj.Kind)
205 }
206
207
208 func (obj *ExternalNamespacedType) GetObjectKind() schema.ObjectKind { return obj }
209
210
211 func (obj *ExternalNamespacedType) SetGroupVersionKind(gvk schema.GroupVersionKind) {
212 obj.APIVersion, obj.Kind = gvk.ToAPIVersionAndKind()
213 }
214
215
216 func (obj *ExternalNamespacedType) GroupVersionKind() schema.GroupVersionKind {
217 return schema.FromAPIVersionAndKind(obj.APIVersion, obj.Kind)
218 }
219
220
221 func (obj *ExternalNamespacedType2) GetObjectKind() schema.ObjectKind { return obj }
222
223
224 func (obj *ExternalNamespacedType2) SetGroupVersionKind(gvk schema.GroupVersionKind) {
225 obj.APIVersion, obj.Kind = gvk.ToAPIVersionAndKind()
226 }
227
228
229 func (obj *ExternalNamespacedType2) GroupVersionKind() schema.GroupVersionKind {
230 return schema.FromAPIVersionAndKind(obj.APIVersion, obj.Kind)
231 }
232
233
234 func NewInternalNamespacedType(kind, apiversion, name, namespace string) *InternalNamespacedType {
235 item := InternalNamespacedType{Kind: kind,
236 APIVersion: apiversion,
237 Name: name,
238 Namespace: namespace}
239 return &item
240 }
241
242 func convertInternalNamespacedTypeToExternalNamespacedType(in *InternalNamespacedType, out *ExternalNamespacedType, s conversion.Scope) error {
243 out.Kind = in.Kind
244 out.APIVersion = in.APIVersion
245 out.Name = in.Name
246 out.Namespace = in.Namespace
247 return nil
248 }
249
250 func convertInternalNamespacedTypeToExternalNamespacedType2(in *InternalNamespacedType, out *ExternalNamespacedType2, s conversion.Scope) error {
251 out.Kind = in.Kind
252 out.APIVersion = in.APIVersion
253 out.Name = in.Name
254 out.Namespace = in.Namespace
255 return nil
256 }
257
258 func convertExternalNamespacedTypeToInternalNamespacedType(in *ExternalNamespacedType, out *InternalNamespacedType, s conversion.Scope) error {
259 out.Kind = in.Kind
260 out.APIVersion = in.APIVersion
261 out.Name = in.Name
262 out.Namespace = in.Namespace
263 return nil
264 }
265
266 func convertExternalNamespacedType2ToInternalNamespacedType(in *ExternalNamespacedType2, out *InternalNamespacedType, s conversion.Scope) error {
267 out.Kind = in.Kind
268 out.APIVersion = in.APIVersion
269 out.Name = in.Name
270 out.Namespace = in.Namespace
271 return nil
272 }
273
274
275 var ValidVersion = "v1"
276
277
278 var InternalGV = schema.GroupVersion{Group: "apitest", Version: runtime.APIVersionInternal}
279
280
281 var UnlikelyGV = schema.GroupVersion{Group: "apitest", Version: "unlikelyversion"}
282
283
284 var ValidVersionGV = schema.GroupVersion{Group: "apitest", Version: ValidVersion}
285
286
287 func NewExternalScheme() (*runtime.Scheme, meta.RESTMapper, runtime.Codec) {
288 scheme := runtime.NewScheme()
289 mapper, codec := AddToScheme(scheme)
290 return scheme, mapper, codec
291 }
292
293 func registerConversions(s *runtime.Scheme) error {
294 if err := s.AddConversionFunc((*InternalType)(nil), (*ExternalType)(nil), func(a, b interface{}, scope conversion.Scope) error {
295 return convertInternalTypeToExternalType(a.(*InternalType), b.(*ExternalType), scope)
296 }); err != nil {
297 return err
298 }
299 if err := s.AddConversionFunc((*InternalType)(nil), (*ExternalType2)(nil), func(a, b interface{}, scope conversion.Scope) error {
300 return convertInternalTypeToExternalType2(a.(*InternalType), b.(*ExternalType2), scope)
301 }); err != nil {
302 return err
303 }
304 if err := s.AddConversionFunc((*ExternalType)(nil), (*InternalType)(nil), func(a, b interface{}, scope conversion.Scope) error {
305 return convertExternalTypeToInternalType(a.(*ExternalType), b.(*InternalType), scope)
306 }); err != nil {
307 return err
308 }
309 if err := s.AddConversionFunc((*ExternalType2)(nil), (*InternalType)(nil), func(a, b interface{}, scope conversion.Scope) error {
310 return convertExternalType2ToInternalType(a.(*ExternalType2), b.(*InternalType), scope)
311 }); err != nil {
312 return err
313 }
314 if err := s.AddConversionFunc((*InternalNamespacedType)(nil), (*ExternalNamespacedType)(nil), func(a, b interface{}, scope conversion.Scope) error {
315 return convertInternalNamespacedTypeToExternalNamespacedType(a.(*InternalNamespacedType), b.(*ExternalNamespacedType), scope)
316 }); err != nil {
317 return err
318 }
319 if err := s.AddConversionFunc((*InternalNamespacedType)(nil), (*ExternalNamespacedType2)(nil), func(a, b interface{}, scope conversion.Scope) error {
320 return convertInternalNamespacedTypeToExternalNamespacedType2(a.(*InternalNamespacedType), b.(*ExternalNamespacedType2), scope)
321 }); err != nil {
322 return err
323 }
324 if err := s.AddConversionFunc((*ExternalNamespacedType)(nil), (*InternalNamespacedType)(nil), func(a, b interface{}, scope conversion.Scope) error {
325 return convertExternalNamespacedTypeToInternalNamespacedType(a.(*ExternalNamespacedType), b.(*InternalNamespacedType), scope)
326 }); err != nil {
327 return err
328 }
329 if err := s.AddConversionFunc((*ExternalNamespacedType2)(nil), (*InternalNamespacedType)(nil), func(a, b interface{}, scope conversion.Scope) error {
330 return convertExternalNamespacedType2ToInternalNamespacedType(a.(*ExternalNamespacedType2), b.(*InternalNamespacedType), scope)
331 }); err != nil {
332 return err
333 }
334 return nil
335 }
336
337
338 func AddToScheme(scheme *runtime.Scheme) (meta.RESTMapper, runtime.Codec) {
339 scheme.AddKnownTypeWithName(InternalGV.WithKind("Type"), &InternalType{})
340 scheme.AddKnownTypeWithName(UnlikelyGV.WithKind("Type"), &ExternalType{})
341
342 scheme.AddKnownTypeWithName(ValidVersionGV.WithKind("Type"), &ExternalType2{})
343
344 scheme.AddKnownTypeWithName(InternalGV.WithKind("NamespacedType"), &InternalNamespacedType{})
345 scheme.AddKnownTypeWithName(UnlikelyGV.WithKind("NamespacedType"), &ExternalNamespacedType{})
346
347 scheme.AddKnownTypeWithName(ValidVersionGV.WithKind("NamespacedType"), &ExternalNamespacedType2{})
348
349 utilruntime.Must(registerConversions(scheme))
350
351 codecs := serializer.NewCodecFactory(scheme)
352 codec := codecs.LegacyCodec(UnlikelyGV)
353 mapper := meta.NewDefaultRESTMapper([]schema.GroupVersion{UnlikelyGV, ValidVersionGV})
354 for _, gv := range []schema.GroupVersion{UnlikelyGV, ValidVersionGV} {
355 for kind := range scheme.KnownTypes(gv) {
356 gvk := gv.WithKind(kind)
357
358 scope := meta.RESTScopeNamespace
359 mapper.Add(gvk, scope)
360 }
361 }
362
363 return mapper, codec
364 }
365
366 type FakeCachedDiscoveryClient struct {
367 discovery.DiscoveryInterface
368 Groups []*metav1.APIGroup
369 Resources []*metav1.APIResourceList
370 PreferredResources []*metav1.APIResourceList
371 Invalidations int
372 }
373
374 func NewFakeCachedDiscoveryClient() *FakeCachedDiscoveryClient {
375 return &FakeCachedDiscoveryClient{
376 Groups: []*metav1.APIGroup{},
377 Resources: []*metav1.APIResourceList{},
378 PreferredResources: []*metav1.APIResourceList{},
379 Invalidations: 0,
380 }
381 }
382
383 func (d *FakeCachedDiscoveryClient) Fresh() bool {
384 return true
385 }
386
387 func (d *FakeCachedDiscoveryClient) Invalidate() {
388 d.Invalidations++
389 }
390
391 func (d *FakeCachedDiscoveryClient) ServerGroupsAndResources() ([]*metav1.APIGroup, []*metav1.APIResourceList, error) {
392 return d.Groups, d.Resources, nil
393 }
394
395 func (d *FakeCachedDiscoveryClient) ServerGroups() (*metav1.APIGroupList, error) {
396 groupList := &metav1.APIGroupList{Groups: []metav1.APIGroup{}}
397 for _, g := range d.Groups {
398 groupList.Groups = append(groupList.Groups, *g)
399 }
400 return groupList, nil
401 }
402
403 func (d *FakeCachedDiscoveryClient) ServerPreferredResources() ([]*metav1.APIResourceList, error) {
404 return d.PreferredResources, nil
405 }
406
407
408 type TestFactory struct {
409 cmdutil.Factory
410
411 kubeConfigFlags *genericclioptions.TestConfigFlags
412
413 Client RESTClient
414 ScaleGetter scaleclient.ScalesGetter
415 UnstructuredClient RESTClient
416 ClientConfigVal *restclient.Config
417 FakeDynamicClient *fakedynamic.FakeDynamicClient
418
419 tempConfigFile *os.File
420
421 UnstructuredClientForMappingFunc resource.FakeClientFunc
422 OpenAPISchemaFunc func() (openapi.Resources, error)
423 OpenAPIV3ClientFunc func() (openapiclient.Client, error)
424 }
425
426
427 func NewTestFactory() *TestFactory {
428
429
430 tmpFile, err := os.CreateTemp(os.TempDir(), "cmdtests_temp")
431 if err != nil {
432 panic(fmt.Sprintf("unable to create a fake client config: %v", err))
433 }
434
435 loadingRules := &clientcmd.ClientConfigLoadingRules{
436 Precedence: []string{tmpFile.Name()},
437 MigrationRules: map[string]string{},
438 }
439
440 overrides := &clientcmd.ConfigOverrides{ClusterDefaults: clientcmdapi.Cluster{Server: "http://localhost:8080"}}
441 fallbackReader := bytes.NewBuffer([]byte{})
442 clientConfig := clientcmd.NewInteractiveDeferredLoadingClientConfig(loadingRules, overrides, fallbackReader)
443
444 configFlags := genericclioptions.NewTestConfigFlags().
445 WithClientConfig(clientConfig).
446 WithRESTMapper(testRESTMapper())
447
448 restConfig, err := clientConfig.ClientConfig()
449 if err != nil {
450 panic(fmt.Sprintf("unable to create a fake restclient config: %v", err))
451 }
452
453 return &TestFactory{
454 Factory: cmdutil.NewFactory(configFlags),
455 kubeConfigFlags: configFlags,
456 FakeDynamicClient: fakedynamic.NewSimpleDynamicClient(scheme.Scheme),
457 tempConfigFile: tmpFile,
458
459 ClientConfigVal: restConfig,
460 }
461 }
462
463
464 func (f *TestFactory) WithNamespace(ns string) *TestFactory {
465 f.kubeConfigFlags.WithNamespace(ns)
466 return f
467 }
468
469
470 func (f *TestFactory) WithClientConfig(clientConfig clientcmd.ClientConfig) *TestFactory {
471 f.kubeConfigFlags.WithClientConfig(clientConfig)
472 return f
473 }
474
475 func (f *TestFactory) WithDiscoveryClient(discoveryClient discovery.CachedDiscoveryInterface) *TestFactory {
476 f.kubeConfigFlags.WithDiscoveryClient(discoveryClient)
477 return f
478 }
479
480
481 func (f *TestFactory) Cleanup() {
482 if f.tempConfigFile == nil {
483 return
484 }
485
486 f.tempConfigFile.Close()
487 os.Remove(f.tempConfigFile.Name())
488 }
489
490
491 func (f *TestFactory) ToRESTConfig() (*restclient.Config, error) {
492 return f.ClientConfigVal, nil
493 }
494
495
496 func (f *TestFactory) ClientForMapping(mapping *meta.RESTMapping) (resource.RESTClient, error) {
497 return f.Client, nil
498 }
499
500
501 func (f *TestFactory) PathOptions() *clientcmd.PathOptions {
502 pathOptions := clientcmd.NewDefaultPathOptions()
503 pathOptions.GlobalFile = f.tempConfigFile.Name()
504 pathOptions.EnvVar = ""
505 return pathOptions
506 }
507
508
509 func (f *TestFactory) PathOptionsWithConfig(config clientcmdapi.Config) (*clientcmd.PathOptions, error) {
510 pathOptions := f.PathOptions()
511 err := clientcmd.WriteToFile(config, pathOptions.GlobalFile)
512 if err != nil {
513 return nil, err
514 }
515
516 return pathOptions, nil
517 }
518
519
520 func (f *TestFactory) UnstructuredClientForMapping(mapping *meta.RESTMapping) (resource.RESTClient, error) {
521 if f.UnstructuredClientForMappingFunc != nil {
522 return f.UnstructuredClientForMappingFunc(mapping.GroupVersionKind.GroupVersion())
523 }
524 return f.UnstructuredClient, nil
525 }
526
527
528 func (f *TestFactory) Validator(validateDirective string) (validation.Schema, error) {
529 return validation.NullSchema{}, nil
530 }
531
532
533 func (f *TestFactory) OpenAPISchema() (openapi.Resources, error) {
534 if f.OpenAPISchemaFunc != nil {
535 return f.OpenAPISchemaFunc()
536 }
537 return openapitesting.EmptyResources{}, nil
538 }
539
540 func (f *TestFactory) OpenAPIV3Client() (openapiclient.Client, error) {
541 if f.OpenAPIV3ClientFunc != nil {
542 return f.OpenAPIV3ClientFunc()
543 }
544 return openapitest.NewFakeClient(), nil
545 }
546
547
548 func (f *TestFactory) NewBuilder() *resource.Builder {
549 return resource.NewFakeBuilder(
550 func(version schema.GroupVersion) (resource.RESTClient, error) {
551 if f.UnstructuredClientForMappingFunc != nil {
552 return f.UnstructuredClientForMappingFunc(version)
553 }
554 if f.UnstructuredClient != nil {
555 return f.UnstructuredClient, nil
556 }
557 return f.Client, nil
558 },
559 f.ToRESTMapper,
560 func() (restmapper.CategoryExpander, error) {
561 return resource.FakeCategoryExpander, nil
562 },
563 )
564 }
565
566
567 func (f *TestFactory) KubernetesClientSet() (*kubernetes.Clientset, error) {
568 fakeClient := f.Client.(*fake.RESTClient)
569 clientset := kubernetes.NewForConfigOrDie(f.ClientConfigVal)
570
571 clientset.CoreV1().RESTClient().(*restclient.RESTClient).Client = fakeClient.Client
572 clientset.AuthorizationV1().RESTClient().(*restclient.RESTClient).Client = fakeClient.Client
573 clientset.AuthorizationV1beta1().RESTClient().(*restclient.RESTClient).Client = fakeClient.Client
574 clientset.AuthorizationV1().RESTClient().(*restclient.RESTClient).Client = fakeClient.Client
575 clientset.AuthorizationV1beta1().RESTClient().(*restclient.RESTClient).Client = fakeClient.Client
576 clientset.AuthenticationV1alpha1().RESTClient().(*restclient.RESTClient).Client = fakeClient.Client
577 clientset.AutoscalingV1().RESTClient().(*restclient.RESTClient).Client = fakeClient.Client
578 clientset.AutoscalingV2().RESTClient().(*restclient.RESTClient).Client = fakeClient.Client
579 clientset.BatchV1().RESTClient().(*restclient.RESTClient).Client = fakeClient.Client
580 clientset.CertificatesV1().RESTClient().(*restclient.RESTClient).Client = fakeClient.Client
581 clientset.CertificatesV1beta1().RESTClient().(*restclient.RESTClient).Client = fakeClient.Client
582 clientset.ExtensionsV1beta1().RESTClient().(*restclient.RESTClient).Client = fakeClient.Client
583 clientset.RbacV1alpha1().RESTClient().(*restclient.RESTClient).Client = fakeClient.Client
584 clientset.RbacV1beta1().RESTClient().(*restclient.RESTClient).Client = fakeClient.Client
585 clientset.StorageV1().RESTClient().(*restclient.RESTClient).Client = fakeClient.Client
586 clientset.StorageV1beta1().RESTClient().(*restclient.RESTClient).Client = fakeClient.Client
587 clientset.AppsV1beta1().RESTClient().(*restclient.RESTClient).Client = fakeClient.Client
588 clientset.AppsV1beta2().RESTClient().(*restclient.RESTClient).Client = fakeClient.Client
589 clientset.AppsV1().RESTClient().(*restclient.RESTClient).Client = fakeClient.Client
590 clientset.PolicyV1beta1().RESTClient().(*restclient.RESTClient).Client = fakeClient.Client
591 clientset.PolicyV1().RESTClient().(*restclient.RESTClient).Client = fakeClient.Client
592 clientset.DiscoveryClient.RESTClient().(*restclient.RESTClient).Client = fakeClient.Client
593
594 return clientset, nil
595 }
596
597
598 func (f *TestFactory) DynamicClient() (dynamic.Interface, error) {
599 if f.FakeDynamicClient != nil {
600 return f.FakeDynamicClient, nil
601 }
602 return f.Factory.DynamicClient()
603 }
604
605
606 func (f *TestFactory) RESTClient() (*restclient.RESTClient, error) {
607
608 fakeClient := f.Client.(*fake.RESTClient)
609 restClient, err := restclient.RESTClientFor(f.ClientConfigVal)
610 if err != nil {
611 panic(err)
612 }
613 restClient.Client = fakeClient.Client
614 return restClient, nil
615 }
616
617
618 func (f *TestFactory) DiscoveryClient() (discovery.CachedDiscoveryInterface, error) {
619 fakeClient := f.Client.(*fake.RESTClient)
620
621 cacheDir := filepath.Join("", ".kube", "cache", "discovery")
622 cachedClient, err := diskcached.NewCachedDiscoveryClientForConfig(f.ClientConfigVal, cacheDir, "", time.Duration(10*time.Minute))
623 if err != nil {
624 return nil, err
625 }
626 cachedClient.RESTClient().(*restclient.RESTClient).Client = fakeClient.Client
627
628 return cachedClient, nil
629 }
630
631 func testRESTMapper() meta.RESTMapper {
632 groupResources := testDynamicResources()
633 mapper := restmapper.NewDiscoveryRESTMapper(groupResources)
634
635
636 mapper = meta.FirstHitRESTMapper{
637 MultiRESTMapper: meta.MultiRESTMapper{
638 mapper,
639 testrestmapper.TestOnlyStaticRESTMapper(scheme.Scheme),
640 },
641 }
642
643 fakeDs := NewFakeCachedDiscoveryClient()
644 expander := restmapper.NewShortcutExpander(mapper, fakeDs, nil)
645 return expander
646 }
647
648
649 func (f *TestFactory) ScaleClient() (scaleclient.ScalesGetter, error) {
650 return f.ScaleGetter, nil
651 }
652
653 func testDynamicResources() []*restmapper.APIGroupResources {
654 return []*restmapper.APIGroupResources{
655 {
656 Group: metav1.APIGroup{
657 Versions: []metav1.GroupVersionForDiscovery{
658 {Version: "v1"},
659 },
660 PreferredVersion: metav1.GroupVersionForDiscovery{Version: "v1"},
661 },
662 VersionedResources: map[string][]metav1.APIResource{
663 "v1": {
664 {Name: "pods", Namespaced: true, Kind: "Pod"},
665 {Name: "services", Namespaced: true, Kind: "Service"},
666 {Name: "replicationcontrollers", Namespaced: true, Kind: "ReplicationController"},
667 {Name: "componentstatuses", Namespaced: false, Kind: "ComponentStatus"},
668 {Name: "nodes", Namespaced: false, Kind: "Node"},
669 {Name: "secrets", Namespaced: true, Kind: "Secret"},
670 {Name: "configmaps", Namespaced: true, Kind: "ConfigMap"},
671 {Name: "namespacedtype", Namespaced: true, Kind: "NamespacedType"},
672 {Name: "namespaces", Namespaced: false, Kind: "Namespace"},
673 {Name: "resourcequotas", Namespaced: true, Kind: "ResourceQuota"},
674 },
675 },
676 },
677 {
678 Group: metav1.APIGroup{
679 Name: "extensions",
680 Versions: []metav1.GroupVersionForDiscovery{
681 {Version: "v1beta1"},
682 },
683 PreferredVersion: metav1.GroupVersionForDiscovery{Version: "v1beta1"},
684 },
685 VersionedResources: map[string][]metav1.APIResource{
686 "v1beta1": {
687 {Name: "deployments", Namespaced: true, Kind: "Deployment"},
688 {Name: "replicasets", Namespaced: true, Kind: "ReplicaSet"},
689 },
690 },
691 },
692 {
693 Group: metav1.APIGroup{
694 Name: "apps",
695 Versions: []metav1.GroupVersionForDiscovery{
696 {Version: "v1beta1"},
697 {Version: "v1beta2"},
698 {Version: "v1"},
699 },
700 PreferredVersion: metav1.GroupVersionForDiscovery{Version: "v1"},
701 },
702 VersionedResources: map[string][]metav1.APIResource{
703 "v1beta1": {
704 {Name: "deployments", Namespaced: true, Kind: "Deployment"},
705 {Name: "replicasets", Namespaced: true, Kind: "ReplicaSet"},
706 },
707 "v1beta2": {
708 {Name: "deployments", Namespaced: true, Kind: "Deployment"},
709 },
710 "v1": {
711 {Name: "deployments", Namespaced: true, Kind: "Deployment"},
712 {Name: "replicasets", Namespaced: true, Kind: "ReplicaSet"},
713 },
714 },
715 },
716 {
717 Group: metav1.APIGroup{
718 Name: "batch",
719 Versions: []metav1.GroupVersionForDiscovery{
720 {Version: "v1beta1"},
721 {Version: "v1"},
722 },
723 PreferredVersion: metav1.GroupVersionForDiscovery{Version: "v1"},
724 },
725 VersionedResources: map[string][]metav1.APIResource{
726 "v1beta1": {
727 {Name: "cronjobs", Namespaced: true, Kind: "CronJob"},
728 },
729 "v1": {
730 {Name: "jobs", Namespaced: true, Kind: "Job"},
731 },
732 },
733 },
734 {
735 Group: metav1.APIGroup{
736 Name: "autoscaling",
737 Versions: []metav1.GroupVersionForDiscovery{
738 {Version: "v1"},
739 {Version: "v2"},
740 },
741 PreferredVersion: metav1.GroupVersionForDiscovery{Version: "v2"},
742 },
743 VersionedResources: map[string][]metav1.APIResource{
744 "v1": {
745 {Name: "horizontalpodautoscalers", Namespaced: true, Kind: "HorizontalPodAutoscaler"},
746 },
747 "v2": {
748 {Name: "horizontalpodautoscalers", Namespaced: true, Kind: "HorizontalPodAutoscaler"},
749 },
750 },
751 },
752 {
753 Group: metav1.APIGroup{
754 Name: "storage.k8s.io",
755 Versions: []metav1.GroupVersionForDiscovery{
756 {Version: "v1beta1"},
757 {Version: "v0"},
758 },
759 PreferredVersion: metav1.GroupVersionForDiscovery{Version: "v1beta1"},
760 },
761 VersionedResources: map[string][]metav1.APIResource{
762 "v1beta1": {
763 {Name: "storageclasses", Namespaced: false, Kind: "StorageClass"},
764 },
765
766 "v0": {
767 {Name: "storageclasses", Namespaced: false, Kind: "StorageClass"},
768 },
769 },
770 },
771 {
772 Group: metav1.APIGroup{
773 Name: "rbac.authorization.k8s.io",
774 Versions: []metav1.GroupVersionForDiscovery{
775 {Version: "v1beta1"},
776 {Version: "v1"},
777 },
778 PreferredVersion: metav1.GroupVersionForDiscovery{Version: "v1"},
779 },
780 VersionedResources: map[string][]metav1.APIResource{
781 "v1": {
782 {Name: "clusterroles", Namespaced: false, Kind: "ClusterRole"},
783 },
784 "v1beta1": {
785 {Name: "clusterrolebindings", Namespaced: false, Kind: "ClusterRoleBinding"},
786 },
787 },
788 },
789 {
790 Group: metav1.APIGroup{
791 Name: "company.com",
792 Versions: []metav1.GroupVersionForDiscovery{
793 {Version: "v1"},
794 },
795 PreferredVersion: metav1.GroupVersionForDiscovery{Version: "v1"},
796 },
797 VersionedResources: map[string][]metav1.APIResource{
798 "v1": {
799 {Name: "bars", Namespaced: true, Kind: "Bar"},
800 {Name: "applysets", Namespaced: false, Kind: "ApplySet"},
801 },
802 },
803 },
804 {
805 Group: metav1.APIGroup{
806 Name: "unit-test.test.com",
807 Versions: []metav1.GroupVersionForDiscovery{
808 {GroupVersion: "unit-test.test.com/v1", Version: "v1"},
809 },
810 PreferredVersion: metav1.GroupVersionForDiscovery{
811 GroupVersion: "unit-test.test.com/v1",
812 Version: "v1"},
813 },
814 VersionedResources: map[string][]metav1.APIResource{
815 "v1": {
816 {Name: "widgets", Namespaced: true, Kind: "Widget"},
817 },
818 },
819 },
820 {
821 Group: metav1.APIGroup{
822 Name: "apitest",
823 Versions: []metav1.GroupVersionForDiscovery{
824 {GroupVersion: "apitest/unlikelyversion", Version: "unlikelyversion"},
825 },
826 PreferredVersion: metav1.GroupVersionForDiscovery{
827 GroupVersion: "apitest/unlikelyversion",
828 Version: "unlikelyversion"},
829 },
830 VersionedResources: map[string][]metav1.APIResource{
831 "unlikelyversion": {
832 {Name: "types", SingularName: "type", Namespaced: false, Kind: "Type"},
833 },
834 },
835 },
836 }
837 }
838
View as plain text