diff --git a/api/internal/plugins/loader/loader.go b/api/internal/plugins/loader/loader.go index 838e126db..93c8559d2 100644 --- a/api/internal/plugins/loader/loader.go +++ b/api/internal/plugins/loader/loader.go @@ -83,20 +83,24 @@ func (l *Loader) LoadGenerator( } func (l *Loader) LoadTransformers( - ldr ifc.Loader, v ifc.Validator, rm resmap.ResMap) ([]resmap.Transformer, error) { - var result []resmap.Transformer + ldr ifc.Loader, v ifc.Validator, rm resmap.ResMap) ([]*resmap.TransformerWithProperties, error) { + var result []*resmap.TransformerWithProperties for _, res := range rm.Resources() { t, err := l.LoadTransformer(ldr, v, res) if err != nil { return nil, err } - result = append(result, t) + transformerOrigin, err := resource.OriginFromCustomPlugin(res) + if err != nil { + return nil, err + } + result = append(result, &resmap.TransformerWithProperties{Transformer: t, Origin: transformerOrigin}) } return result, nil } func (l *Loader) LoadTransformer( - ldr ifc.Loader, v ifc.Validator, res *resource.Resource) (resmap.Transformer, error) { + ldr ifc.Loader, v ifc.Validator, res *resource.Resource) (*resmap.TransformerWithProperties, error) { c, err := l.loadAndConfigurePlugin(ldr, v, res) if err != nil { return nil, err @@ -105,7 +109,7 @@ func (l *Loader) LoadTransformer( if !ok { return nil, fmt.Errorf("plugin %s not a transformer", res.OrgId()) } - return t, nil + return &resmap.TransformerWithProperties{Transformer: t}, nil } func relativePluginPath(id resid.ResId) string { diff --git a/api/internal/target/kusttarget.go b/api/internal/target/kusttarget.go index 95c7849c4..152862d65 100644 --- a/api/internal/target/kusttarget.go +++ b/api/internal/target/kusttarget.go @@ -119,7 +119,7 @@ func (kt *KustTarget) MakeCustomizedResMap() (resmap.ResMap, error) { func (kt *KustTarget) makeCustomizedResMap() (resmap.ResMap, error) { var origin *resource.Origin - if utils.StringSliceContains(kt.kustomization.BuildMetadata, types.OriginAnnotations) { + if len(kt.kustomization.BuildMetadata) != 0 { origin = &resource.Origin{} } ra, err := kt.AccumulateTarget(origin) @@ -215,7 +215,7 @@ func (kt *KustTarget) accumulateTarget(ra *accumulator.ResAccumulator, origin *r if err != nil { return nil, err } - err = kt.runTransformers(ra) + err = kt.runTransformers(ra, origin) if err != nil { return nil, err } @@ -262,7 +262,6 @@ func (kt *KustTarget) runGenerators( return errors.Wrap(err, "loading generator plugins") } generators = append(generators, gs...) - for i, g := range generators { resMap, err := g.Generate() if err != nil { @@ -293,14 +292,13 @@ func (kt *KustTarget) configureExternalGenerators(origin *resource.Origin) ( // not an inline config generatorPaths = append(generatorPaths, p) continue - } else { - // inline config, track the origin - if origin != nil { - resources := rm.Resources() - for _, r := range resources { - r.SetOrigin(origin.Append(kt.kustFileName)) - rm.Replace(r) - } + } + // inline config, track the origin + if origin != nil { + resources := rm.Resources() + for _, r := range resources { + r.SetOrigin(origin.Append(kt.kustFileName)) + rm.Replace(r) } } ra.AppendAll(rm) @@ -312,23 +310,27 @@ func (kt *KustTarget) configureExternalGenerators(origin *resource.Origin) ( return kt.pLdr.LoadGenerators(kt.ldr, kt.validator, ra.ResMap()) } -func (kt *KustTarget) runTransformers(ra *accumulator.ResAccumulator) error { - var r []resmap.Transformer +func (kt *KustTarget) runTransformers(ra *accumulator.ResAccumulator, origin *resource.Origin) error { + var r []*resmap.TransformerWithProperties tConfig := ra.GetTransformerConfig() - lts, err := kt.configureBuiltinTransformers(tConfig) + lts, err := kt.configureBuiltinTransformers(tConfig, origin) if err != nil { return err } r = append(r, lts...) - lts, err = kt.configureExternalTransformers(kt.kustomization.Transformers) + lts, err = kt.configureExternalTransformers(kt.kustomization.Transformers, origin) if err != nil { return err } r = append(r, lts...) - return ra.Transform(newMultiTransformer(r)) + err = ra.Transform(newMultiTransformer(r)) + if err != nil { + return err + } + return nil } -func (kt *KustTarget) configureExternalTransformers(transformers []string) ([]resmap.Transformer, error) { +func (kt *KustTarget) configureExternalTransformers(transformers []string, origin *resource.Origin) ([]*resmap.TransformerWithProperties, error) { ra := accumulator.MakeEmptyAccumulator() var transformerPaths []string for _, p := range transformers { @@ -339,9 +341,17 @@ func (kt *KustTarget) configureExternalTransformers(transformers []string) ([]re transformerPaths = append(transformerPaths, p) continue } + // inline config, track the origin + if origin != nil { + resources := rm.Resources() + for _, r := range resources { + r.SetOrigin(origin.Append(kt.kustFileName)) + rm.Replace(r) + } + } ra.AppendAll(rm) } - ra, err := kt.accumulateResources(ra, transformerPaths, &resource.Origin{}) + ra, err := kt.accumulateResources(ra, transformerPaths, origin) if err != nil { return nil, err } @@ -349,7 +359,7 @@ func (kt *KustTarget) configureExternalTransformers(transformers []string) ([]re } func (kt *KustTarget) runValidators(ra *accumulator.ResAccumulator) error { - validators, err := kt.configureExternalTransformers(kt.kustomization.Validators) + validators, err := kt.configureExternalTransformers(kt.kustomization.Validators, nil) if err != nil { return err } diff --git a/api/internal/target/kusttarget_configplugin.go b/api/internal/target/kusttarget_configplugin.go index 9da09fcd9..cdada6295 100644 --- a/api/internal/target/kusttarget_configplugin.go +++ b/api/internal/target/kusttarget_configplugin.go @@ -66,8 +66,8 @@ func (kt *KustTarget) configureBuiltinGenerators(origin *resource.Origin) ( } func (kt *KustTarget) configureBuiltinTransformers( - tc *builtinconfig.TransformerConfig) ( - result []resmap.Transformer, err error) { + tc *builtinconfig.TransformerConfig, origin *resource.Origin) ( + result []*resmap.TransformerWithProperties, err error) { for _, bpt := range []builtinhelpers.BuiltinPluginType{ builtinhelpers.PatchStrategicMergeTransformer, builtinhelpers.PatchTransformer, @@ -86,7 +86,23 @@ func (kt *KustTarget) configureBuiltinTransformers( if err != nil { return nil, err } - result = append(result, r...) + var transformerOrigin *resource.Origin + if origin != nil { + transformerOrigin = &resource.Origin{ + Repo: origin.Repo, + Ref: origin.Ref, + ConfiguredIn: filepath.Join(origin.Path, kt.kustFileName), + ConfiguredBy: yaml.ResourceIdentifier{ + TypeMeta: yaml.TypeMeta{ + APIVersion: "builtin", + Kind: bpt.String(), + }, + }, + } + } + for i := range r { + result = append(result, &resmap.TransformerWithProperties{Transformer: r[i], Origin: transformerOrigin}) + } } return result, nil } @@ -169,6 +185,9 @@ var transformerConfigurators = map[builtinhelpers.BuiltinPluginType]func( builtinhelpers.NamespaceTransformer: func( kt *KustTarget, bpt builtinhelpers.BuiltinPluginType, f tFactory, tc *builtinconfig.TransformerConfig) ( result []resmap.Transformer, err error) { + if kt.kustomization.Namespace == "" { + return + } var c struct { types.ObjectMeta `json:"metadata,omitempty" yaml:"metadata,omitempty"` FieldSpecs []types.FieldSpec @@ -252,6 +271,9 @@ var transformerConfigurators = map[builtinhelpers.BuiltinPluginType]func( builtinhelpers.LabelTransformer: func( kt *KustTarget, bpt builtinhelpers.BuiltinPluginType, f tFactory, tc *builtinconfig.TransformerConfig) ( result []resmap.Transformer, err error) { + if len(kt.kustomization.Labels) == 0 && len(kt.kustomization.CommonLabels) == 0 { + return + } for _, label := range kt.kustomization.Labels { var c struct { Labels map[string]string @@ -294,6 +316,9 @@ var transformerConfigurators = map[builtinhelpers.BuiltinPluginType]func( builtinhelpers.AnnotationsTransformer: func( kt *KustTarget, bpt builtinhelpers.BuiltinPluginType, f tFactory, tc *builtinconfig.TransformerConfig) ( result []resmap.Transformer, err error) { + if len(kt.kustomization.CommonAnnotations) == 0 { + return + } var c struct { Annotations map[string]string FieldSpecs []types.FieldSpec @@ -311,6 +336,9 @@ var transformerConfigurators = map[builtinhelpers.BuiltinPluginType]func( builtinhelpers.PrefixTransformer: func( kt *KustTarget, bpt builtinhelpers.BuiltinPluginType, f tFactory, tc *builtinconfig.TransformerConfig) ( result []resmap.Transformer, err error) { + if kt.kustomization.NamePrefix == "" { + return + } var c struct { Prefix string `json:"prefix,omitempty" yaml:"prefix,omitempty"` FieldSpecs []types.FieldSpec `json:"fieldSpecs,omitempty" yaml:"fieldSpecs,omitempty"` @@ -328,6 +356,9 @@ var transformerConfigurators = map[builtinhelpers.BuiltinPluginType]func( builtinhelpers.SuffixTransformer: func( kt *KustTarget, bpt builtinhelpers.BuiltinPluginType, f tFactory, tc *builtinconfig.TransformerConfig) ( result []resmap.Transformer, err error) { + if kt.kustomization.NameSuffix == "" { + return + } var c struct { Suffix string `json:"suffix,omitempty" yaml:"suffix,omitempty"` FieldSpecs []types.FieldSpec `json:"fieldSpecs,omitempty" yaml:"fieldSpecs,omitempty"` @@ -364,6 +395,9 @@ var transformerConfigurators = map[builtinhelpers.BuiltinPluginType]func( builtinhelpers.ReplacementTransformer: func( kt *KustTarget, bpt builtinhelpers.BuiltinPluginType, f tFactory, _ *builtinconfig.TransformerConfig) ( result []resmap.Transformer, err error) { + if len(kt.kustomization.Replacements) == 0 { + return + } var c struct { Replacements []types.ReplacementField } diff --git a/api/internal/target/multitransformer.go b/api/internal/target/multitransformer.go index caf1bd2de..3bc0a8715 100644 --- a/api/internal/target/multitransformer.go +++ b/api/internal/target/multitransformer.go @@ -9,15 +9,15 @@ import ( // multiTransformer contains a list of transformers. type multiTransformer struct { - transformers []resmap.Transformer + transformers []*resmap.TransformerWithProperties } var _ resmap.Transformer = &multiTransformer{} // newMultiTransformer constructs a multiTransformer. -func newMultiTransformer(t []resmap.Transformer) resmap.Transformer { +func newMultiTransformer(t []*resmap.TransformerWithProperties) resmap.Transformer { r := &multiTransformer{ - transformers: make([]resmap.Transformer, len(t)), + transformers: make([]*resmap.TransformerWithProperties, len(t)), } copy(r.transformers, t) return r @@ -30,6 +30,11 @@ func (o *multiTransformer) Transform(m resmap.ResMap) error { if err := t.Transform(m); err != nil { return err } + if t.Origin != nil { + if err := m.AddTransformerAnnotation(t.Origin); err != nil { + return err + } + } m.DropEmpties() } return nil diff --git a/api/internal/utils/annotations.go b/api/internal/utils/annotations.go index 3cc5d4140..34f3553af 100644 --- a/api/internal/utils/annotations.go +++ b/api/internal/utils/annotations.go @@ -20,7 +20,7 @@ const ( // for keeping track of origin and transformer data OriginAnnotationKey = "config.kubernetes.io/origin" - TransformerAnnotationKey = "config.kubernetes.io/transformations" + TransformerAnnotationKey = "alpha.config.kubernetes.io/transformations" Enabled = "enabled" ) diff --git a/api/krusty/helmchartinflationgenerator_test.go b/api/krusty/helmchartinflationgenerator_test.go index b49d84ce5..2f867b378 100644 --- a/api/krusty/helmchartinflationgenerator_test.go +++ b/api/krusty/helmchartinflationgenerator_test.go @@ -26,7 +26,6 @@ type: Opaque apiVersion: v1 kind: Service metadata: - annotations: {} labels: app: test-minecraft chart: minecraft-3.1.3 diff --git a/api/krusty/kustomizer.go b/api/krusty/kustomizer.go index 646a5c3f5..f2784155f 100644 --- a/api/krusty/kustomizer.go +++ b/api/krusty/kustomizer.go @@ -112,5 +112,11 @@ func (b *Kustomizer) Run( } } m.RemoveBuildAnnotations() + if !utils.StringSliceContains(kt.Kustomization().BuildMetadata, types.OriginAnnotations) { + m.RemoveOriginAnnotations() + } + if !utils.StringSliceContains(kt.Kustomization().BuildMetadata, types.TransformerAnnotations) { + m.RemoveTransformerAnnotations() + } return m, nil } diff --git a/api/krusty/originannotation_test.go b/api/krusty/originannotation_test.go index a293ff70f..7adbc9f54 100644 --- a/api/krusty/originannotation_test.go +++ b/api/krusty/originannotation_test.go @@ -1004,3 +1004,142 @@ metadata: name: bob-79t79mt227 `) } + +func TestAnnoOriginGeneratorInTransformersField(t *testing.T) { + fSys := filesys.MakeFsOnDisk() + + th := kusttest_test.MakeHarnessWithFs(t, fSys) + o := th.MakeOptionsPluginsEnabled() + o.PluginConfig.FnpLoadingOptions.EnableExec = true + + tmpDir, err := filesys.NewTmpConfirmedDir() + assert.NoError(t, err) + th.WriteK(tmpDir.String(), ` +transformers: +- gener.yaml +buildMetadata: [originAnnotations] +`) + + th.WriteF(filepath.Join(tmpDir.String(), "generateDeployment.sh"), generateDeploymentDotSh) + + assert.NoError(t, os.Chmod(filepath.Join(tmpDir.String(), "generateDeployment.sh"), 0777)) + th.WriteF(filepath.Join(tmpDir.String(), "gener.yaml"), ` +kind: executable +metadata: + name: demo + annotations: + config.kubernetes.io/function: | + exec: + path: ./generateDeployment.sh +spec: +`) + + m := th.Run(tmpDir.String(), o) + assert.NoError(t, err) + yml, err := m.AsYaml() + assert.NoError(t, err) + assert.Equal(t, `apiVersion: apps/v1 +kind: Deployment +metadata: + annotations: + config.kubernetes.io/origin: | + configuredIn: gener.yaml + configuredBy: + kind: executable + name: demo + tshirt-size: small + labels: + app: nginx + name: nginx +spec: + selector: + matchLabels: + app: nginx + template: + metadata: + labels: + app: nginx + spec: + containers: + - image: nginx + name: nginx +`, string(yml)) + assert.NoError(t, fSys.RemoveAll(tmpDir.String())) +} + +func TestAnnoOriginGeneratorInTransformersFieldWithOverlay(t *testing.T) { + fSys := filesys.MakeFsOnDisk() + + th := kusttest_test.MakeHarnessWithFs(t, fSys) + o := th.MakeOptionsPluginsEnabled() + o.PluginConfig.FnpLoadingOptions.EnableExec = true + + tmpDir, err := filesys.NewTmpConfirmedDir() + assert.NoError(t, err) + base := filepath.Join(tmpDir.String(), "base") + prod := filepath.Join(tmpDir.String(), "prod") + assert.NoError(t, fSys.Mkdir(base)) + assert.NoError(t, fSys.Mkdir(prod)) + + th.WriteK(base, ` +transformers: +- gener.yaml +`) + + th.WriteF(filepath.Join(base, "generateDeployment.sh"), generateDeploymentDotSh) + + assert.NoError(t, os.Chmod(filepath.Join(base, "generateDeployment.sh"), 0777)) + th.WriteF(filepath.Join(base, "gener.yaml"), ` +kind: executable +metadata: + name: demo + annotations: + config.kubernetes.io/function: | + exec: + path: ./generateDeployment.sh +spec: +`) + th.WriteK(prod, ` +resources: +- ../base +nameSuffix: -foo +buildMetadata: [originAnnotations, transformerAnnotations] +`) + + m := th.Run(prod, o) + assert.NoError(t, err) + yml, err := m.AsYaml() + assert.NoError(t, err) + assert.Equal(t, `apiVersion: apps/v1 +kind: Deployment +metadata: + annotations: + alpha.config.kubernetes.io/transformations: | + - configuredIn: kustomization.yaml + configuredBy: + apiVersion: builtin + kind: SuffixTransformer + config.kubernetes.io/origin: | + configuredIn: ../base/gener.yaml + configuredBy: + kind: executable + name: demo + tshirt-size: small + labels: + app: nginx + name: nginx-foo +spec: + selector: + matchLabels: + app: nginx + template: + metadata: + labels: + app: nginx + spec: + containers: + - image: nginx + name: nginx +`, string(yml)) + assert.NoError(t, fSys.RemoveAll(tmpDir.String())) +} diff --git a/api/krusty/transformerannotation_test.go b/api/krusty/transformerannotation_test.go new file mode 100644 index 000000000..d385fb94d --- /dev/null +++ b/api/krusty/transformerannotation_test.go @@ -0,0 +1,495 @@ +// Copyright 2019 The Kubernetes Authors. +// SPDX-License-Identifier: Apache-2.0 + +package krusty_test + +import ( + "os" + "path/filepath" + "testing" + + "github.com/stretchr/testify/assert" + "sigs.k8s.io/kustomize/api/internal/utils" + "sigs.k8s.io/kustomize/api/krusty" + kusttest_test "sigs.k8s.io/kustomize/api/testutils/kusttest" + "sigs.k8s.io/kustomize/kyaml/filesys" +) + +const generateDeploymentWithOriginDotSh = `#!/bin/sh + +cat <