1
2
3
4 package types
5
6 import (
7 "bytes"
8 "encoding/json"
9 "fmt"
10 "reflect"
11
12 "sigs.k8s.io/kustomize/kyaml/errors"
13 "sigs.k8s.io/kustomize/kyaml/filesys"
14 "sigs.k8s.io/yaml"
15 )
16
17 const (
18 KustomizationVersion = "kustomize.config.k8s.io/v1beta1"
19 KustomizationKind = "Kustomization"
20 ComponentVersion = "kustomize.config.k8s.io/v1alpha1"
21 ComponentKind = "Component"
22 MetadataNamespacePath = "metadata/namespace"
23 MetadataNamespaceApiVersion = "v1"
24 MetadataNamePath = "metadata/name"
25
26 OriginAnnotations = "originAnnotations"
27 TransformerAnnotations = "transformerAnnotations"
28 ManagedByLabelOption = "managedByLabel"
29 )
30
31 var BuildMetadataOptions = []string{OriginAnnotations, TransformerAnnotations, ManagedByLabelOption}
32
33
34 type Kustomization struct {
35 TypeMeta `json:",inline" yaml:",inline"`
36
37
38 MetaData *ObjectMeta `json:"metadata,omitempty" yaml:"metadata,omitempty"`
39
40
41 OpenAPI map[string]string `json:"openapi,omitempty" yaml:"openapi,omitempty"`
42
43
44
45
46
47
48
49 NamePrefix string `json:"namePrefix,omitempty" yaml:"namePrefix,omitempty"`
50
51
52
53 NameSuffix string `json:"nameSuffix,omitempty" yaml:"nameSuffix,omitempty"`
54
55
56 Namespace string `json:"namespace,omitempty" yaml:"namespace,omitempty"`
57
58
59 CommonLabels map[string]string `json:"commonLabels,omitempty" yaml:"commonLabels,omitempty"`
60
61
62 Labels []Label `json:"labels,omitempty" yaml:"labels,omitempty"`
63
64
65 CommonAnnotations map[string]string `json:"commonAnnotations,omitempty" yaml:"commonAnnotations,omitempty"`
66
67
68
69
70
71
72 PatchesStrategicMerge []PatchStrategicMerge `json:"patchesStrategicMerge,omitempty" yaml:"patchesStrategicMerge,omitempty"`
73
74
75
76
77
78 PatchesJson6902 []Patch `json:"patchesJson6902,omitempty" yaml:"patchesJson6902,omitempty"`
79
80
81
82
83 Patches []Patch `json:"patches,omitempty" yaml:"patches,omitempty"`
84
85
86
87
88 Images []Image `json:"images,omitempty" yaml:"images,omitempty"`
89
90
91 ImageTags []Image `json:"imageTags,omitempty" yaml:"imageTags,omitempty"`
92
93
94
95 Replacements []ReplacementField `json:"replacements,omitempty" yaml:"replacements,omitempty"`
96
97
98
99 Replicas []Replica `json:"replicas,omitempty" yaml:"replicas,omitempty"`
100
101
102
103
104
105
106
107
108
109 Vars []Var `json:"vars,omitempty" yaml:"vars,omitempty"`
110
111
112 SortOptions *SortOptions `json:"sortOptions,omitempty" yaml:"sortOptions,omitempty"`
113
114
115
116
117
118
119
120
121 Resources []string `json:"resources,omitempty" yaml:"resources,omitempty"`
122
123
124
125 Components []string `json:"components,omitempty" yaml:"components,omitempty"`
126
127
128
129
130
131 Crds []string `json:"crds,omitempty" yaml:"crds,omitempty"`
132
133
134 Bases []string `json:"bases,omitempty" yaml:"bases,omitempty"`
135
136
137
138
139
140
141
142
143
144
145 ConfigMapGenerator []ConfigMapArgs `json:"configMapGenerator,omitempty" yaml:"configMapGenerator,omitempty"`
146
147
148
149
150
151
152 SecretGenerator []SecretArgs `json:"secretGenerator,omitempty" yaml:"secretGenerator,omitempty"`
153
154
155 HelmGlobals *HelmGlobals `json:"helmGlobals,omitempty" yaml:"helmGlobals,omitempty"`
156
157
158 HelmCharts []HelmChart `json:"helmCharts,omitempty" yaml:"helmCharts,omitempty"`
159
160
161
162 HelmChartInflationGenerator []HelmChartArgs `json:"helmChartInflationGenerator,omitempty" yaml:"helmChartInflationGenerator,omitempty"`
163
164
165 GeneratorOptions *GeneratorOptions `json:"generatorOptions,omitempty" yaml:"generatorOptions,omitempty"`
166
167
168 Configurations []string `json:"configurations,omitempty" yaml:"configurations,omitempty"`
169
170
171 Generators []string `json:"generators,omitempty" yaml:"generators,omitempty"`
172
173
174 Transformers []string `json:"transformers,omitempty" yaml:"transformers,omitempty"`
175
176
177 Validators []string `json:"validators,omitempty" yaml:"validators,omitempty"`
178
179
180 BuildMetadata []string `json:"buildMetadata,omitempty" yaml:"buildMetadata,omitempty"`
181 }
182
183 const (
184 deprecatedWarningToRunEditFix = "Run 'kustomize edit fix' to update your Kustomization automatically."
185 deprecatedWarningToRunEditFixExperimential = "[EXPERIMENTAL] Run 'kustomize edit fix' to update your Kustomization automatically."
186 deprecatedBaseWarningMessage = "# Warning: 'bases' is deprecated. Please use 'resources' instead." + " " + deprecatedWarningToRunEditFix
187 deprecatedImageTagsWarningMessage = "# Warning: 'imageTags' is deprecated. Please use 'images' instead." + " " + deprecatedWarningToRunEditFix
188 deprecatedPatchesJson6902Message = "# Warning: 'patchesJson6902' is deprecated. Please use 'patches' instead." + " " + deprecatedWarningToRunEditFix
189 deprecatedPatchesStrategicMergeMessage = "# Warning: 'patchesStrategicMerge' is deprecated. Please use 'patches' instead." + " " + deprecatedWarningToRunEditFix
190 deprecatedVarsMessage = "# Warning: 'vars' is deprecated. Please use 'replacements' instead." + " " + deprecatedWarningToRunEditFixExperimential
191 deprecatedCommonLabelsWarningMessage = "# Warning: 'commonLabels' is deprecated. Please use 'labels' instead." + " " + deprecatedWarningToRunEditFix
192 )
193
194
195 func (k *Kustomization) CheckDeprecatedFields() *[]string {
196 var warningMessages []string
197 if k.Bases != nil {
198 warningMessages = append(warningMessages, deprecatedBaseWarningMessage)
199 }
200 if k.CommonLabels != nil {
201 warningMessages = append(warningMessages, deprecatedCommonLabelsWarningMessage)
202 }
203 if k.ImageTags != nil {
204 warningMessages = append(warningMessages, deprecatedImageTagsWarningMessage)
205 }
206 if k.PatchesJson6902 != nil {
207 warningMessages = append(warningMessages, deprecatedPatchesJson6902Message)
208 }
209 if k.PatchesStrategicMerge != nil {
210 warningMessages = append(warningMessages, deprecatedPatchesStrategicMergeMessage)
211 }
212 if k.Vars != nil {
213 warningMessages = append(warningMessages, deprecatedVarsMessage)
214 }
215 return &warningMessages
216 }
217
218
219
220
221
222 func (k *Kustomization) FixKustomization() {
223 if k.Kind == "" {
224 k.Kind = KustomizationKind
225 }
226 if k.APIVersion == "" {
227 if k.Kind == ComponentKind {
228 k.APIVersion = ComponentVersion
229 } else {
230 k.APIVersion = KustomizationVersion
231 }
232 }
233
234
235 k.Resources = append(k.Resources, k.Bases...)
236 k.Bases = nil
237
238
239 k.Images = append(k.Images, k.ImageTags...)
240 k.ImageTags = nil
241
242 for i, g := range k.ConfigMapGenerator {
243 if g.EnvSource != "" {
244 k.ConfigMapGenerator[i].EnvSources =
245 append(g.EnvSources, g.EnvSource)
246 k.ConfigMapGenerator[i].EnvSource = ""
247 }
248 }
249 for i, g := range k.SecretGenerator {
250 if g.EnvSource != "" {
251 k.SecretGenerator[i].EnvSources =
252 append(g.EnvSources, g.EnvSource)
253 k.SecretGenerator[i].EnvSource = ""
254 }
255 }
256 charts, globals := SplitHelmParameters(k.HelmChartInflationGenerator)
257 if k.HelmGlobals == nil {
258 if globals.ChartHome != "" || globals.ConfigHome != "" {
259 k.HelmGlobals = &globals
260 }
261 }
262 k.HelmCharts = append(k.HelmCharts, charts...)
263
264 k.HelmChartInflationGenerator = nil
265 }
266
267
268
269
270 func (k *Kustomization) FixKustomizationPreMarshalling(fSys filesys.FileSystem) error {
271
272 k.Patches = append(k.Patches, k.PatchesJson6902...)
273 k.PatchesJson6902 = nil
274
275 if k.PatchesStrategicMerge != nil {
276 for _, patchStrategicMerge := range k.PatchesStrategicMerge {
277
278 if _, err := fSys.ReadFile(string(patchStrategicMerge)); err == nil {
279
280 k.Patches = append(k.Patches, Patch{Path: string(patchStrategicMerge)})
281 } else {
282
283 k.Patches = append(k.Patches, Patch{Patch: string(patchStrategicMerge)})
284 }
285 }
286 k.PatchesStrategicMerge = nil
287 }
288
289
290
291
292 if cl := labelFromCommonLabels(k.CommonLabels); cl != nil {
293
294 for _, l := range k.Labels {
295 for k := range l.Pairs {
296 if _, exist := cl.Pairs[k]; exist {
297 return fmt.Errorf("label name '%s' exists in both commonLabels and labels", k)
298 }
299 }
300 }
301 k.Labels = append(k.Labels, *cl)
302 k.CommonLabels = nil
303 }
304
305 return nil
306 }
307
308 func (k *Kustomization) CheckEmpty() error {
309
310 emptyKustomization := &Kustomization{}
311
312
313 emptyKustomization.TypeMeta = k.TypeMeta
314
315 if reflect.DeepEqual(k, emptyKustomization) {
316 return fmt.Errorf("kustomization.yaml is empty")
317 }
318
319 return nil
320 }
321
322 func (k *Kustomization) EnforceFields() []string {
323 var errs []string
324 if k.Kind != "" && k.Kind != KustomizationKind && k.Kind != ComponentKind {
325 errs = append(errs, "kind should be "+KustomizationKind+" or "+ComponentKind)
326 }
327 requiredVersion := KustomizationVersion
328 if k.Kind == ComponentKind {
329 requiredVersion = ComponentVersion
330 }
331 if k.APIVersion != "" && k.APIVersion != requiredVersion {
332 errs = append(errs, "apiVersion for "+k.Kind+" should be "+requiredVersion)
333 }
334 return errs
335 }
336
337
338 func (k *Kustomization) Unmarshal(y []byte) error {
339
340
341
342 j, err := yaml.YAMLToJSON(y)
343 if err != nil {
344 return errors.WrapPrefixf(err, "invalid Kustomization")
345 }
346 dec := json.NewDecoder(bytes.NewReader(j))
347 dec.DisallowUnknownFields()
348 var nk Kustomization
349 err = dec.Decode(&nk)
350 if err != nil {
351 return errors.WrapPrefixf(err, "invalid Kustomization")
352 }
353 *k = nk
354 return nil
355 }
356
View as plain text