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 &timestamp
   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  }