1 package unstructured
2
3 import (
4 "bytes"
5 "encoding/json"
6 "strings"
7
8 "github.com/pkg/errors"
9 "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
10 "k8s.io/apimachinery/pkg/runtime"
11 "k8s.io/apimachinery/pkg/runtime/schema"
12
13 "sigs.k8s.io/controller-runtime/pkg/client"
14 )
15
16 const YAMLFileDelimiter = "\n---\n"
17
18
19 type Unstructured = unstructured.Unstructured
20
21 var (
22
23 ErrUnstructuredFieldNotFound = errors.New("field not found")
24 )
25
26
27 func New(gv schema.GroupVersion, kind, namespace, name string) *unstructured.Unstructured {
28 u := &unstructured.Unstructured{}
29 u.SetNamespace(namespace)
30 u.SetName(name)
31 u.SetGroupVersionKind(schema.GroupVersionKind{
32 Group: gv.Group,
33 Kind: kind,
34 Version: gv.Version,
35 })
36 return u
37 }
38
39
40 func FromUnstructured(u *unstructured.Unstructured, obj interface{}) (err error) {
41 err = runtime.DefaultUnstructuredConverter.FromUnstructured(u.Object, obj)
42 return err
43 }
44
45
46
47 func ToUnstructured(obj client.Object) (*unstructured.Unstructured, error) {
48 return FromRuntime(obj)
49 }
50
51 func FromRuntime(obj runtime.Object) (*unstructured.Unstructured, error) {
52
53
54
55 if _, ok := obj.(runtime.Unstructured); ok {
56 obj = obj.DeepCopyObject()
57 }
58 rawMap, err := runtime.DefaultUnstructuredConverter.ToUnstructured(obj)
59 if err != nil {
60 return nil, err
61 }
62 return &unstructured.Unstructured{Object: rawMap}, nil
63 }
64
65
66
67 func ToUnstructuredArray(objs ...client.Object) ([]*unstructured.Unstructured, error) {
68 var uu []*unstructured.Unstructured
69 for _, o := range objs {
70 u, err := ToUnstructured(o)
71 if err != nil {
72 return nil, err
73 }
74 uu = append(uu, u)
75 }
76
77 return uu, nil
78 }
79
80
81
82 func ToClientObjArray(objs ...*unstructured.Unstructured) []client.Object {
83 clobjs := make([]client.Object, len(objs))
84 for i, obj := range objs {
85 clobjs[i] = obj
86 }
87 return clobjs
88 }
89
90
91
92 func ToUnstructuredList(obj client.Object) (*unstructured.UnstructuredList, error) {
93 un, err := ToUnstructured(obj)
94 if err != nil {
95 return nil, err
96 }
97 unl := &unstructured.UnstructuredList{Items: []unstructured.Unstructured{*un}}
98 unl.SetAPIVersion("v1")
99 unl.SetKind("List")
100 return unl, nil
101 }
102
103
104
105
106 func AddToUnstructuredListBytes(resources []byte, obj client.Object) ([]byte, error) {
107 if len(resources) == 0 {
108 unl, err := ToUnstructuredList(obj)
109 if err != nil {
110 return nil, err
111 }
112 return unl.MarshalJSON()
113 }
114 unl := &unstructured.UnstructuredList{}
115 if err := unl.UnmarshalJSON(resources); err != nil {
116 return nil, err
117 }
118 un, err := ToUnstructured(obj)
119 if err != nil {
120 return nil, err
121 }
122 unl.Items = append(unl.Items, *un)
123 return unl.MarshalJSON()
124 }
125
126
127 func StringsToUnstructuredList(objs []string) (*unstructured.UnstructuredList, error) {
128 resp := &unstructured.UnstructuredList{}
129 for _, obj := range objs {
130 resource := &unstructured.Unstructured{}
131 if err := resource.UnmarshalJSON([]byte(obj)); err != nil {
132 return resp, err
133 }
134 resp.Items = append(resp.Items, *resource)
135 }
136 return resp, nil
137 }
138
139
140
141
142
143 func UnstructuredListToStrings(unl *unstructured.UnstructuredList) ([]string, error) {
144 if unl == nil {
145 return []string{}, nil
146 }
147 var result []string
148 for _, item := range unl.Items {
149 data, err := item.MarshalJSON()
150 if err != nil {
151 return result, err
152 }
153 result = append(result, string(data))
154 }
155 return result, nil
156 }
157
158
159
160 func UnmarshalField(u *unstructured.Unstructured, v interface{}, fields ...string) error {
161 value, found, err := unstructured.NestedFieldNoCopy(u.Object, fields...)
162 if err != nil {
163 return errors.Wrapf(err, "failed to retrieve field %q from %q", strings.Join(fields, "."), u.GroupVersionKind())
164 }
165 if !found || value == nil {
166 return ErrUnstructuredFieldNotFound
167 }
168 valueBytes, err := json.Marshal(value)
169 if err != nil {
170 return errors.Wrapf(err, "failed to json-encode field %q value from %q", strings.Join(fields, "."), u.GroupVersionKind())
171 }
172 if err := json.Unmarshal(valueBytes, v); err != nil {
173 return errors.Wrapf(err, "failed to json-decode field %q value from %q", strings.Join(fields, "."), u.GroupVersionKind())
174 }
175 return nil
176 }
177
178
179 func ToJSON(uobjs []*unstructured.Unstructured) ([]byte, error) {
180 jsonDoc := make([]byte, 0)
181 for _, doc := range uobjs {
182 jsonData, err := doc.MarshalJSON()
183 if err != nil {
184 return nil, err
185 }
186 jsonDoc = append(jsonDoc, jsonData...)
187 }
188 return jsonDoc, nil
189 }
190
191
192 func FromJSON(jsonData []byte) ([]*unstructured.Unstructured, error) {
193 manifests := []*unstructured.Unstructured{}
194 decoder := json.NewDecoder(bytes.NewBuffer(jsonData))
195 for {
196 var rawObj runtime.RawExtension
197 if err := decoder.Decode(&rawObj); err != nil {
198 break
199 }
200 obj := &unstructured.Unstructured{}
201 if rawObj.Size() == 0 {
202 continue
203 }
204 if err := obj.UnmarshalJSON(rawObj.Raw); err != nil {
205 return nil, err
206 }
207 manifests = append(manifests, obj)
208 }
209 return manifests, nil
210 }
211
View as plain text