1
2
3
4 package walk
5
6 import (
7 "sort"
8
9 "sigs.k8s.io/kustomize/kyaml/fieldmeta"
10 "sigs.k8s.io/kustomize/kyaml/openapi"
11 "sigs.k8s.io/kustomize/kyaml/sets"
12 "sigs.k8s.io/kustomize/kyaml/yaml"
13 )
14
15
16
17
18
19
20
21 func (l Walker) walkMap() (*yaml.RNode, error) {
22
23 dest, err := l.Sources.setDestNode(l.VisitMap(l.Sources, l.Schema))
24 if dest == nil || err != nil {
25 return nil, err
26 }
27
28
29 for _, key := range l.fieldNames() {
30 var res *yaml.RNode
31 var keys []*yaml.RNode
32 if l.VisitKeysAsScalars {
33
34
35
36 for i := range l.Sources {
37
38 if l.Sources[i] == nil {
39 keys = append(keys, nil)
40 continue
41 }
42 field := l.Sources[i].Field(key)
43 if field == nil || yaml.IsMissingOrNull(field.Key) {
44 keys = append(keys, nil)
45 continue
46 }
47 keys = append(keys, field.Key)
48 }
49
50
51 res, err = l.Visitor.VisitScalar(keys, nil)
52 if err != nil {
53 return nil, err
54 }
55 }
56
57 var s *openapi.ResourceSchema
58 if l.Schema != nil {
59 s = l.Schema.Field(key)
60 }
61 fv, commentSch, keyStyles := l.fieldValue(key)
62 if commentSch != nil {
63 s = commentSch
64 }
65 val, err := Walker{
66 VisitKeysAsScalars: l.VisitKeysAsScalars,
67 InferAssociativeLists: l.InferAssociativeLists,
68 Visitor: l,
69 Schema: s,
70 Sources: fv,
71 MergeOptions: l.MergeOptions,
72 Path: append(l.Path, key)}.Walk()
73 if err != nil {
74 return nil, err
75 }
76
77
78 var comments yaml.Comments
79 if !yaml.IsMissingOrNull(res) {
80 comments = yaml.Comments{
81 LineComment: res.YNode().LineComment,
82 HeadComment: res.YNode().HeadComment,
83 FootComment: res.YNode().FootComment,
84 }
85 if len(keys) > 0 && !yaml.IsMissingOrNull(keys[DestIndex]) {
86 keys[DestIndex].YNode().HeadComment = res.YNode().HeadComment
87 keys[DestIndex].YNode().LineComment = res.YNode().LineComment
88 keys[DestIndex].YNode().FootComment = res.YNode().FootComment
89 }
90 }
91
92
93 fieldSetter := yaml.FieldSetter{
94 Name: key,
95 Comments: comments,
96 AppendKeyStyle: keyStyles[val],
97 Value: val,
98 }
99 _, err = dest.Pipe(fieldSetter)
100 if err != nil {
101 return nil, err
102 }
103 }
104
105 return dest, nil
106 }
107
108
109 func (l Walker) valueIfPresent(node *yaml.MapNode) (*yaml.RNode, *openapi.ResourceSchema) {
110 if node == nil {
111 return nil, nil
112 }
113
114
115 var s *openapi.ResourceSchema
116 fm := fieldmeta.FieldMeta{}
117 var err error
118
119 if err = fm.Read(node.Value); err == nil {
120 s = &openapi.ResourceSchema{Schema: &fm.Schema}
121 if fm.Schema.Ref.String() != "" {
122 r, err := openapi.Resolve(&fm.Schema.Ref, openapi.Schema())
123 if err == nil && r != nil {
124 s.Schema = r
125 }
126 }
127 }
128
129
130
131 if fm.IsEmpty() {
132 if err = fm.Read(node.Key); err == nil {
133 s = &openapi.ResourceSchema{Schema: &fm.Schema}
134 }
135 if fm.Schema.Ref.String() != "" {
136 r, err := openapi.Resolve(&fm.Schema.Ref, openapi.Schema())
137 if err == nil && r != nil {
138 s.Schema = r
139 }
140 }
141 }
142 return node.Value, s
143 }
144
145
146
147 func (l Walker) fieldNames() []string {
148 fields := sets.String{}
149 for _, s := range l.Sources {
150 if s == nil {
151 continue
152 }
153
154 sFields, _ := s.Fields()
155 fields.Insert(sFields...)
156 }
157 result := fields.List()
158 sort.Strings(result)
159 return result
160 }
161
162
163
164 func (l Walker) fieldValue(fieldName string) ([]*yaml.RNode, *openapi.ResourceSchema, map[*yaml.RNode]yaml.Style) {
165 var fields []*yaml.RNode
166 var sch *openapi.ResourceSchema
167 keyStyles := make(map[*yaml.RNode]yaml.Style, len(l.Sources))
168 for i := range l.Sources {
169 if l.Sources[i] == nil {
170 fields = append(fields, nil)
171 continue
172 }
173 field := l.Sources[i].Field(fieldName)
174 f, s := l.valueIfPresent(field)
175 fields = append(fields, f)
176 if field != nil && field.Key != nil && field.Key.YNode() != nil {
177 keyStyles[f] = field.Key.YNode().Style
178 }
179 if sch == nil && !s.IsMissingOrNull() {
180 sch = s
181 }
182 }
183 return fields, sch, keyStyles
184 }
185
View as plain text