...
1
2
3
4 package accumulator
5
6 import (
7 "fmt"
8 "log"
9 "strings"
10
11 "sigs.k8s.io/kustomize/api/internal/plugins/builtinconfig"
12 "sigs.k8s.io/kustomize/api/resmap"
13 "sigs.k8s.io/kustomize/api/types"
14 "sigs.k8s.io/kustomize/kyaml/resid"
15 )
16
17
18
19
20 type ResAccumulator struct {
21 resMap resmap.ResMap
22 tConfig *builtinconfig.TransformerConfig
23 varSet types.VarSet
24 }
25
26 func MakeEmptyAccumulator() *ResAccumulator {
27 ra := &ResAccumulator{}
28 ra.resMap = resmap.New()
29 ra.tConfig = &builtinconfig.TransformerConfig{}
30 ra.varSet = types.NewVarSet()
31 return ra
32 }
33
34
35 func (ra *ResAccumulator) ResMap() resmap.ResMap {
36 return ra.resMap.ShallowCopy()
37 }
38
39
40 func (ra *ResAccumulator) Vars() []types.Var {
41 return ra.varSet.AsSlice()
42 }
43
44 func (ra *ResAccumulator) AppendAll(resources resmap.ResMap) error {
45 return ra.resMap.AppendAll(resources)
46 }
47
48 func (ra *ResAccumulator) AbsorbAll(resources resmap.ResMap) error {
49 return ra.resMap.AbsorbAll(resources)
50 }
51
52 func (ra *ResAccumulator) MergeConfig(
53 tConfig *builtinconfig.TransformerConfig) (err error) {
54 ra.tConfig, err = ra.tConfig.Merge(tConfig)
55 return err
56 }
57
58 func (ra *ResAccumulator) GetTransformerConfig() *builtinconfig.TransformerConfig {
59 return ra.tConfig
60 }
61
62
63
64
65
66
67
68
69
70
71 func (ra *ResAccumulator) MergeVars(incoming []types.Var) error {
72 for _, v := range incoming {
73 targetId := resid.NewResIdWithNamespace(v.ObjRef.GVK(), v.ObjRef.Name, v.ObjRef.Namespace)
74 idMatcher := targetId.GvknEquals
75 if targetId.Namespace != "" || targetId.IsClusterScoped() {
76
77
78 idMatcher = targetId.Equals
79 }
80 matched := ra.resMap.GetMatchingResourcesByAnyId(idMatcher)
81 if len(matched) > 1 {
82 return fmt.Errorf(
83 "found %d resId matches for var %s "+
84 "(unable to disambiguate)",
85 len(matched), v)
86 }
87 if len(matched) == 1 {
88 matched[0].AppendRefVarName(v)
89 }
90 }
91 return ra.varSet.MergeSlice(incoming)
92 }
93
94 func (ra *ResAccumulator) MergeAccumulator(other *ResAccumulator) (err error) {
95 err = ra.AppendAll(other.resMap)
96 if err != nil {
97 return err
98 }
99 err = ra.MergeConfig(other.tConfig)
100 if err != nil {
101 return err
102 }
103 return ra.varSet.MergeSet(other.varSet)
104 }
105
106 func (ra *ResAccumulator) findVarValueFromResources(v types.Var) (interface{}, error) {
107 for _, res := range ra.resMap.Resources() {
108 for _, varName := range res.GetRefVarNames() {
109 if varName == v.Name {
110 s, err := res.GetFieldValue(v.FieldRef.FieldPath)
111 if err != nil {
112 return "", fmt.Errorf(
113 "field specified in var '%v' "+
114 "not found in corresponding resource", v)
115 }
116 return s, nil
117 }
118 }
119 }
120 return "", fmt.Errorf(
121 "var '%v' cannot be mapped to a field "+
122 "in the set of known resources", v)
123 }
124
125
126
127
128 func (ra *ResAccumulator) makeVarReplacementMap() (map[string]interface{}, error) {
129 result := map[string]interface{}{}
130 for _, v := range ra.Vars() {
131 s, err := ra.findVarValueFromResources(v)
132 if err != nil {
133 return nil, err
134 }
135 result[v.Name] = s
136 }
137 return result, nil
138 }
139
140 func (ra *ResAccumulator) Transform(t resmap.Transformer) error {
141 return t.Transform(ra.resMap)
142 }
143
144 func (ra *ResAccumulator) ResolveVars() error {
145 replacementMap, err := ra.makeVarReplacementMap()
146 if err != nil {
147 return err
148 }
149 if len(replacementMap) == 0 {
150 return nil
151 }
152 t := newRefVarTransformer(
153 replacementMap, ra.tConfig.VarReference)
154 err = ra.Transform(t)
155 if len(t.UnusedVars()) > 0 {
156 log.Printf(
157 "well-defined vars that were never replaced: %s\n",
158 strings.Join(t.UnusedVars(), ","))
159 }
160 return err
161 }
162
163 func (ra *ResAccumulator) FixBackReferences() (err error) {
164 if ra.tConfig.NameReference == nil {
165 return nil
166 }
167 return ra.Transform(
168 newNameReferenceTransformer(ra.tConfig.NameReference))
169 }
170
171
172 func (ra *ResAccumulator) Intersection(other resmap.ResMap) error {
173 otherIds := other.AllIds()
174 for _, curId := range ra.resMap.AllIds() {
175 toDelete := true
176 for _, otherId := range otherIds {
177 if otherId == curId {
178 toDelete = false
179 break
180 }
181 }
182 if toDelete {
183 err := ra.resMap.Remove(curId)
184 if err != nil {
185 return err
186 }
187 }
188 }
189 return nil
190 }
191
View as plain text