@@ -21,15 +21,20 @@ import (
21
21
const (
22
22
ManuallyControlledAnnKey = "ext.packaging.carvel.dev/manually-controlled"
23
23
24
- HelmTemplateOverlayNameKey = "ext.packaging.carvel.dev/helm-template-name"
25
- HelmTemplateOverlayNameSpaceKey = "ext.packaging.carvel.dev/helm-template-namespace"
24
+ HelmTemplateOverlayNameKey = "ext.packaging.carvel.dev/helm-template-name"
25
+ HelmTemplateOverlayNameKeyFmt = "ext.packaging.carvel.dev/helm-%d-template-name"
26
+ HelmTemplateOverlayNameSpaceKey = "ext.packaging.carvel.dev/helm-template-namespace"
27
+ HelmTemplateOverlayNameSpaceKeyFmt = "ext.packaging.carvel.dev/helm-%d-template-namespace"
26
28
27
29
// Resulting secret names are sorted deterministically by suffix
28
- ExtYttPathsFromSecretNameAnnKey = "ext.packaging.carvel.dev/ytt-paths-from-secret-name"
29
- ExtHelmPathsFromSecretNameAnnKey = "ext.packaging.carvel.dev/helm-template-values-from-secret-name"
30
+ ExtYttPathsFromSecretNameAnnKey = "ext.packaging.carvel.dev/ytt-paths-from-secret-name"
31
+ ExtYttPathsFromSecretNameAnnKeyFmt = "ext.packaging.carvel.dev/ytt-%d-paths-from-secret-name"
32
+ ExtHelmPathsFromSecretNameAnnKey = "ext.packaging.carvel.dev/helm-template-values-from-secret-name"
33
+ ExtHelmPathsFromSecretNameAnnKeyFmt = "ext.packaging.carvel.dev/helm-%d-template-values-from-secret-name"
30
34
31
35
// ExtYttDataValuesOverlaysAnnKey if set, adds the pkgi's values secrets as overlays/paths, not as values, to the app
32
- ExtYttDataValuesOverlaysAnnKey = "ext.packaging.carvel.dev/ytt-data-values-overlays"
36
+ ExtYttDataValuesOverlaysAnnKey = "ext.packaging.carvel.dev/ytt-data-values-overlays"
37
+ ExtYttDataValuesOverlaysAnnKeyFmt = "ext.packaging.carvel.dev/ytt-%d-data-values-overlays"
33
38
34
39
ExtFetchSecretNameAnnKeyFmt = "ext.packaging.carvel.dev/fetch-%d-secret-name"
35
40
)
@@ -101,21 +106,10 @@ func NewApp(existingApp *v1alpha1.App, pkgInstall *pkgingv1alpha1.PackageInstall
101
106
}
102
107
103
108
templatesPatcher := templateStepsPatcher {
104
- yttPatcher : & yttStepPatcher {
105
- addValuesAsInlinePaths : pkgiHasAnnotation (pkgInstall , ExtYttDataValuesOverlaysAnnKey ),
106
- additionalPaths : secretNamesFromAnn (pkgInstall , ExtYttPathsFromSecretNameAnnKey ),
107
- },
108
- helmPatcher : & helmStepPatcher {
109
- additionalPaths : secretNamesFromAnn (pkgInstall , ExtHelmPathsFromSecretNameAnnKey ),
110
- name : pkgiAnnotationValue (pkgInstall , HelmTemplateOverlayNameKey ),
111
- namespace : pkgiAnnotationValue (pkgInstall , HelmTemplateOverlayNameSpaceKey ),
112
- },
113
- cuePatcher : & cueStepPatcher {},
114
-
115
109
templateSteps : desiredApp .Spec .Template ,
116
110
values : pkgInstall .Spec .Values ,
111
+ annotations : pkgInstall .Annotations ,
117
112
}
118
-
119
113
if err := templatesPatcher .patch (); err != nil {
120
114
return & v1alpha1.App {}, err
121
115
}
@@ -136,63 +130,10 @@ const (
136
130
stepClassCue stepClass = "cue"
137
131
)
138
132
139
- type yttStepPatcher struct {
140
- addValuesAsInlinePaths bool // TODO: support multiple ytt steps
141
- additionalPaths []string // TODO: support multiple ytt steps
142
- }
143
-
144
- func (yp * yttStepPatcher ) addValues (yttStep * kcv1alpha1.AppTemplateYtt , value pkgingv1alpha1.PackageInstallValues ) {
145
- if yp .addValuesAsInlinePaths {
146
- addSecretAsInlinePath (& yttStep .Inline , value .SecretRef .Name )
147
- } else {
148
- addSecretAsValueSource (& yttStep .ValuesFrom , value .SecretRef .Name )
149
- }
150
- }
151
-
152
- func (yp * yttStepPatcher ) addPaths (yttStep * kcv1alpha1.AppTemplateYtt ) {
153
- for _ , secretName := range yp .additionalPaths {
154
- addSecretAsInlinePath (& yttStep .Inline , secretName )
155
- }
156
- }
157
-
158
- type helmStepPatcher struct {
159
- additionalPaths []string
160
- name string // TODO: support multiple helm steps
161
- namespace string // TODO: support multiple helm steps
162
- }
163
-
164
- func (hp * helmStepPatcher ) addValues (helmStep * kcv1alpha1.AppTemplateHelmTemplate , value pkgingv1alpha1.PackageInstallValues ) {
165
- addSecretAsValueSource (& helmStep .ValuesFrom , value .SecretRef .Name )
166
- }
167
-
168
- func (hp * helmStepPatcher ) addPaths (helmStep * kcv1alpha1.AppTemplateHelmTemplate ) {
169
- for _ , secretName := range hp .additionalPaths {
170
- addSecretAsValueSource (& helmStep .ValuesFrom , secretName )
171
- }
172
- }
173
-
174
- func (hp * helmStepPatcher ) setNameAndNamespace (helmStep * kcv1alpha1.AppTemplateHelmTemplate ) {
175
- if hp .name != "" {
176
- helmStep .Name = hp .name
177
- }
178
- if hp .namespace != "" {
179
- helmStep .Namespace = hp .namespace
180
- }
181
- }
182
-
183
- type cueStepPatcher struct {}
184
-
185
- func (cp * cueStepPatcher ) addValues (cueStep * kcv1alpha1.AppTemplateCue , value pkgingv1alpha1.PackageInstallValues ) {
186
- addSecretAsValueSource (& cueStep .ValuesFrom , value .SecretRef .Name )
187
- }
188
-
189
133
type templateStepsPatcher struct {
190
134
templateSteps []kcv1alpha1.AppTemplate
191
135
values []pkgingv1alpha1.PackageInstallValues
192
-
193
- yttPatcher * yttStepPatcher
194
- helmPatcher * helmStepPatcher
195
- cuePatcher * cueStepPatcher
136
+ annotations map [string ]string
196
137
197
138
classifiedSteps [][]stepClass
198
139
once sync.Once
@@ -266,6 +207,18 @@ func (p *templateStepsPatcher) defaultStepIdxs(stepIdxs []int, class stepClass)
266
207
}
267
208
268
209
func (p * templateStepsPatcher ) patch () error {
210
+ if err := p .patchFromValues (); err != nil {
211
+ return err
212
+ }
213
+ p .patchFromYttAnnotations ()
214
+ p .patchFromHelmAnnotations ()
215
+
216
+ return nil
217
+ }
218
+
219
+ // patchFromValues patches all 'valueable' template steps with values from the
220
+ // packageInstall
221
+ func (p * templateStepsPatcher ) patchFromValues () error {
269
222
for _ , values := range p .values {
270
223
stepIdxs , err := p .defaultStepIdxs (values .TemplateSteps , stepClassValueable )
271
224
if err != nil {
@@ -284,36 +237,108 @@ func (p *templateStepsPatcher) patch() error {
284
237
285
238
switch {
286
239
case p .stepHasClass (stepIdx , stepClassYtt ):
287
- p .yttPatcher .addValues (templateStep .Ytt , values )
240
+ // ytt is a bit special: when we find the indexed annotation (or the
241
+ // naked one for the first ytt step) to apply the values as inline
242
+ // paths on the app, we do so; else, by default, we apply the pkgi's
243
+ // values as values on the app.
244
+ valuesAsPath := false
245
+ if firstYttStepIdx , ok := p .firstOf (stepClassYtt ); ok && stepIdx == firstYttStepIdx {
246
+ if _ , ok := p .annotations [ExtYttDataValuesOverlaysAnnKey ]; ok {
247
+ valuesAsPath = true
248
+ }
249
+ }
250
+ if _ , ok := p .annotations [fmt .Sprintf (ExtYttDataValuesOverlaysAnnKeyFmt , stepIdx )]; ok {
251
+ valuesAsPath = true
252
+ }
253
+ if valuesAsPath {
254
+ addSecretAsInlinePath (& templateStep .Ytt .Inline , values .SecretRef .Name )
255
+ } else {
256
+ addSecretAsValueSource (& templateStep .Ytt .ValuesFrom , values .SecretRef .Name )
257
+ }
288
258
289
259
case p .stepHasClass (stepIdx , stepClassHelm ):
290
- p . helmPatcher . addValues ( templateStep .HelmTemplate , values )
260
+ addSecretAsValueSource ( & templateStep .HelmTemplate . ValuesFrom , values . SecretRef . Name )
291
261
292
262
case p .stepHasClass (stepIdx , stepClassCue ):
293
- p . cuePatcher . addValues ( templateStep .Cue , values )
263
+ addSecretAsValueSource ( & templateStep .Cue . ValuesFrom , values . SecretRef . Name )
294
264
}
295
265
}
296
266
}
297
267
268
+ return nil
269
+ }
270
+
271
+ // patchFromYttAnnotations patches ytt template steps with values from
272
+ // annotations from the packageInstall
273
+ func (p * templateStepsPatcher ) patchFromYttAnnotations () {
274
+ firstYttIdx , hasYtt := p .firstOf (stepClassYtt )
275
+
276
+ if ! hasYtt {
277
+ return
278
+ }
279
+
280
+ patcher := func (ts * kcv1alpha1.AppTemplateYtt , pathsAnno string ) {
281
+ for _ , secretName := range secretNamesFromAnn (p .annotations , pathsAnno ) {
282
+ addSecretAsInlinePath (& ts .Inline , secretName )
283
+ }
284
+ }
285
+
298
286
for _ , stepIdx := range p .getClassifiedSteps (stepClassYtt ) {
299
- p .yttPatcher .addPaths (p .templateSteps [stepIdx ].Ytt )
300
- break // TODO: support multiple ytt steps
287
+ ts := p .templateSteps [stepIdx ].Ytt
288
+
289
+ if stepIdx == firstYttIdx {
290
+ // annotations that are not indexed are only applied to the first ytt
291
+ // step, so that we are backwards compatible
292
+ patcher (ts , ExtYttPathsFromSecretNameAnnKey )
293
+ }
294
+
295
+ patcher (ts , fmt .Sprintf (ExtYttPathsFromSecretNameAnnKeyFmt , stepIdx ))
296
+ }
297
+ }
298
+
299
+ // patchFromHelmAnnotations patches helm template steps with values from
300
+ // annotations from the packageInstall
301
+ func (p * templateStepsPatcher ) patchFromHelmAnnotations () {
302
+ firstHelmIdx , hasHelm := p .firstOf (stepClassHelm )
303
+
304
+ if ! hasHelm {
305
+ return
301
306
}
307
+
308
+ patcher := func (ts * kcv1alpha1.AppTemplateHelmTemplate , nameAnno , namespaceAnno , pathsAnno string ) {
309
+ if name , ok := p .annotations [nameAnno ]; ok && name != "" {
310
+ ts .Name = name
311
+ }
312
+ if namespace , ok := p .annotations [namespaceAnno ]; ok && namespace != "" {
313
+ ts .Namespace = namespace
314
+ }
315
+ for _ , secretName := range secretNamesFromAnn (p .annotations , pathsAnno ) {
316
+ addSecretAsValueSource (& ts .ValuesFrom , secretName )
317
+ }
318
+ }
319
+
302
320
for _ , stepIdx := range p .getClassifiedSteps (stepClassHelm ) {
303
321
ts := p .templateSteps [stepIdx ].HelmTemplate
304
- p .helmPatcher .addPaths (ts )
305
- p .helmPatcher .setNameAndNamespace (ts )
306
- break // TODO: support multiple helm steps
307
- }
308
322
309
- return nil
323
+ if stepIdx == firstHelmIdx {
324
+ // annotations that are not indexed are only applied to the first helm
325
+ // step, so that we are backwards compatible
326
+ patcher (ts , HelmTemplateOverlayNameKey , HelmTemplateOverlayNameSpaceKey , ExtHelmPathsFromSecretNameAnnKey )
327
+ }
328
+
329
+ patcher (ts ,
330
+ fmt .Sprintf (HelmTemplateOverlayNameKeyFmt , stepIdx ),
331
+ fmt .Sprintf (HelmTemplateOverlayNameSpaceKeyFmt , stepIdx ),
332
+ fmt .Sprintf (ExtHelmPathsFromSecretNameAnnKeyFmt , stepIdx ),
333
+ )
334
+ }
310
335
}
311
336
312
- func secretNamesFromAnn (installedPkg * pkgingv1alpha1. PackageInstall , annKey string ) []string {
337
+ func secretNamesFromAnn (annotations map [ string ] string , annKey string ) []string {
313
338
var suffixes []string
314
339
suffixToSecretName := map [string ]string {}
315
340
316
- for ann , secretName := range installedPkg . Annotations {
341
+ for ann , secretName := range annotations {
317
342
if ann == annKey {
318
343
suffix := ""
319
344
suffixToSecretName [suffix ] = secretName
@@ -334,18 +359,6 @@ func secretNamesFromAnn(installedPkg *pkgingv1alpha1.PackageInstall, annKey stri
334
359
return result
335
360
}
336
361
337
- func pkgiAnnotationValue (pkgi * pkgingv1alpha1.PackageInstall , key string ) string {
338
- if anno , found := pkgi .Annotations [key ]; found {
339
- return anno
340
- }
341
- return ""
342
- }
343
-
344
- func pkgiHasAnnotation (pkgi * pkgingv1alpha1.PackageInstall , key string ) bool {
345
- _ , found := pkgi .Annotations [key ]
346
- return found
347
- }
348
-
349
362
// addSecretAsInlinePath adds a secret as an inline path to the provided inline
350
363
// fetches. If the inline fetch is nil, it is initialized.
351
364
func addSecretAsInlinePath (inline * * kcv1alpha1.AppFetchInline , secretName string ) {
0 commit comments