github.com/spotmaxtech/k8s-apimachinery-v0260@v0.0.1/pkg/apis/meta/v1/unstructured/unstructured.go (about) 1 /* 2 Copyright 2015 The Kubernetes Authors. 3 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 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 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. 15 */ 16 17 package unstructured 18 19 import ( 20 "bytes" 21 "errors" 22 "fmt" 23 24 metav1 "github.com/spotmaxtech/k8s-apimachinery-v0260/pkg/apis/meta/v1" 25 "github.com/spotmaxtech/k8s-apimachinery-v0260/pkg/runtime" 26 "github.com/spotmaxtech/k8s-apimachinery-v0260/pkg/runtime/schema" 27 "github.com/spotmaxtech/k8s-apimachinery-v0260/pkg/types" 28 utilruntime "github.com/spotmaxtech/k8s-apimachinery-v0260/pkg/util/runtime" 29 ) 30 31 // Unstructured allows objects that do not have Golang structs registered to be manipulated 32 // generically. This can be used to deal with the API objects from a plug-in. Unstructured 33 // objects still have functioning TypeMeta features-- kind, version, etc. 34 // 35 // WARNING: This object has accessors for the v1 standard metadata. You *MUST NOT* use this 36 // type if you are dealing with objects that are not in the server meta v1 schema. 37 // 38 // TODO: make the serialization part of this type distinct from the field accessors. 39 // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object 40 // +k8s:deepcopy-gen=true 41 type Unstructured struct { 42 // Object is a JSON compatible map with string, float, int, bool, []interface{}, or 43 // map[string]interface{} 44 // children. 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 // return an empty list back 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) UnstructuredContent() map[string]interface{} { 105 if obj.Object == nil { 106 return make(map[string]interface{}) 107 } 108 return obj.Object 109 } 110 111 func (obj *Unstructured) SetUnstructuredContent(content map[string]interface{}) { 112 obj.Object = content 113 } 114 115 // MarshalJSON ensures that the unstructured object produces proper 116 // JSON when passed to Go's standard JSON library. 117 func (u *Unstructured) MarshalJSON() ([]byte, error) { 118 var buf bytes.Buffer 119 err := UnstructuredJSONScheme.Encode(u, &buf) 120 return buf.Bytes(), err 121 } 122 123 // UnmarshalJSON ensures that the unstructured object properly decodes 124 // JSON when passed to Go's standard JSON library. 125 func (u *Unstructured) UnmarshalJSON(b []byte) error { 126 _, _, err := UnstructuredJSONScheme.Decode(b, nil, u) 127 return err 128 } 129 130 // NewEmptyInstance returns a new instance of the concrete type containing only kind/apiVersion and no other data. 131 // This should be called instead of reflect.New() for unstructured types because the go type alone does not preserve kind/apiVersion info. 132 func (in *Unstructured) NewEmptyInstance() runtime.Unstructured { 133 out := new(Unstructured) 134 if in != nil { 135 out.GetObjectKind().SetGroupVersionKind(in.GetObjectKind().GroupVersionKind()) 136 } 137 return out 138 } 139 140 func (in *Unstructured) DeepCopy() *Unstructured { 141 if in == nil { 142 return nil 143 } 144 out := new(Unstructured) 145 *out = *in 146 out.Object = runtime.DeepCopyJSON(in.Object) 147 return out 148 } 149 150 func (u *Unstructured) setNestedField(value interface{}, fields ...string) { 151 if u.Object == nil { 152 u.Object = make(map[string]interface{}) 153 } 154 SetNestedField(u.Object, value, fields...) 155 } 156 157 func (u *Unstructured) setNestedStringSlice(value []string, fields ...string) { 158 if u.Object == nil { 159 u.Object = make(map[string]interface{}) 160 } 161 SetNestedStringSlice(u.Object, value, fields...) 162 } 163 164 func (u *Unstructured) setNestedSlice(value []interface{}, fields ...string) { 165 if u.Object == nil { 166 u.Object = make(map[string]interface{}) 167 } 168 SetNestedSlice(u.Object, value, fields...) 169 } 170 171 func (u *Unstructured) setNestedMap(value map[string]string, fields ...string) { 172 if u.Object == nil { 173 u.Object = make(map[string]interface{}) 174 } 175 SetNestedStringMap(u.Object, value, fields...) 176 } 177 178 func (u *Unstructured) GetOwnerReferences() []metav1.OwnerReference { 179 field, found, err := NestedFieldNoCopy(u.Object, "metadata", "ownerReferences") 180 if !found || err != nil { 181 return nil 182 } 183 original, ok := field.([]interface{}) 184 if !ok { 185 return nil 186 } 187 ret := make([]metav1.OwnerReference, 0, len(original)) 188 for _, obj := range original { 189 o, ok := obj.(map[string]interface{}) 190 if !ok { 191 // expected map[string]interface{}, got something else 192 return nil 193 } 194 ret = append(ret, extractOwnerReference(o)) 195 } 196 return ret 197 } 198 199 func (u *Unstructured) SetOwnerReferences(references []metav1.OwnerReference) { 200 if references == nil { 201 RemoveNestedField(u.Object, "metadata", "ownerReferences") 202 return 203 } 204 205 newReferences := make([]interface{}, 0, len(references)) 206 for _, reference := range references { 207 out, err := runtime.DefaultUnstructuredConverter.ToUnstructured(&reference) 208 if err != nil { 209 utilruntime.HandleError(fmt.Errorf("unable to convert Owner Reference: %v", err)) 210 continue 211 } 212 newReferences = append(newReferences, out) 213 } 214 u.setNestedField(newReferences, "metadata", "ownerReferences") 215 } 216 217 func (u *Unstructured) GetAPIVersion() string { 218 return getNestedString(u.Object, "apiVersion") 219 } 220 221 func (u *Unstructured) SetAPIVersion(version string) { 222 u.setNestedField(version, "apiVersion") 223 } 224 225 func (u *Unstructured) GetKind() string { 226 return getNestedString(u.Object, "kind") 227 } 228 229 func (u *Unstructured) SetKind(kind string) { 230 u.setNestedField(kind, "kind") 231 } 232 233 func (u *Unstructured) GetNamespace() string { 234 return getNestedString(u.Object, "metadata", "namespace") 235 } 236 237 func (u *Unstructured) SetNamespace(namespace string) { 238 if len(namespace) == 0 { 239 RemoveNestedField(u.Object, "metadata", "namespace") 240 return 241 } 242 u.setNestedField(namespace, "metadata", "namespace") 243 } 244 245 func (u *Unstructured) GetName() string { 246 return getNestedString(u.Object, "metadata", "name") 247 } 248 249 func (u *Unstructured) SetName(name string) { 250 if len(name) == 0 { 251 RemoveNestedField(u.Object, "metadata", "name") 252 return 253 } 254 u.setNestedField(name, "metadata", "name") 255 } 256 257 func (u *Unstructured) GetGenerateName() string { 258 return getNestedString(u.Object, "metadata", "generateName") 259 } 260 261 func (u *Unstructured) SetGenerateName(generateName string) { 262 if len(generateName) == 0 { 263 RemoveNestedField(u.Object, "metadata", "generateName") 264 return 265 } 266 u.setNestedField(generateName, "metadata", "generateName") 267 } 268 269 func (u *Unstructured) GetUID() types.UID { 270 return types.UID(getNestedString(u.Object, "metadata", "uid")) 271 } 272 273 func (u *Unstructured) SetUID(uid types.UID) { 274 if len(string(uid)) == 0 { 275 RemoveNestedField(u.Object, "metadata", "uid") 276 return 277 } 278 u.setNestedField(string(uid), "metadata", "uid") 279 } 280 281 func (u *Unstructured) GetResourceVersion() string { 282 return getNestedString(u.Object, "metadata", "resourceVersion") 283 } 284 285 func (u *Unstructured) SetResourceVersion(resourceVersion string) { 286 if len(resourceVersion) == 0 { 287 RemoveNestedField(u.Object, "metadata", "resourceVersion") 288 return 289 } 290 u.setNestedField(resourceVersion, "metadata", "resourceVersion") 291 } 292 293 func (u *Unstructured) GetGeneration() int64 { 294 val, found, err := NestedInt64(u.Object, "metadata", "generation") 295 if !found || err != nil { 296 return 0 297 } 298 return val 299 } 300 301 func (u *Unstructured) SetGeneration(generation int64) { 302 if generation == 0 { 303 RemoveNestedField(u.Object, "metadata", "generation") 304 return 305 } 306 u.setNestedField(generation, "metadata", "generation") 307 } 308 309 func (u *Unstructured) GetSelfLink() string { 310 return getNestedString(u.Object, "metadata", "selfLink") 311 } 312 313 func (u *Unstructured) SetSelfLink(selfLink string) { 314 if len(selfLink) == 0 { 315 RemoveNestedField(u.Object, "metadata", "selfLink") 316 return 317 } 318 u.setNestedField(selfLink, "metadata", "selfLink") 319 } 320 321 func (u *Unstructured) GetContinue() string { 322 return getNestedString(u.Object, "metadata", "continue") 323 } 324 325 func (u *Unstructured) SetContinue(c string) { 326 if len(c) == 0 { 327 RemoveNestedField(u.Object, "metadata", "continue") 328 return 329 } 330 u.setNestedField(c, "metadata", "continue") 331 } 332 333 func (u *Unstructured) GetRemainingItemCount() *int64 { 334 return getNestedInt64Pointer(u.Object, "metadata", "remainingItemCount") 335 } 336 337 func (u *Unstructured) SetRemainingItemCount(c *int64) { 338 if c == nil { 339 RemoveNestedField(u.Object, "metadata", "remainingItemCount") 340 } else { 341 u.setNestedField(*c, "metadata", "remainingItemCount") 342 } 343 } 344 345 func (u *Unstructured) GetCreationTimestamp() metav1.Time { 346 var timestamp metav1.Time 347 timestamp.UnmarshalQueryParameter(getNestedString(u.Object, "metadata", "creationTimestamp")) 348 return timestamp 349 } 350 351 func (u *Unstructured) SetCreationTimestamp(timestamp metav1.Time) { 352 ts, _ := timestamp.MarshalQueryParameter() 353 if len(ts) == 0 || timestamp.Time.IsZero() { 354 RemoveNestedField(u.Object, "metadata", "creationTimestamp") 355 return 356 } 357 u.setNestedField(ts, "metadata", "creationTimestamp") 358 } 359 360 func (u *Unstructured) GetDeletionTimestamp() *metav1.Time { 361 var timestamp metav1.Time 362 timestamp.UnmarshalQueryParameter(getNestedString(u.Object, "metadata", "deletionTimestamp")) 363 if timestamp.IsZero() { 364 return nil 365 } 366 return ×tamp 367 } 368 369 func (u *Unstructured) SetDeletionTimestamp(timestamp *metav1.Time) { 370 if timestamp == nil { 371 RemoveNestedField(u.Object, "metadata", "deletionTimestamp") 372 return 373 } 374 ts, _ := timestamp.MarshalQueryParameter() 375 u.setNestedField(ts, "metadata", "deletionTimestamp") 376 } 377 378 func (u *Unstructured) GetDeletionGracePeriodSeconds() *int64 { 379 val, found, err := NestedInt64(u.Object, "metadata", "deletionGracePeriodSeconds") 380 if !found || err != nil { 381 return nil 382 } 383 return &val 384 } 385 386 func (u *Unstructured) SetDeletionGracePeriodSeconds(deletionGracePeriodSeconds *int64) { 387 if deletionGracePeriodSeconds == nil { 388 RemoveNestedField(u.Object, "metadata", "deletionGracePeriodSeconds") 389 return 390 } 391 u.setNestedField(*deletionGracePeriodSeconds, "metadata", "deletionGracePeriodSeconds") 392 } 393 394 func (u *Unstructured) GetLabels() map[string]string { 395 m, _, _ := NestedStringMap(u.Object, "metadata", "labels") 396 return m 397 } 398 399 func (u *Unstructured) SetLabels(labels map[string]string) { 400 if labels == nil { 401 RemoveNestedField(u.Object, "metadata", "labels") 402 return 403 } 404 u.setNestedMap(labels, "metadata", "labels") 405 } 406 407 func (u *Unstructured) GetAnnotations() map[string]string { 408 m, _, _ := NestedStringMap(u.Object, "metadata", "annotations") 409 return m 410 } 411 412 func (u *Unstructured) SetAnnotations(annotations map[string]string) { 413 if annotations == nil { 414 RemoveNestedField(u.Object, "metadata", "annotations") 415 return 416 } 417 u.setNestedMap(annotations, "metadata", "annotations") 418 } 419 420 func (u *Unstructured) SetGroupVersionKind(gvk schema.GroupVersionKind) { 421 u.SetAPIVersion(gvk.GroupVersion().String()) 422 u.SetKind(gvk.Kind) 423 } 424 425 func (u *Unstructured) GroupVersionKind() schema.GroupVersionKind { 426 gv, err := schema.ParseGroupVersion(u.GetAPIVersion()) 427 if err != nil { 428 return schema.GroupVersionKind{} 429 } 430 gvk := gv.WithKind(u.GetKind()) 431 return gvk 432 } 433 434 func (u *Unstructured) GetFinalizers() []string { 435 val, _, _ := NestedStringSlice(u.Object, "metadata", "finalizers") 436 return val 437 } 438 439 func (u *Unstructured) SetFinalizers(finalizers []string) { 440 if finalizers == nil { 441 RemoveNestedField(u.Object, "metadata", "finalizers") 442 return 443 } 444 u.setNestedStringSlice(finalizers, "metadata", "finalizers") 445 } 446 447 func (u *Unstructured) GetManagedFields() []metav1.ManagedFieldsEntry { 448 items, found, err := NestedSlice(u.Object, "metadata", "managedFields") 449 if !found || err != nil { 450 return nil 451 } 452 managedFields := []metav1.ManagedFieldsEntry{} 453 for _, item := range items { 454 m, ok := item.(map[string]interface{}) 455 if !ok { 456 utilruntime.HandleError(fmt.Errorf("unable to retrieve managedFields for object, item %v is not a map", item)) 457 return nil 458 } 459 out := metav1.ManagedFieldsEntry{} 460 if err := runtime.DefaultUnstructuredConverter.FromUnstructured(m, &out); err != nil { 461 utilruntime.HandleError(fmt.Errorf("unable to retrieve managedFields for object: %v", err)) 462 return nil 463 } 464 managedFields = append(managedFields, out) 465 } 466 return managedFields 467 } 468 469 func (u *Unstructured) SetManagedFields(managedFields []metav1.ManagedFieldsEntry) { 470 if managedFields == nil { 471 RemoveNestedField(u.Object, "metadata", "managedFields") 472 return 473 } 474 items := []interface{}{} 475 for _, managedFieldsEntry := range managedFields { 476 out, err := runtime.DefaultUnstructuredConverter.ToUnstructured(&managedFieldsEntry) 477 if err != nil { 478 utilruntime.HandleError(fmt.Errorf("unable to set managedFields for object: %v", err)) 479 return 480 } 481 items = append(items, out) 482 } 483 u.setNestedSlice(items, "metadata", "managedFields") 484 }