1
16
17 package client
18
19 import (
20 "context"
21 "fmt"
22 "strings"
23
24 "k8s.io/apimachinery/pkg/runtime"
25 )
26
27 var _ Reader = &unstructuredClient{}
28 var _ Writer = &unstructuredClient{}
29
30 type unstructuredClient struct {
31 resources *clientRestResources
32 paramCodec runtime.ParameterCodec
33 }
34
35
36 func (uc *unstructuredClient) Create(ctx context.Context, obj Object, opts ...CreateOption) error {
37 u, ok := obj.(runtime.Unstructured)
38 if !ok {
39 return fmt.Errorf("unstructured client did not understand object: %T", obj)
40 }
41
42 gvk := u.GetObjectKind().GroupVersionKind()
43
44 o, err := uc.resources.getObjMeta(obj)
45 if err != nil {
46 return err
47 }
48
49 createOpts := &CreateOptions{}
50 createOpts.ApplyOptions(opts)
51
52 result := o.Post().
53 NamespaceIfScoped(o.GetNamespace(), o.isNamespaced()).
54 Resource(o.resource()).
55 Body(obj).
56 VersionedParams(createOpts.AsCreateOptions(), uc.paramCodec).
57 Do(ctx).
58 Into(obj)
59
60 u.GetObjectKind().SetGroupVersionKind(gvk)
61 return result
62 }
63
64
65 func (uc *unstructuredClient) Update(ctx context.Context, obj Object, opts ...UpdateOption) error {
66 u, ok := obj.(runtime.Unstructured)
67 if !ok {
68 return fmt.Errorf("unstructured client did not understand object: %T", obj)
69 }
70
71 gvk := u.GetObjectKind().GroupVersionKind()
72
73 o, err := uc.resources.getObjMeta(obj)
74 if err != nil {
75 return err
76 }
77
78 updateOpts := UpdateOptions{}
79 updateOpts.ApplyOptions(opts)
80
81 result := o.Put().
82 NamespaceIfScoped(o.GetNamespace(), o.isNamespaced()).
83 Resource(o.resource()).
84 Name(o.GetName()).
85 Body(obj).
86 VersionedParams(updateOpts.AsUpdateOptions(), uc.paramCodec).
87 Do(ctx).
88 Into(obj)
89
90 u.GetObjectKind().SetGroupVersionKind(gvk)
91 return result
92 }
93
94
95 func (uc *unstructuredClient) Delete(ctx context.Context, obj Object, opts ...DeleteOption) error {
96 if _, ok := obj.(runtime.Unstructured); !ok {
97 return fmt.Errorf("unstructured client did not understand object: %T", obj)
98 }
99
100 o, err := uc.resources.getObjMeta(obj)
101 if err != nil {
102 return err
103 }
104
105 deleteOpts := DeleteOptions{}
106 deleteOpts.ApplyOptions(opts)
107
108 return o.Delete().
109 NamespaceIfScoped(o.GetNamespace(), o.isNamespaced()).
110 Resource(o.resource()).
111 Name(o.GetName()).
112 Body(deleteOpts.AsDeleteOptions()).
113 Do(ctx).
114 Error()
115 }
116
117
118 func (uc *unstructuredClient) DeleteAllOf(ctx context.Context, obj Object, opts ...DeleteAllOfOption) error {
119 if _, ok := obj.(runtime.Unstructured); !ok {
120 return fmt.Errorf("unstructured client did not understand object: %T", obj)
121 }
122
123 o, err := uc.resources.getObjMeta(obj)
124 if err != nil {
125 return err
126 }
127
128 deleteAllOfOpts := DeleteAllOfOptions{}
129 deleteAllOfOpts.ApplyOptions(opts)
130
131 return o.Delete().
132 NamespaceIfScoped(deleteAllOfOpts.ListOptions.Namespace, o.isNamespaced()).
133 Resource(o.resource()).
134 VersionedParams(deleteAllOfOpts.AsListOptions(), uc.paramCodec).
135 Body(deleteAllOfOpts.AsDeleteOptions()).
136 Do(ctx).
137 Error()
138 }
139
140
141 func (uc *unstructuredClient) Patch(ctx context.Context, obj Object, patch Patch, opts ...PatchOption) error {
142 if _, ok := obj.(runtime.Unstructured); !ok {
143 return fmt.Errorf("unstructured client did not understand object: %T", obj)
144 }
145
146 o, err := uc.resources.getObjMeta(obj)
147 if err != nil {
148 return err
149 }
150
151 data, err := patch.Data(obj)
152 if err != nil {
153 return err
154 }
155
156 patchOpts := &PatchOptions{}
157 patchOpts.ApplyOptions(opts)
158
159 return o.Patch(patch.Type()).
160 NamespaceIfScoped(o.GetNamespace(), o.isNamespaced()).
161 Resource(o.resource()).
162 Name(o.GetName()).
163 VersionedParams(patchOpts.AsPatchOptions(), uc.paramCodec).
164 Body(data).
165 Do(ctx).
166 Into(obj)
167 }
168
169
170 func (uc *unstructuredClient) Get(ctx context.Context, key ObjectKey, obj Object, opts ...GetOption) error {
171 u, ok := obj.(runtime.Unstructured)
172 if !ok {
173 return fmt.Errorf("unstructured client did not understand object: %T", obj)
174 }
175
176 gvk := u.GetObjectKind().GroupVersionKind()
177
178 getOpts := GetOptions{}
179 getOpts.ApplyOptions(opts)
180
181 r, err := uc.resources.getResource(obj)
182 if err != nil {
183 return err
184 }
185
186 result := r.Get().
187 NamespaceIfScoped(key.Namespace, r.isNamespaced()).
188 Resource(r.resource()).
189 VersionedParams(getOpts.AsGetOptions(), uc.paramCodec).
190 Name(key.Name).
191 Do(ctx).
192 Into(obj)
193
194 u.GetObjectKind().SetGroupVersionKind(gvk)
195
196 return result
197 }
198
199
200 func (uc *unstructuredClient) List(ctx context.Context, obj ObjectList, opts ...ListOption) error {
201 u, ok := obj.(runtime.Unstructured)
202 if !ok {
203 return fmt.Errorf("unstructured client did not understand object: %T", obj)
204 }
205
206 gvk := u.GetObjectKind().GroupVersionKind()
207 gvk.Kind = strings.TrimSuffix(gvk.Kind, "List")
208
209 r, err := uc.resources.getResource(obj)
210 if err != nil {
211 return err
212 }
213
214 listOpts := ListOptions{}
215 listOpts.ApplyOptions(opts)
216
217 return r.Get().
218 NamespaceIfScoped(listOpts.Namespace, r.isNamespaced()).
219 Resource(r.resource()).
220 VersionedParams(listOpts.AsListOptions(), uc.paramCodec).
221 Do(ctx).
222 Into(obj)
223 }
224
225 func (uc *unstructuredClient) GetSubResource(ctx context.Context, obj, subResourceObj Object, subResource string, opts ...SubResourceGetOption) error {
226 if _, ok := obj.(runtime.Unstructured); !ok {
227 return fmt.Errorf("unstructured client did not understand object: %T", obj)
228 }
229
230 if _, ok := subResourceObj.(runtime.Unstructured); !ok {
231 return fmt.Errorf("unstructured client did not understand object: %T", subResourceObj)
232 }
233
234 if subResourceObj.GetName() == "" {
235 subResourceObj.SetName(obj.GetName())
236 }
237
238 o, err := uc.resources.getObjMeta(obj)
239 if err != nil {
240 return err
241 }
242
243 getOpts := &SubResourceGetOptions{}
244 getOpts.ApplyOptions(opts)
245
246 return o.Get().
247 NamespaceIfScoped(o.GetNamespace(), o.isNamespaced()).
248 Resource(o.resource()).
249 Name(o.GetName()).
250 SubResource(subResource).
251 VersionedParams(getOpts.AsGetOptions(), uc.paramCodec).
252 Do(ctx).
253 Into(subResourceObj)
254 }
255
256 func (uc *unstructuredClient) CreateSubResource(ctx context.Context, obj, subResourceObj Object, subResource string, opts ...SubResourceCreateOption) error {
257 if _, ok := obj.(runtime.Unstructured); !ok {
258 return fmt.Errorf("unstructured client did not understand object: %T", obj)
259 }
260
261 if _, ok := subResourceObj.(runtime.Unstructured); !ok {
262 return fmt.Errorf("unstructured client did not understand object: %T", subResourceObj)
263 }
264
265 if subResourceObj.GetName() == "" {
266 subResourceObj.SetName(obj.GetName())
267 }
268
269 o, err := uc.resources.getObjMeta(obj)
270 if err != nil {
271 return err
272 }
273
274 createOpts := &SubResourceCreateOptions{}
275 createOpts.ApplyOptions(opts)
276
277 return o.Post().
278 NamespaceIfScoped(o.GetNamespace(), o.isNamespaced()).
279 Resource(o.resource()).
280 Name(o.GetName()).
281 SubResource(subResource).
282 Body(subResourceObj).
283 VersionedParams(createOpts.AsCreateOptions(), uc.paramCodec).
284 Do(ctx).
285 Into(subResourceObj)
286 }
287
288 func (uc *unstructuredClient) UpdateSubResource(ctx context.Context, obj Object, subResource string, opts ...SubResourceUpdateOption) error {
289 if _, ok := obj.(runtime.Unstructured); !ok {
290 return fmt.Errorf("unstructured client did not understand object: %T", obj)
291 }
292
293 o, err := uc.resources.getObjMeta(obj)
294 if err != nil {
295 return err
296 }
297
298 updateOpts := SubResourceUpdateOptions{}
299 updateOpts.ApplyOptions(opts)
300
301 body := obj
302 if updateOpts.SubResourceBody != nil {
303 body = updateOpts.SubResourceBody
304 }
305 if body.GetName() == "" {
306 body.SetName(obj.GetName())
307 }
308 if body.GetNamespace() == "" {
309 body.SetNamespace(obj.GetNamespace())
310 }
311
312 return o.Put().
313 NamespaceIfScoped(o.GetNamespace(), o.isNamespaced()).
314 Resource(o.resource()).
315 Name(o.GetName()).
316 SubResource(subResource).
317 Body(body).
318 VersionedParams(updateOpts.AsUpdateOptions(), uc.paramCodec).
319 Do(ctx).
320 Into(body)
321 }
322
323 func (uc *unstructuredClient) PatchSubResource(ctx context.Context, obj Object, subResource string, patch Patch, opts ...SubResourcePatchOption) error {
324 u, ok := obj.(runtime.Unstructured)
325 if !ok {
326 return fmt.Errorf("unstructured client did not understand object: %T", obj)
327 }
328
329 gvk := u.GetObjectKind().GroupVersionKind()
330
331 o, err := uc.resources.getObjMeta(obj)
332 if err != nil {
333 return err
334 }
335
336 patchOpts := &SubResourcePatchOptions{}
337 patchOpts.ApplyOptions(opts)
338
339 body := obj
340 if patchOpts.SubResourceBody != nil {
341 body = patchOpts.SubResourceBody
342 }
343
344 data, err := patch.Data(body)
345 if err != nil {
346 return err
347 }
348
349 result := o.Patch(patch.Type()).
350 NamespaceIfScoped(o.GetNamespace(), o.isNamespaced()).
351 Resource(o.resource()).
352 Name(o.GetName()).
353 SubResource(subResource).
354 Body(data).
355 VersionedParams(patchOpts.AsPatchOptions(), uc.paramCodec).
356 Do(ctx).
357 Into(body)
358
359 u.GetObjectKind().SetGroupVersionKind(gvk)
360 return result
361 }
362
View as plain text