1
2
3
4 package resource
5
6 import (
7 "encoding/json"
8 "fmt"
9 "log"
10 "strings"
11
12 "sigs.k8s.io/kustomize/api/ifc"
13 "sigs.k8s.io/kustomize/api/internal/generators"
14 "sigs.k8s.io/kustomize/api/internal/kusterr"
15 "sigs.k8s.io/kustomize/api/konfig"
16 "sigs.k8s.io/kustomize/api/types"
17 "sigs.k8s.io/kustomize/kyaml/kio"
18 "sigs.k8s.io/kustomize/kyaml/resid"
19 "sigs.k8s.io/kustomize/kyaml/yaml"
20 )
21
22
23 type Factory struct {
24 hasher ifc.KustHasher
25
26
27
28
29
30 IncludeLocalConfigs bool
31 }
32
33
34 func NewFactory(h ifc.KustHasher) *Factory {
35 return &Factory{hasher: h}
36 }
37
38
39 func (rf *Factory) Hasher() ifc.KustHasher {
40 return rf.hasher
41 }
42
43
44 func (rf *Factory) FromMap(m map[string]interface{}) *Resource {
45 res, err := rf.FromMapAndOption(m, nil)
46 if err != nil {
47
48 log.Fatalf("failed to create resource from map: %v", err)
49 }
50 return res
51 }
52
53
54 func (rf *Factory) FromMapWithName(n string, m map[string]interface{}) *Resource {
55 return rf.FromMapWithNamespaceAndName(resid.DefaultNamespace, n, m)
56 }
57
58
59 func (rf *Factory) FromMapWithNamespaceAndName(ns string, n string, m map[string]interface{}) *Resource {
60 r, err := rf.FromMapAndOption(m, nil)
61 if err != nil {
62
63 log.Fatalf("failed to create resource from map: %v", err)
64 }
65 return r.setPreviousId(ns, n, r.GetKind())
66 }
67
68
69 func (rf *Factory) FromMapAndOption(
70 m map[string]interface{}, args *types.GeneratorArgs) (*Resource, error) {
71 n, err := yaml.FromMap(m)
72 if err != nil {
73 return nil, fmt.Errorf("failed to convert map to YAML node: %w", err)
74 }
75 return rf.makeOne(n, args), nil
76 }
77
78
79 func (rf *Factory) makeOne(rn *yaml.RNode, o *types.GeneratorArgs) *Resource {
80 if rn == nil {
81 log.Fatal("RNode must not be null")
82 }
83 resource := &Resource{RNode: *rn}
84 if o != nil {
85 if o.Options == nil || !o.Options.DisableNameSuffixHash {
86 resource.EnableHashSuffix()
87 }
88 resource.SetBehavior(types.NewGenerationBehavior(o.Behavior))
89 }
90
91 return resource
92 }
93
94
95
96 func (rf *Factory) SliceFromPatches(
97 ldr ifc.Loader, paths []types.PatchStrategicMerge) ([]*Resource, error) {
98 var result []*Resource
99 for _, path := range paths {
100 content, err := ldr.Load(string(path))
101 if err != nil {
102 return nil, err
103 }
104 res, err := rf.SliceFromBytes(content)
105 if err != nil {
106 return nil, kusterr.Handler(err, string(path))
107 }
108 result = append(result, res...)
109 }
110 return result, nil
111 }
112
113
114 func (rf *Factory) FromBytes(in []byte) (*Resource, error) {
115 result, err := rf.SliceFromBytes(in)
116 if err != nil {
117 return nil, err
118 }
119 if len(result) != 1 {
120 return nil, fmt.Errorf(
121 "expected 1 resource, found %d in %v", len(result), in)
122 }
123 return result[0], nil
124 }
125
126
127 func (rf *Factory) SliceFromBytes(in []byte) ([]*Resource, error) {
128 nodes, err := rf.RNodesFromBytes(in)
129 if err != nil {
130 return nil, err
131 }
132 return rf.resourcesFromRNodes(nodes), nil
133 }
134
135
136 func (rf *Factory) DropLocalNodes(nodes []*yaml.RNode) ([]*Resource, error) {
137 var result []*yaml.RNode
138 for _, node := range nodes {
139 if node.IsNilOrEmpty() {
140 continue
141 }
142 md, err := node.GetValidatedMetadata()
143 if err != nil {
144 return nil, err
145 }
146
147 if rf.IncludeLocalConfigs {
148 result = append(result, node)
149 continue
150 }
151 localConfig, exist := md.ObjectMeta.Annotations[konfig.IgnoredByKustomizeAnnotation]
152 if !exist || localConfig == "false" {
153 result = append(result, node)
154 }
155 }
156 return rf.resourcesFromRNodes(result), nil
157 }
158
159
160 func (rf *Factory) ResourcesFromRNodes(
161 nodes []*yaml.RNode) (result []*Resource, err error) {
162 return rf.DropLocalNodes(nodes)
163 }
164
165
166 func (rf *Factory) resourcesFromRNodes(
167 nodes []*yaml.RNode) (result []*Resource) {
168 for _, n := range nodes {
169 result = append(result, rf.makeOne(n, nil))
170 }
171 return
172 }
173
174 func (rf *Factory) RNodesFromBytes(b []byte) ([]*yaml.RNode, error) {
175 nodes, err := kio.FromBytes(b)
176 if err != nil {
177 return nil, err
178 }
179 nodes, err = rf.dropBadNodes(nodes)
180 if err != nil {
181 return nil, err
182 }
183 return rf.inlineAnyEmbeddedLists(nodes)
184 }
185
186
187
188
189 func (rf *Factory) inlineAnyEmbeddedLists(
190 nodes []*yaml.RNode) (result []*yaml.RNode, err error) {
191 var n0 *yaml.RNode
192 for len(nodes) > 0 {
193 n0, nodes = nodes[0], nodes[1:]
194 kind := n0.GetKind()
195 if !strings.HasSuffix(kind, "List") {
196 result = append(result, n0)
197 continue
198 }
199
200 var m map[string]interface{}
201 m, err = n0.Map()
202 if err != nil {
203 return nil, fmt.Errorf("trouble expanding list of %s; %w", kind, err)
204 }
205 items, ok := m["items"]
206 if !ok {
207
208 continue
209 }
210 slice, ok := items.([]interface{})
211 if !ok {
212 if items == nil {
213
214 continue
215 }
216 return nil, fmt.Errorf(
217 "expected array in %s/items, but found %T", kind, items)
218 }
219 innerNodes, err := rf.convertObjectSliceToNodeSlice(slice)
220 if err != nil {
221 return nil, err
222 }
223 nodes = append(nodes, innerNodes...)
224 }
225 return result, nil
226 }
227
228
229 func (rf *Factory) convertObjectSliceToNodeSlice(
230 objects []interface{}) (result []*yaml.RNode, err error) {
231 var bytes []byte
232 var nodes []*yaml.RNode
233 for _, obj := range objects {
234 bytes, err = json.Marshal(obj)
235 if err != nil {
236 return
237 }
238 nodes, err = kio.FromBytes(bytes)
239 if err != nil {
240 return
241 }
242 nodes, err = rf.dropBadNodes(nodes)
243 if err != nil {
244 return
245 }
246 result = append(result, nodes...)
247 }
248 return
249 }
250
251
252 func (rf *Factory) dropBadNodes(nodes []*yaml.RNode) ([]*yaml.RNode, error) {
253 var result []*yaml.RNode
254 for _, n := range nodes {
255 if n.IsNilOrEmpty() {
256 continue
257 }
258 if _, err := n.GetValidatedMetadata(); err != nil {
259 return nil, err
260 }
261 if foundNil, path := n.HasNilEntryInList(); foundNil {
262 return nil, fmt.Errorf("empty item at %v in object %v", path, n)
263 }
264 result = append(result, n)
265 }
266 return result, nil
267 }
268
269
270
271 func (rf *Factory) SliceFromBytesWithNames(names []string, in []byte) ([]*Resource, error) {
272 result, err := rf.SliceFromBytes(in)
273 if err != nil {
274 return nil, err
275 }
276 if len(names) != len(result) {
277 return nil, fmt.Errorf("number of names doesn't match number of resources")
278 }
279 for i, res := range result {
280 res.setPreviousId(resid.DefaultNamespace, names[i], res.GetKind())
281 }
282 return result, nil
283 }
284
285
286 func (rf *Factory) MakeConfigMap(kvLdr ifc.KvLoader, args *types.ConfigMapArgs) (*Resource, error) {
287 rn, err := generators.MakeConfigMap(kvLdr, args)
288 if err != nil {
289 return nil, err
290 }
291 return rf.makeOne(rn, &args.GeneratorArgs), nil
292 }
293
294
295 func (rf *Factory) MakeSecret(kvLdr ifc.KvLoader, args *types.SecretArgs) (*Resource, error) {
296 rn, err := generators.MakeSecret(kvLdr, args)
297 if err != nil {
298 return nil, err
299 }
300 return rf.makeOne(rn, &args.GeneratorArgs), nil
301 }
302
View as plain text