...

Source file src/k8s.io/apimachinery/pkg/apis/meta/v1/unstructured/unstructured_list.go

Documentation: k8s.io/apimachinery/pkg/apis/meta/v1/unstructured

     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  
    22  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    23  	"k8s.io/apimachinery/pkg/runtime"
    24  	"k8s.io/apimachinery/pkg/runtime/schema"
    25  )
    26  
    27  var _ runtime.Unstructured = &UnstructuredList{}
    28  var _ metav1.ListInterface = &UnstructuredList{}
    29  
    30  // UnstructuredList allows lists that do not have Golang structs
    31  // registered to be manipulated generically. This can be used to deal
    32  // with the API lists from a plug-in.
    33  // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
    34  // +k8s:deepcopy-gen=true
    35  type UnstructuredList struct {
    36  	Object map[string]interface{}
    37  
    38  	// Items is a list of unstructured objects.
    39  	Items []Unstructured `json:"items"`
    40  }
    41  
    42  func (u *UnstructuredList) GetObjectKind() schema.ObjectKind { return u }
    43  
    44  func (u *UnstructuredList) IsList() bool { return true }
    45  
    46  func (u *UnstructuredList) EachListItem(fn func(runtime.Object) error) error {
    47  	for i := range u.Items {
    48  		if err := fn(&u.Items[i]); err != nil {
    49  			return err
    50  		}
    51  	}
    52  	return nil
    53  }
    54  
    55  func (u *UnstructuredList) EachListItemWithAlloc(fn func(runtime.Object) error) error {
    56  	for i := range u.Items {
    57  		if err := fn(&Unstructured{Object: u.Items[i].Object}); err != nil {
    58  			return err
    59  		}
    60  	}
    61  	return nil
    62  }
    63  
    64  // NewEmptyInstance returns a new instance of the concrete type containing only kind/apiVersion and no other data.
    65  // This should be called instead of reflect.New() for unstructured types because the go type alone does not preserve kind/apiVersion info.
    66  func (u *UnstructuredList) NewEmptyInstance() runtime.Unstructured {
    67  	out := new(UnstructuredList)
    68  	if u != nil {
    69  		out.SetGroupVersionKind(u.GroupVersionKind())
    70  	}
    71  	return out
    72  }
    73  
    74  // UnstructuredContent returns a map contain an overlay of the Items field onto
    75  // the Object field. Items always overwrites overlay.
    76  func (u *UnstructuredList) UnstructuredContent() map[string]interface{} {
    77  	out := make(map[string]interface{}, len(u.Object)+1)
    78  
    79  	// shallow copy every property
    80  	for k, v := range u.Object {
    81  		out[k] = v
    82  	}
    83  
    84  	items := make([]interface{}, len(u.Items))
    85  	for i, item := range u.Items {
    86  		items[i] = item.UnstructuredContent()
    87  	}
    88  	out["items"] = items
    89  	return out
    90  }
    91  
    92  // SetUnstructuredContent obeys the conventions of List and keeps Items and the items
    93  // array in sync. If items is not an array of objects in the incoming map, then any
    94  // mismatched item will be removed.
    95  func (obj *UnstructuredList) SetUnstructuredContent(content map[string]interface{}) {
    96  	obj.Object = content
    97  	if content == nil {
    98  		obj.Items = nil
    99  		return
   100  	}
   101  	items, ok := obj.Object["items"].([]interface{})
   102  	if !ok || items == nil {
   103  		items = []interface{}{}
   104  	}
   105  	unstructuredItems := make([]Unstructured, 0, len(items))
   106  	newItems := make([]interface{}, 0, len(items))
   107  	for _, item := range items {
   108  		o, ok := item.(map[string]interface{})
   109  		if !ok {
   110  			continue
   111  		}
   112  		unstructuredItems = append(unstructuredItems, Unstructured{Object: o})
   113  		newItems = append(newItems, o)
   114  	}
   115  	obj.Items = unstructuredItems
   116  	obj.Object["items"] = newItems
   117  }
   118  
   119  func (u *UnstructuredList) DeepCopy() *UnstructuredList {
   120  	if u == nil {
   121  		return nil
   122  	}
   123  	out := new(UnstructuredList)
   124  	*out = *u
   125  	out.Object = runtime.DeepCopyJSON(u.Object)
   126  	out.Items = make([]Unstructured, len(u.Items))
   127  	for i := range u.Items {
   128  		u.Items[i].DeepCopyInto(&out.Items[i])
   129  	}
   130  	return out
   131  }
   132  
   133  // MarshalJSON ensures that the unstructured list object produces proper
   134  // JSON when passed to Go's standard JSON library.
   135  func (u *UnstructuredList) MarshalJSON() ([]byte, error) {
   136  	var buf bytes.Buffer
   137  	err := UnstructuredJSONScheme.Encode(u, &buf)
   138  	return buf.Bytes(), err
   139  }
   140  
   141  // UnmarshalJSON ensures that the unstructured list object properly
   142  // decodes JSON when passed to Go's standard JSON library.
   143  func (u *UnstructuredList) UnmarshalJSON(b []byte) error {
   144  	_, _, err := UnstructuredJSONScheme.Decode(b, nil, u)
   145  	return err
   146  }
   147  
   148  func (u *UnstructuredList) GetAPIVersion() string {
   149  	return getNestedString(u.Object, "apiVersion")
   150  }
   151  
   152  func (u *UnstructuredList) SetAPIVersion(version string) {
   153  	u.setNestedField(version, "apiVersion")
   154  }
   155  
   156  func (u *UnstructuredList) GetKind() string {
   157  	return getNestedString(u.Object, "kind")
   158  }
   159  
   160  func (u *UnstructuredList) SetKind(kind string) {
   161  	u.setNestedField(kind, "kind")
   162  }
   163  
   164  func (u *UnstructuredList) GetResourceVersion() string {
   165  	return getNestedString(u.Object, "metadata", "resourceVersion")
   166  }
   167  
   168  func (u *UnstructuredList) SetResourceVersion(version string) {
   169  	u.setNestedField(version, "metadata", "resourceVersion")
   170  }
   171  
   172  func (u *UnstructuredList) GetSelfLink() string {
   173  	return getNestedString(u.Object, "metadata", "selfLink")
   174  }
   175  
   176  func (u *UnstructuredList) SetSelfLink(selfLink string) {
   177  	u.setNestedField(selfLink, "metadata", "selfLink")
   178  }
   179  
   180  func (u *UnstructuredList) GetContinue() string {
   181  	return getNestedString(u.Object, "metadata", "continue")
   182  }
   183  
   184  func (u *UnstructuredList) SetContinue(c string) {
   185  	u.setNestedField(c, "metadata", "continue")
   186  }
   187  
   188  func (u *UnstructuredList) GetRemainingItemCount() *int64 {
   189  	return getNestedInt64Pointer(u.Object, "metadata", "remainingItemCount")
   190  }
   191  
   192  func (u *UnstructuredList) SetRemainingItemCount(c *int64) {
   193  	if c == nil {
   194  		RemoveNestedField(u.Object, "metadata", "remainingItemCount")
   195  	} else {
   196  		u.setNestedField(*c, "metadata", "remainingItemCount")
   197  	}
   198  }
   199  
   200  func (u *UnstructuredList) SetGroupVersionKind(gvk schema.GroupVersionKind) {
   201  	u.SetAPIVersion(gvk.GroupVersion().String())
   202  	u.SetKind(gvk.Kind)
   203  }
   204  
   205  func (u *UnstructuredList) GroupVersionKind() schema.GroupVersionKind {
   206  	gv, err := schema.ParseGroupVersion(u.GetAPIVersion())
   207  	if err != nil {
   208  		return schema.GroupVersionKind{}
   209  	}
   210  	gvk := gv.WithKind(u.GetKind())
   211  	return gvk
   212  }
   213  
   214  func (u *UnstructuredList) setNestedField(value interface{}, fields ...string) {
   215  	if u.Object == nil {
   216  		u.Object = make(map[string]interface{})
   217  	}
   218  	SetNestedField(u.Object, value, fields...)
   219  }
   220  

View as plain text