blob: bf3fd023f4d6c8301be0ce2a3021f039448e233f [file] [log] [blame]
sslobodrd046be82019-01-16 10:02:22 -05001/*
2Copyright 2015 The Kubernetes Authors.
3
4Licensed under the Apache License, Version 2.0 (the "License");
5you may not use this file except in compliance with the License.
6You may obtain a copy of the License at
7
8 http://www.apache.org/licenses/LICENSE-2.0
9
10Unless required by applicable law or agreed to in writing, software
11distributed under the License is distributed on an "AS IS" BASIS,
12WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13See the License for the specific language governing permissions and
14limitations under the License.
15*/
16
17package unstructured
18
19import (
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
27var _ runtime.Unstructured = &UnstructuredList{}
28var _ 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
35type UnstructuredList struct {
36 Object map[string]interface{}
37
38 // Items is a list of unstructured objects.
39 Items []Unstructured `json:"items"`
40}
41
42func (u *UnstructuredList) GetObjectKind() schema.ObjectKind { return u }
43
44func (u *UnstructuredList) IsList() bool { return true }
45
46func (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// UnstructuredContent returns a map contain an overlay of the Items field onto
56// the Object field. Items always overwrites overlay.
57func (u *UnstructuredList) UnstructuredContent() map[string]interface{} {
58 out := make(map[string]interface{}, len(u.Object)+1)
59
60 // shallow copy every property
61 for k, v := range u.Object {
62 out[k] = v
63 }
64
65 items := make([]interface{}, len(u.Items))
66 for i, item := range u.Items {
67 items[i] = item.UnstructuredContent()
68 }
69 out["items"] = items
70 return out
71}
72
73// SetUnstructuredContent obeys the conventions of List and keeps Items and the items
74// array in sync. If items is not an array of objects in the incoming map, then any
75// mismatched item will be removed.
76func (obj *UnstructuredList) SetUnstructuredContent(content map[string]interface{}) {
77 obj.Object = content
78 if content == nil {
79 obj.Items = nil
80 return
81 }
82 items, ok := obj.Object["items"].([]interface{})
83 if !ok || items == nil {
84 items = []interface{}{}
85 }
86 unstructuredItems := make([]Unstructured, 0, len(items))
87 newItems := make([]interface{}, 0, len(items))
88 for _, item := range items {
89 o, ok := item.(map[string]interface{})
90 if !ok {
91 continue
92 }
93 unstructuredItems = append(unstructuredItems, Unstructured{Object: o})
94 newItems = append(newItems, o)
95 }
96 obj.Items = unstructuredItems
97 obj.Object["items"] = newItems
98}
99
100func (u *UnstructuredList) DeepCopy() *UnstructuredList {
101 if u == nil {
102 return nil
103 }
104 out := new(UnstructuredList)
105 *out = *u
106 out.Object = runtime.DeepCopyJSON(u.Object)
107 out.Items = make([]Unstructured, len(u.Items))
108 for i := range u.Items {
109 u.Items[i].DeepCopyInto(&out.Items[i])
110 }
111 return out
112}
113
114// MarshalJSON ensures that the unstructured list object produces proper
115// JSON when passed to Go's standard JSON library.
116func (u *UnstructuredList) MarshalJSON() ([]byte, error) {
117 var buf bytes.Buffer
118 err := UnstructuredJSONScheme.Encode(u, &buf)
119 return buf.Bytes(), err
120}
121
122// UnmarshalJSON ensures that the unstructured list object properly
123// decodes JSON when passed to Go's standard JSON library.
124func (u *UnstructuredList) UnmarshalJSON(b []byte) error {
125 _, _, err := UnstructuredJSONScheme.Decode(b, nil, u)
126 return err
127}
128
129func (u *UnstructuredList) GetAPIVersion() string {
130 return getNestedString(u.Object, "apiVersion")
131}
132
133func (u *UnstructuredList) SetAPIVersion(version string) {
134 u.setNestedField(version, "apiVersion")
135}
136
137func (u *UnstructuredList) GetKind() string {
138 return getNestedString(u.Object, "kind")
139}
140
141func (u *UnstructuredList) SetKind(kind string) {
142 u.setNestedField(kind, "kind")
143}
144
145func (u *UnstructuredList) GetResourceVersion() string {
146 return getNestedString(u.Object, "metadata", "resourceVersion")
147}
148
149func (u *UnstructuredList) SetResourceVersion(version string) {
150 u.setNestedField(version, "metadata", "resourceVersion")
151}
152
153func (u *UnstructuredList) GetSelfLink() string {
154 return getNestedString(u.Object, "metadata", "selfLink")
155}
156
157func (u *UnstructuredList) SetSelfLink(selfLink string) {
158 u.setNestedField(selfLink, "metadata", "selfLink")
159}
160
161func (u *UnstructuredList) GetContinue() string {
162 return getNestedString(u.Object, "metadata", "continue")
163}
164
165func (u *UnstructuredList) SetContinue(c string) {
166 u.setNestedField(c, "metadata", "continue")
167}
168
169func (u *UnstructuredList) SetGroupVersionKind(gvk schema.GroupVersionKind) {
170 u.SetAPIVersion(gvk.GroupVersion().String())
171 u.SetKind(gvk.Kind)
172}
173
174func (u *UnstructuredList) GroupVersionKind() schema.GroupVersionKind {
175 gv, err := schema.ParseGroupVersion(u.GetAPIVersion())
176 if err != nil {
177 return schema.GroupVersionKind{}
178 }
179 gvk := gv.WithKind(u.GetKind())
180 return gvk
181}
182
183func (u *UnstructuredList) setNestedField(value interface{}, fields ...string) {
184 if u.Object == nil {
185 u.Object = make(map[string]interface{})
186 }
187 SetNestedField(u.Object, value, fields...)
188}