1
16
17 package unstructured
18
19 import (
20 "bytes"
21 "errors"
22 "fmt"
23
24 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
25 "k8s.io/apimachinery/pkg/runtime"
26 "k8s.io/apimachinery/pkg/runtime/schema"
27 "k8s.io/apimachinery/pkg/types"
28 utilruntime "k8s.io/apimachinery/pkg/util/runtime"
29 )
30
31
32
33
34
35
36
37
38
39
40
41 type Unstructured struct {
42
43
44
45 Object map[string]interface{}
46 }
47
48 var _ metav1.Object = &Unstructured{}
49 var _ runtime.Unstructured = &Unstructured{}
50 var _ metav1.ListInterface = &Unstructured{}
51
52 func (obj *Unstructured) GetObjectKind() schema.ObjectKind { return obj }
53
54 func (obj *Unstructured) IsList() bool {
55 field, ok := obj.Object["items"]
56 if !ok {
57 return false
58 }
59 _, ok = field.([]interface{})
60 return ok
61 }
62 func (obj *Unstructured) ToList() (*UnstructuredList, error) {
63 if !obj.IsList() {
64
65 return &UnstructuredList{Object: obj.Object}, nil
66 }
67
68 ret := &UnstructuredList{}
69 ret.Object = obj.Object
70
71 err := obj.EachListItem(func(item runtime.Object) error {
72 castItem := item.(*Unstructured)
73 ret.Items = append(ret.Items, *castItem)
74 return nil
75 })
76 if err != nil {
77 return nil, err
78 }
79
80 return ret, nil
81 }
82
83 func (obj *Unstructured) EachListItem(fn func(runtime.Object) error) error {
84 field, ok := obj.Object["items"]
85 if !ok {
86 return errors.New("content is not a list")
87 }
88 items, ok := field.([]interface{})
89 if !ok {
90 return fmt.Errorf("content is not a list: %T", field)
91 }
92 for _, item := range items {
93 child, ok := item.(map[string]interface{})
94 if !ok {
95 return fmt.Errorf("items member is not an object: %T", child)
96 }
97 if err := fn(&Unstructured{Object: child}); err != nil {
98 return err
99 }
100 }
101 return nil
102 }
103
104 func (obj *Unstructured) EachListItemWithAlloc(fn func(runtime.Object) error) error {
105
106 return obj.EachListItem(fn)
107 }
108
109 func (obj *Unstructured) UnstructuredContent() map[string]interface{} {
110 if obj.Object == nil {
111 return make(map[string]interface{})
112 }
113 return obj.Object
114 }
115
116 func (obj *Unstructured) SetUnstructuredContent(content map[string]interface{}) {
117 obj.Object = content
118 }
119
120
121
122 func (u *Unstructured) MarshalJSON() ([]byte, error) {
123 var buf bytes.Buffer
124 err := UnstructuredJSONScheme.Encode(u, &buf)
125 return buf.Bytes(), err
126 }
127
128
129
130 func (u *Unstructured) UnmarshalJSON(b []byte) error {
131 _, _, err := UnstructuredJSONScheme.Decode(b, nil, u)
132 return err
133 }
134
135
136
137 func (in *Unstructured) NewEmptyInstance() runtime.Unstructured {
138 out := new(Unstructured)
139 if in != nil {
140 out.GetObjectKind().SetGroupVersionKind(in.GetObjectKind().GroupVersionKind())
141 }
142 return out
143 }
144
145 func (in *Unstructured) DeepCopy() *Unstructured {
146 if in == nil {
147 return nil
148 }
149 out := new(Unstructured)
150 *out = *in
151 out.Object = runtime.DeepCopyJSON(in.Object)
152 return out
153 }
154
155 func (u *Unstructured) setNestedField(value interface{}, fields ...string) {
156 if u.Object == nil {
157 u.Object = make(map[string]interface{})
158 }
159 SetNestedField(u.Object, value, fields...)
160 }
161
162 func (u *Unstructured) setNestedStringSlice(value []string, fields ...string) {
163 if u.Object == nil {
164 u.Object = make(map[string]interface{})
165 }
166 SetNestedStringSlice(u.Object, value, fields...)
167 }
168
169 func (u *Unstructured) setNestedSlice(value []interface{}, fields ...string) {
170 if u.Object == nil {
171 u.Object = make(map[string]interface{})
172 }
173 SetNestedSlice(u.Object, value, fields...)
174 }
175
176 func (u *Unstructured) setNestedMap(value map[string]string, fields ...string) {
177 if u.Object == nil {
178 u.Object = make(map[string]interface{})
179 }
180 SetNestedStringMap(u.Object, value, fields...)
181 }
182
183 func (u *Unstructured) GetOwnerReferences() []metav1.OwnerReference {
184 field, found, err := NestedFieldNoCopy(u.Object, "metadata", "ownerReferences")
185 if !found || err != nil {
186 return nil
187 }
188 original, ok := field.([]interface{})
189 if !ok {
190 return nil
191 }
192 ret := make([]metav1.OwnerReference, 0, len(original))
193 for _, obj := range original {
194 o, ok := obj.(map[string]interface{})
195 if !ok {
196
197 return nil
198 }
199 ret = append(ret, extractOwnerReference(o))
200 }
201 return ret
202 }
203
204 func (u *Unstructured) SetOwnerReferences(references []metav1.OwnerReference) {
205 if references == nil {
206 RemoveNestedField(u.Object, "metadata", "ownerReferences")
207 return
208 }
209
210 newReferences := make([]interface{}, 0, len(references))
211 for _, reference := range references {
212 out, err := runtime.DefaultUnstructuredConverter.ToUnstructured(&reference)
213 if err != nil {
214 utilruntime.HandleError(fmt.Errorf("unable to convert Owner Reference: %v", err))
215 continue
216 }
217 newReferences = append(newReferences, out)
218 }
219 u.setNestedField(newReferences, "metadata", "ownerReferences")
220 }
221
222 func (u *Unstructured) GetAPIVersion() string {
223 return getNestedString(u.Object, "apiVersion")
224 }
225
226 func (u *Unstructured) SetAPIVersion(version string) {
227 u.setNestedField(version, "apiVersion")
228 }
229
230 func (u *Unstructured) GetKind() string {
231 return getNestedString(u.Object, "kind")
232 }
233
234 func (u *Unstructured) SetKind(kind string) {
235 u.setNestedField(kind, "kind")
236 }
237
238 func (u *Unstructured) GetNamespace() string {
239 return getNestedString(u.Object, "metadata", "namespace")
240 }
241
242 func (u *Unstructured) SetNamespace(namespace string) {
243 if len(namespace) == 0 {
244 RemoveNestedField(u.Object, "metadata", "namespace")
245 return
246 }
247 u.setNestedField(namespace, "metadata", "namespace")
248 }
249
250 func (u *Unstructured) GetName() string {
251 return getNestedString(u.Object, "metadata", "name")
252 }
253
254 func (u *Unstructured) SetName(name string) {
255 if len(name) == 0 {
256 RemoveNestedField(u.Object, "metadata", "name")
257 return
258 }
259 u.setNestedField(name, "metadata", "name")
260 }
261
262 func (u *Unstructured) GetGenerateName() string {
263 return getNestedString(u.Object, "metadata", "generateName")
264 }
265
266 func (u *Unstructured) SetGenerateName(generateName string) {
267 if len(generateName) == 0 {
268 RemoveNestedField(u.Object, "metadata", "generateName")
269 return
270 }
271 u.setNestedField(generateName, "metadata", "generateName")
272 }
273
274 func (u *Unstructured) GetUID() types.UID {
275 return types.UID(getNestedString(u.Object, "metadata", "uid"))
276 }
277
278 func (u *Unstructured) SetUID(uid types.UID) {
279 if len(string(uid)) == 0 {
280 RemoveNestedField(u.Object, "metadata", "uid")
281 return
282 }
283 u.setNestedField(string(uid), "metadata", "uid")
284 }
285
286 func (u *Unstructured) GetResourceVersion() string {
287 return getNestedString(u.Object, "metadata", "resourceVersion")
288 }
289
290 func (u *Unstructured) SetResourceVersion(resourceVersion string) {
291 if len(resourceVersion) == 0 {
292 RemoveNestedField(u.Object, "metadata", "resourceVersion")
293 return
294 }
295 u.setNestedField(resourceVersion, "metadata", "resourceVersion")
296 }
297
298 func (u *Unstructured) GetGeneration() int64 {
299 val, found, err := NestedInt64(u.Object, "metadata", "generation")
300 if !found || err != nil {
301 return 0
302 }
303 return val
304 }
305
306 func (u *Unstructured) SetGeneration(generation int64) {
307 if generation == 0 {
308 RemoveNestedField(u.Object, "metadata", "generation")
309 return
310 }
311 u.setNestedField(generation, "metadata", "generation")
312 }
313
314 func (u *Unstructured) GetSelfLink() string {
315 return getNestedString(u.Object, "metadata", "selfLink")
316 }
317
318 func (u *Unstructured) SetSelfLink(selfLink string) {
319 if len(selfLink) == 0 {
320 RemoveNestedField(u.Object, "metadata", "selfLink")
321 return
322 }
323 u.setNestedField(selfLink, "metadata", "selfLink")
324 }
325
326 func (u *Unstructured) GetContinue() string {
327 return getNestedString(u.Object, "metadata", "continue")
328 }
329
330 func (u *Unstructured) SetContinue(c string) {
331 if len(c) == 0 {
332 RemoveNestedField(u.Object, "metadata", "continue")
333 return
334 }
335 u.setNestedField(c, "metadata", "continue")
336 }
337
338 func (u *Unstructured) GetRemainingItemCount() *int64 {
339 return getNestedInt64Pointer(u.Object, "metadata", "remainingItemCount")
340 }
341
342 func (u *Unstructured) SetRemainingItemCount(c *int64) {
343 if c == nil {
344 RemoveNestedField(u.Object, "metadata", "remainingItemCount")
345 } else {
346 u.setNestedField(*c, "metadata", "remainingItemCount")
347 }
348 }
349
350 func (u *Unstructured) GetCreationTimestamp() metav1.Time {
351 var timestamp metav1.Time
352 timestamp.UnmarshalQueryParameter(getNestedString(u.Object, "metadata", "creationTimestamp"))
353 return timestamp
354 }
355
356 func (u *Unstructured) SetCreationTimestamp(timestamp metav1.Time) {
357 ts, _ := timestamp.MarshalQueryParameter()
358 if len(ts) == 0 || timestamp.Time.IsZero() {
359 RemoveNestedField(u.Object, "metadata", "creationTimestamp")
360 return
361 }
362 u.setNestedField(ts, "metadata", "creationTimestamp")
363 }
364
365 func (u *Unstructured) GetDeletionTimestamp() *metav1.Time {
366 var timestamp metav1.Time
367 timestamp.UnmarshalQueryParameter(getNestedString(u.Object, "metadata", "deletionTimestamp"))
368 if timestamp.IsZero() {
369 return nil
370 }
371 return ×tamp
372 }
373
374 func (u *Unstructured) SetDeletionTimestamp(timestamp *metav1.Time) {
375 if timestamp == nil {
376 RemoveNestedField(u.Object, "metadata", "deletionTimestamp")
377 return
378 }
379 ts, _ := timestamp.MarshalQueryParameter()
380 u.setNestedField(ts, "metadata", "deletionTimestamp")
381 }
382
383 func (u *Unstructured) GetDeletionGracePeriodSeconds() *int64 {
384 val, found, err := NestedInt64(u.Object, "metadata", "deletionGracePeriodSeconds")
385 if !found || err != nil {
386 return nil
387 }
388 return &val
389 }
390
391 func (u *Unstructured) SetDeletionGracePeriodSeconds(deletionGracePeriodSeconds *int64) {
392 if deletionGracePeriodSeconds == nil {
393 RemoveNestedField(u.Object, "metadata", "deletionGracePeriodSeconds")
394 return
395 }
396 u.setNestedField(*deletionGracePeriodSeconds, "metadata", "deletionGracePeriodSeconds")
397 }
398
399 func (u *Unstructured) GetLabels() map[string]string {
400 m, _, _ := NestedStringMap(u.Object, "metadata", "labels")
401 return m
402 }
403
404 func (u *Unstructured) SetLabels(labels map[string]string) {
405 if labels == nil {
406 RemoveNestedField(u.Object, "metadata", "labels")
407 return
408 }
409 u.setNestedMap(labels, "metadata", "labels")
410 }
411
412 func (u *Unstructured) GetAnnotations() map[string]string {
413 m, _, _ := NestedStringMap(u.Object, "metadata", "annotations")
414 return m
415 }
416
417 func (u *Unstructured) SetAnnotations(annotations map[string]string) {
418 if annotations == nil {
419 RemoveNestedField(u.Object, "metadata", "annotations")
420 return
421 }
422 u.setNestedMap(annotations, "metadata", "annotations")
423 }
424
425 func (u *Unstructured) SetGroupVersionKind(gvk schema.GroupVersionKind) {
426 u.SetAPIVersion(gvk.GroupVersion().String())
427 u.SetKind(gvk.Kind)
428 }
429
430 func (u *Unstructured) GroupVersionKind() schema.GroupVersionKind {
431 gv, err := schema.ParseGroupVersion(u.GetAPIVersion())
432 if err != nil {
433 return schema.GroupVersionKind{}
434 }
435 gvk := gv.WithKind(u.GetKind())
436 return gvk
437 }
438
439 func (u *Unstructured) GetFinalizers() []string {
440 val, _, _ := NestedStringSlice(u.Object, "metadata", "finalizers")
441 return val
442 }
443
444 func (u *Unstructured) SetFinalizers(finalizers []string) {
445 if finalizers == nil {
446 RemoveNestedField(u.Object, "metadata", "finalizers")
447 return
448 }
449 u.setNestedStringSlice(finalizers, "metadata", "finalizers")
450 }
451
452 func (u *Unstructured) GetManagedFields() []metav1.ManagedFieldsEntry {
453 items, found, err := NestedSlice(u.Object, "metadata", "managedFields")
454 if !found || err != nil {
455 return nil
456 }
457 managedFields := []metav1.ManagedFieldsEntry{}
458 for _, item := range items {
459 m, ok := item.(map[string]interface{})
460 if !ok {
461 utilruntime.HandleError(fmt.Errorf("unable to retrieve managedFields for object, item %v is not a map", item))
462 return nil
463 }
464 out := metav1.ManagedFieldsEntry{}
465 if err := runtime.DefaultUnstructuredConverter.FromUnstructured(m, &out); err != nil {
466 utilruntime.HandleError(fmt.Errorf("unable to retrieve managedFields for object: %v", err))
467 return nil
468 }
469 managedFields = append(managedFields, out)
470 }
471 return managedFields
472 }
473
474 func (u *Unstructured) SetManagedFields(managedFields []metav1.ManagedFieldsEntry) {
475 if managedFields == nil {
476 RemoveNestedField(u.Object, "metadata", "managedFields")
477 return
478 }
479 items := []interface{}{}
480 for _, managedFieldsEntry := range managedFields {
481 out, err := runtime.DefaultUnstructuredConverter.ToUnstructured(&managedFieldsEntry)
482 if err != nil {
483 utilruntime.HandleError(fmt.Errorf("unable to set managedFields for object: %v", err))
484 return
485 }
486 items = append(items, out)
487 }
488 u.setNestedSlice(items, "metadata", "managedFields")
489 }
490
View as plain text