2 Copyright 2018 The Kubernetes Authors.
4 Licensed under the Apache License, Version 2.0 (the "License");
5 you may not use this file except in compliance with the License.
6 You may obtain a copy of the License at
8 http://www.apache.org/licenses/LICENSE-2.0
10 Unless required by applicable law or agreed to in writing, software
11 distributed under the License is distributed on an "AS IS" BASIS,
12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 See the License for the specific language governing permissions and
14 limitations under the License.
22 "k8s.io/apimachinery/pkg/api/meta"
23 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
24 "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
25 "k8s.io/apimachinery/pkg/labels"
26 "k8s.io/apimachinery/pkg/runtime"
27 "k8s.io/apimachinery/pkg/runtime/schema"
28 "k8s.io/apimachinery/pkg/runtime/serializer"
29 "k8s.io/apimachinery/pkg/types"
30 "k8s.io/apimachinery/pkg/watch"
31 "k8s.io/client-go/dynamic"
32 "k8s.io/client-go/testing"
35 func NewSimpleDynamicClient(scheme *runtime.Scheme, objects ...runtime.Object) *FakeDynamicClient {
36 // In order to use List with this client, you have to have the v1.List registered in your scheme. Neat thing though
37 // it does NOT have to be the *same* list
38 scheme.AddKnownTypeWithName(schema.GroupVersionKind{Group: "fake-dynamic-client-group", Version: "v1", Kind: "List"}, &unstructured.UnstructuredList{})
40 codecs := serializer.NewCodecFactory(scheme)
41 o := testing.NewObjectTracker(scheme, codecs.UniversalDecoder())
42 for _, obj := range objects {
43 if err := o.Add(obj); err != nil {
48 cs := &FakeDynamicClient{scheme: scheme}
49 cs.AddReactor("*", "*", testing.ObjectReaction(o))
50 cs.AddWatchReactor("*", func(action testing.Action) (handled bool, ret watch.Interface, err error) {
51 gvr := action.GetResource()
52 ns := action.GetNamespace()
53 watch, err := o.Watch(gvr, ns)
55 return false, nil, err
57 return true, watch, nil
63 // Clientset implements clientset.Interface. Meant to be embedded into a
64 // struct to get a default implementation. This makes faking out just the method
65 // you want to test easier.
66 type FakeDynamicClient struct {
68 scheme *runtime.Scheme
71 type dynamicResourceClient struct {
72 client *FakeDynamicClient
74 resource schema.GroupVersionResource
77 var _ dynamic.Interface = &FakeDynamicClient{}
79 func (c *FakeDynamicClient) Resource(resource schema.GroupVersionResource) dynamic.NamespaceableResourceInterface {
80 return &dynamicResourceClient{client: c, resource: resource}
83 func (c *dynamicResourceClient) Namespace(ns string) dynamic.ResourceInterface {
89 func (c *dynamicResourceClient) Create(obj *unstructured.Unstructured, opts metav1.CreateOptions, subresources ...string) (*unstructured.Unstructured, error) {
90 var uncastRet runtime.Object
93 case len(c.namespace) == 0 && len(subresources) == 0:
94 uncastRet, err = c.client.Fake.
95 Invokes(testing.NewRootCreateAction(c.resource, obj), obj)
97 case len(c.namespace) == 0 && len(subresources) > 0:
98 accessor, err := meta.Accessor(obj)
102 name := accessor.GetName()
103 uncastRet, err = c.client.Fake.
104 Invokes(testing.NewRootCreateSubresourceAction(c.resource, name, strings.Join(subresources, "/"), obj), obj)
106 case len(c.namespace) > 0 && len(subresources) == 0:
107 uncastRet, err = c.client.Fake.
108 Invokes(testing.NewCreateAction(c.resource, c.namespace, obj), obj)
110 case len(c.namespace) > 0 && len(subresources) > 0:
111 accessor, err := meta.Accessor(obj)
115 name := accessor.GetName()
116 uncastRet, err = c.client.Fake.
117 Invokes(testing.NewCreateSubresourceAction(c.resource, name, strings.Join(subresources, "/"), c.namespace, obj), obj)
124 if uncastRet == nil {
128 ret := &unstructured.Unstructured{}
129 if err := c.client.scheme.Convert(uncastRet, ret, nil); err != nil {
135 func (c *dynamicResourceClient) Update(obj *unstructured.Unstructured, opts metav1.UpdateOptions, subresources ...string) (*unstructured.Unstructured, error) {
136 var uncastRet runtime.Object
139 case len(c.namespace) == 0 && len(subresources) == 0:
140 uncastRet, err = c.client.Fake.
141 Invokes(testing.NewRootUpdateAction(c.resource, obj), obj)
143 case len(c.namespace) == 0 && len(subresources) > 0:
144 uncastRet, err = c.client.Fake.
145 Invokes(testing.NewRootUpdateSubresourceAction(c.resource, strings.Join(subresources, "/"), obj), obj)
147 case len(c.namespace) > 0 && len(subresources) == 0:
148 uncastRet, err = c.client.Fake.
149 Invokes(testing.NewUpdateAction(c.resource, c.namespace, obj), obj)
151 case len(c.namespace) > 0 && len(subresources) > 0:
152 uncastRet, err = c.client.Fake.
153 Invokes(testing.NewUpdateSubresourceAction(c.resource, strings.Join(subresources, "/"), c.namespace, obj), obj)
160 if uncastRet == nil {
164 ret := &unstructured.Unstructured{}
165 if err := c.client.scheme.Convert(uncastRet, ret, nil); err != nil {
171 func (c *dynamicResourceClient) UpdateStatus(obj *unstructured.Unstructured, opts metav1.UpdateOptions) (*unstructured.Unstructured, error) {
172 var uncastRet runtime.Object
175 case len(c.namespace) == 0:
176 uncastRet, err = c.client.Fake.
177 Invokes(testing.NewRootUpdateSubresourceAction(c.resource, "status", obj), obj)
179 case len(c.namespace) > 0:
180 uncastRet, err = c.client.Fake.
181 Invokes(testing.NewUpdateSubresourceAction(c.resource, "status", c.namespace, obj), obj)
188 if uncastRet == nil {
192 ret := &unstructured.Unstructured{}
193 if err := c.client.scheme.Convert(uncastRet, ret, nil); err != nil {
199 func (c *dynamicResourceClient) Delete(name string, opts *metav1.DeleteOptions, subresources ...string) error {
202 case len(c.namespace) == 0 && len(subresources) == 0:
203 _, err = c.client.Fake.
204 Invokes(testing.NewRootDeleteAction(c.resource, name), &metav1.Status{Status: "dynamic delete fail"})
206 case len(c.namespace) == 0 && len(subresources) > 0:
207 _, err = c.client.Fake.
208 Invokes(testing.NewRootDeleteSubresourceAction(c.resource, strings.Join(subresources, "/"), name), &metav1.Status{Status: "dynamic delete fail"})
210 case len(c.namespace) > 0 && len(subresources) == 0:
211 _, err = c.client.Fake.
212 Invokes(testing.NewDeleteAction(c.resource, c.namespace, name), &metav1.Status{Status: "dynamic delete fail"})
214 case len(c.namespace) > 0 && len(subresources) > 0:
215 _, err = c.client.Fake.
216 Invokes(testing.NewDeleteSubresourceAction(c.resource, strings.Join(subresources, "/"), c.namespace, name), &metav1.Status{Status: "dynamic delete fail"})
222 func (c *dynamicResourceClient) DeleteCollection(opts *metav1.DeleteOptions, listOptions metav1.ListOptions) error {
225 case len(c.namespace) == 0:
226 action := testing.NewRootDeleteCollectionAction(c.resource, listOptions)
227 _, err = c.client.Fake.Invokes(action, &metav1.Status{Status: "dynamic deletecollection fail"})
229 case len(c.namespace) > 0:
230 action := testing.NewDeleteCollectionAction(c.resource, c.namespace, listOptions)
231 _, err = c.client.Fake.Invokes(action, &metav1.Status{Status: "dynamic deletecollection fail"})
238 func (c *dynamicResourceClient) Get(name string, opts metav1.GetOptions, subresources ...string) (*unstructured.Unstructured, error) {
239 var uncastRet runtime.Object
242 case len(c.namespace) == 0 && len(subresources) == 0:
243 uncastRet, err = c.client.Fake.
244 Invokes(testing.NewRootGetAction(c.resource, name), &metav1.Status{Status: "dynamic get fail"})
246 case len(c.namespace) == 0 && len(subresources) > 0:
247 uncastRet, err = c.client.Fake.
248 Invokes(testing.NewRootGetSubresourceAction(c.resource, strings.Join(subresources, "/"), name), &metav1.Status{Status: "dynamic get fail"})
250 case len(c.namespace) > 0 && len(subresources) == 0:
251 uncastRet, err = c.client.Fake.
252 Invokes(testing.NewGetAction(c.resource, c.namespace, name), &metav1.Status{Status: "dynamic get fail"})
254 case len(c.namespace) > 0 && len(subresources) > 0:
255 uncastRet, err = c.client.Fake.
256 Invokes(testing.NewGetSubresourceAction(c.resource, c.namespace, strings.Join(subresources, "/"), name), &metav1.Status{Status: "dynamic get fail"})
262 if uncastRet == nil {
266 ret := &unstructured.Unstructured{}
267 if err := c.client.scheme.Convert(uncastRet, ret, nil); err != nil {
273 func (c *dynamicResourceClient) List(opts metav1.ListOptions) (*unstructured.UnstructuredList, error) {
274 var obj runtime.Object
277 case len(c.namespace) == 0:
278 obj, err = c.client.Fake.
279 Invokes(testing.NewRootListAction(c.resource, schema.GroupVersionKind{Group: "fake-dynamic-client-group", Version: "v1", Kind: "" /*List is appended by the tracker automatically*/}, opts), &metav1.Status{Status: "dynamic list fail"})
281 case len(c.namespace) > 0:
282 obj, err = c.client.Fake.
283 Invokes(testing.NewListAction(c.resource, schema.GroupVersionKind{Group: "fake-dynamic-client-group", Version: "v1", Kind: "" /*List is appended by the tracker automatically*/}, c.namespace, opts), &metav1.Status{Status: "dynamic list fail"})
291 label, _, _ := testing.ExtractFromListOptions(opts)
293 label = labels.Everything()
296 retUnstructured := &unstructured.Unstructured{}
297 if err := c.client.scheme.Convert(obj, retUnstructured, nil); err != nil {
300 entireList, err := retUnstructured.ToList()
305 list := &unstructured.UnstructuredList{}
306 list.SetResourceVersion(entireList.GetResourceVersion())
307 for i := range entireList.Items {
308 item := &entireList.Items[i]
309 metadata, err := meta.Accessor(item)
313 if label.Matches(labels.Set(metadata.GetLabels())) {
314 list.Items = append(list.Items, *item)
320 func (c *dynamicResourceClient) Watch(opts metav1.ListOptions) (watch.Interface, error) {
322 case len(c.namespace) == 0:
323 return c.client.Fake.
324 InvokesWatch(testing.NewRootWatchAction(c.resource, opts))
326 case len(c.namespace) > 0:
327 return c.client.Fake.
328 InvokesWatch(testing.NewWatchAction(c.resource, c.namespace, opts))
335 // TODO: opts are currently ignored.
336 func (c *dynamicResourceClient) Patch(name string, pt types.PatchType, data []byte, opts metav1.UpdateOptions, subresources ...string) (*unstructured.Unstructured, error) {
337 var uncastRet runtime.Object
340 case len(c.namespace) == 0 && len(subresources) == 0:
341 uncastRet, err = c.client.Fake.
342 Invokes(testing.NewRootPatchAction(c.resource, name, pt, data), &metav1.Status{Status: "dynamic patch fail"})
344 case len(c.namespace) == 0 && len(subresources) > 0:
345 uncastRet, err = c.client.Fake.
346 Invokes(testing.NewRootPatchSubresourceAction(c.resource, name, pt, data, subresources...), &metav1.Status{Status: "dynamic patch fail"})
348 case len(c.namespace) > 0 && len(subresources) == 0:
349 uncastRet, err = c.client.Fake.
350 Invokes(testing.NewPatchAction(c.resource, c.namespace, name, pt, data), &metav1.Status{Status: "dynamic patch fail"})
352 case len(c.namespace) > 0 && len(subresources) > 0:
353 uncastRet, err = c.client.Fake.
354 Invokes(testing.NewPatchSubresourceAction(c.resource, c.namespace, name, pt, data, subresources...), &metav1.Status{Status: "dynamic patch fail"})
361 if uncastRet == nil {
365 ret := &unstructured.Unstructured{}
366 if err := c.client.scheme.Convert(uncastRet, ret, nil); err != nil {