diff --git a/api/internal/builtins/ReplacementTransformer.go b/api/internal/builtins/ReplacementTransformer.go index 21e42c81e4..7accb64bf2 100644 --- a/api/internal/builtins/ReplacementTransformer.go +++ b/api/internal/builtins/ReplacementTransformer.go @@ -5,6 +5,7 @@ package builtins import ( "fmt" + "reflect" "sigs.k8s.io/kustomize/api/filters/replacement" "sigs.k8s.io/kustomize/api/resmap" @@ -35,11 +36,29 @@ func (p *ReplacementTransformerPlugin) Config( if err != nil { return err } - repl := types.Replacement{} - if err := yaml.Unmarshal(content, &repl); err != nil { + // find if the path contains a a list of replacements or a single replacement + var replacement interface{} + err = yaml.Unmarshal(content, &replacement) + if err != nil { return err } - p.Replacements = append(p.Replacements, repl) + items := reflect.ValueOf(replacement) + switch items.Kind() { + case reflect.Slice: + repl := []types.Replacement{} + if err := yaml.Unmarshal(content, &repl); err != nil { + return err + } + p.Replacements = append(p.Replacements, repl...) + case reflect.Map: + repl := types.Replacement{} + if err := yaml.Unmarshal(content, &repl); err != nil { + return err + } + p.Replacements = append(p.Replacements, repl) + default: + return fmt.Errorf("unsupported replacement type encountered within replacement path: %v", items.Kind()) + } } else { // replacement information is already loaded p.Replacements = append(p.Replacements, r.Replacement) diff --git a/api/krusty/replacementtransformer_test.go b/api/krusty/replacementtransformer_test.go index 15c0888180..531962c005 100644 --- a/api/krusty/replacementtransformer_test.go +++ b/api/krusty/replacementtransformer_test.go @@ -110,6 +110,67 @@ spec: th.AssertActualEqualsExpected(m, expected) } +func TestReplacementsFieldWithPathMultiple(t *testing.T) { + th := kusttest_test.MakeEnhancedHarness(t) + defer th.Reset() + + th.WriteK(".", ` +resources: +- resource.yaml + +replacements: +- path: replacement.yaml +`) + th.WriteF("replacement.yaml", ` +- source: + kind: Deployment + fieldPath: spec.template.spec.containers.0.image + targets: + - select: + kind: Deployment + fieldPaths: + - spec.template.spec.containers.1.image +- source: + kind: Deployment + fieldPath: spec.template.spec.containers.0.name + targets: + - select: + kind: Deployment + fieldPaths: + - spec.template.spec.containers.1.name +`) + th.WriteF("resource.yaml", ` +apiVersion: apps/v1 +kind: Deployment +metadata: + name: deploy +spec: + template: + spec: + containers: + - image: foobar:1 + name: replaced-with-digest + - image: postgres:1.8.0 + name: postgresdb +`) + expected := ` +apiVersion: apps/v1 +kind: Deployment +metadata: + name: deploy +spec: + template: + spec: + containers: + - image: foobar:1 + name: replaced-with-digest + - image: foobar:1 + name: replaced-with-digest +` + m := th.Run(".", th.MakeDefaultOptions()) + th.AssertActualEqualsExpected(m, expected) +} + func TestReplacementTransformerWithDiamondShape(t *testing.T) { th := kusttest_test.MakeEnhancedHarness(t) defer th.Reset() diff --git a/plugin/builtin/replacementtransformer/ReplacementTransformer.go b/plugin/builtin/replacementtransformer/ReplacementTransformer.go index 595ef6bc23..1e4942949a 100644 --- a/plugin/builtin/replacementtransformer/ReplacementTransformer.go +++ b/plugin/builtin/replacementtransformer/ReplacementTransformer.go @@ -6,6 +6,7 @@ package main import ( "fmt" + "reflect" "sigs.k8s.io/kustomize/api/filters/replacement" "sigs.k8s.io/kustomize/api/resmap" @@ -39,11 +40,29 @@ func (p *plugin) Config( if err != nil { return err } - repl := types.Replacement{} - if err := yaml.Unmarshal(content, &repl); err != nil { + // find if the path contains a a list of replacements or a single replacement + var replacement interface{} + err = yaml.Unmarshal(content, &replacement) + if err != nil { return err } - p.Replacements = append(p.Replacements, repl) + items := reflect.ValueOf(replacement) + switch items.Kind() { + case reflect.Slice: + repl := []types.Replacement{} + if err := yaml.Unmarshal(content, &repl); err != nil { + return err + } + p.Replacements = append(p.Replacements, repl...) + case reflect.Map: + repl := types.Replacement{} + if err := yaml.Unmarshal(content, &repl); err != nil { + return err + } + p.Replacements = append(p.Replacements, repl) + default: + return fmt.Errorf("unsupported replacement type encountered within replacement path: %v", items.Kind()) + } } else { // replacement information is already loaded p.Replacements = append(p.Replacements, r.Replacement) diff --git a/plugin/builtin/replacementtransformer/ReplacementTransformer_test.go b/plugin/builtin/replacementtransformer/ReplacementTransformer_test.go index 07d19a772c..13bb9a3699 100644 --- a/plugin/builtin/replacementtransformer/ReplacementTransformer_test.go +++ b/plugin/builtin/replacementtransformer/ReplacementTransformer_test.go @@ -112,6 +112,68 @@ spec: `) } +func TestReplacementTransformerFromPathMultiple(t *testing.T) { + th := kusttest_test.MakeEnhancedHarness(t). + PrepBuiltin("ReplacementTransformer") + defer th.Reset() + + th.WriteF("replacement.yaml", ` +- source: + kind: Deployment + fieldPath: spec.template.spec.containers.0.image + targets: + - select: + kind: Deployment + fieldPaths: + - spec.template.spec.containers.1.image +- source: + kind: Deployment + fieldPath: spec.template.spec.containers.0.name + targets: + - select: + kind: Deployment + fieldPaths: + - spec.template.spec.containers.1.name`) + + rm := th.LoadAndRunTransformer(` +apiVersion: builtin +kind: ReplacementTransformer +metadata: + name: notImportantHere +replacements: +- path: replacement.yaml +`, ` +apiVersion: apps/v1 +kind: Deployment +metadata: + name: deploy +spec: + template: + spec: + containers: + - image: foobar:1 + name: replaced-with-digest + - image: postgres:1.8.0 + name: postgresdb + +`) + + th.AssertActualEqualsExpected(rm, ` +apiVersion: apps/v1 +kind: Deployment +metadata: + name: deploy +spec: + template: + spec: + containers: + - image: foobar:1 + name: replaced-with-digest + - image: foobar:1 + name: replaced-with-digest +`) +} + func TestReplacementTransformerComplexType(t *testing.T) { th := kusttest_test.MakeEnhancedHarness(t). PrepBuiltin("ReplacementTransformer")