From fe67bcdb8b458fa43bb8257f336255f23ebb50dd Mon Sep 17 00:00:00 2001 From: jregan Date: Wed, 22 May 2019 11:22:31 -0700 Subject: [PATCH] Cut more ties to k8sdeps Add tests for all the plugins. --- pkg/resmap/factory.go | 29 ++++++++++ plugin/builtin/ConfigMapGenerator.go | 5 +- plugin/builtin/ImageTagTransformer.go | 5 +- plugin/builtin/SecretGenerator.go | 5 +- .../configmapgenerator/ConfigMapGenerator.go | 5 +- .../ImageTagTransformer.go | 5 +- .../secretgenerator/SecretGenerator.go | 5 +- .../ConfigMapGenerator_test.go | 38 +++++++++++++ .../v1/dateprefixer/DatePrefixer_test.go | 39 ++++++++++++++ .../v1/kvmaker/kvMaker.go | 25 --------- .../v1/printworkdir/PrintWorkDir_test.go | 41 ++++++++++++++ .../SecretsFromDatabase.go | 54 +++++++++++++++++++ .../SecretsFromDatabase_test.go | 44 +++++++++++++++ .../SomeServiceGenerator.go | 7 ++- .../v1/stringprefixer/StringPrefixer_test.go | 39 ++++++++++++++ 15 files changed, 295 insertions(+), 51 deletions(-) create mode 100644 plugin/someteam.example.com/v1/configmapgenerator/ConfigMapGenerator_test.go create mode 100644 plugin/someteam.example.com/v1/dateprefixer/DatePrefixer_test.go delete mode 100644 plugin/someteam.example.com/v1/kvmaker/kvMaker.go create mode 100644 plugin/someteam.example.com/v1/printworkdir/PrintWorkDir_test.go create mode 100644 plugin/someteam.example.com/v1/secretsfromdatabase/SecretsFromDatabase.go create mode 100644 plugin/someteam.example.com/v1/secretsfromdatabase/SecretsFromDatabase_test.go create mode 100644 plugin/someteam.example.com/v1/stringprefixer/StringPrefixer_test.go diff --git a/pkg/resmap/factory.go b/pkg/resmap/factory.go index 1fe55597e..54a3c02ea 100644 --- a/pkg/resmap/factory.go +++ b/pkg/resmap/factory.go @@ -41,6 +41,13 @@ func (rmF *Factory) RF() *resource.Factory { return rmF.resF } +// FromResource returns a ResMap with one entry. +func (rmF *Factory) FromResource(res *resource.Resource) ResMap { + result := ResMap{} + result[res.Id()] = res + return result +} + // FromFile returns a ResMap given a resource path. func (rmF *Factory) FromFile( loader ifc.Loader, path string) (ResMap, error) { @@ -89,6 +96,17 @@ func (rmF *Factory) NewResMapFromConfigMapArgs( return newResMapFromResourceSlice(resources) } +func (rmF *Factory) FromConfigMapArgs( + ldr ifc.Loader, + options *types.GeneratorOptions, + args types.ConfigMapArgs) (ResMap, error) { + res, err := rmF.resF.MakeConfigMap(ldr, options, &args) + if err != nil { + return nil, err + } + return rmF.FromResource(res), nil +} + // NewResMapFromSecretArgs takes a SecretArgs slice, generates // secrets from each entry, and accumulates them in a ResMap. func (rmF *Factory) NewResMapFromSecretArgs( @@ -106,6 +124,17 @@ func (rmF *Factory) NewResMapFromSecretArgs( return newResMapFromResourceSlice(resources) } +func (rmF *Factory) FromSecretArgs( + ldr ifc.Loader, + options *types.GeneratorOptions, + args types.SecretArgs) (ResMap, error) { + res, err := rmF.resF.MakeSecret(ldr, options, &args) + if err != nil { + return nil, err + } + return rmF.FromResource(res), nil +} + func newResMapFromResourceSlice(resources []*resource.Resource) (ResMap, error) { result := ResMap{} for _, res := range resources { diff --git a/plugin/builtin/ConfigMapGenerator.go b/plugin/builtin/ConfigMapGenerator.go index 3981fe609..2859f23c6 100644 --- a/plugin/builtin/ConfigMapGenerator.go +++ b/plugin/builtin/ConfigMapGenerator.go @@ -30,8 +30,5 @@ func (p *ConfigMapGeneratorPlugin) Config( } func (p *ConfigMapGeneratorPlugin) Generate() (resmap.ResMap, error) { - argsList := make([]types.ConfigMapArgs, 1) - argsList[0] = p.ConfigMapArgs - return p.rf.NewResMapFromConfigMapArgs( - p.ldr, &p.GeneratorOptions, argsList) + return p.rf.FromConfigMapArgs(p.ldr, &p.GeneratorOptions, p.ConfigMapArgs) } diff --git a/plugin/builtin/ImageTagTransformer.go b/plugin/builtin/ImageTagTransformer.go index 80ba6b371..c27fe200e 100644 --- a/plugin/builtin/ImageTagTransformer.go +++ b/plugin/builtin/ImageTagTransformer.go @@ -29,9 +29,8 @@ func (p *ImageTagTransformerPlugin) Config( } func (p *ImageTagTransformerPlugin) Transform(m resmap.ResMap) error { - argsList := make([]image.Image, 1) - argsList[0] = p.ImageTag - t, err := transformers.NewImageTransformer(argsList, p.FieldSpecs) + t, err := transformers.NewImageTransformer( + []image.Image{p.ImageTag}, p.FieldSpecs) if err != nil { return err } diff --git a/plugin/builtin/SecretGenerator.go b/plugin/builtin/SecretGenerator.go index 3dd955d14..7cea56c36 100644 --- a/plugin/builtin/SecretGenerator.go +++ b/plugin/builtin/SecretGenerator.go @@ -30,8 +30,5 @@ func (p *SecretGeneratorPlugin) Config( } func (p *SecretGeneratorPlugin) Generate() (resmap.ResMap, error) { - argsList := make([]types.SecretArgs, 1) - argsList[0] = p.SecretArgs - return p.rf.NewResMapFromSecretArgs( - p.ldr, &p.GeneratorOptions, argsList) + return p.rf.FromSecretArgs(p.ldr, &p.GeneratorOptions, p.SecretArgs) } diff --git a/plugin/builtin/configmapgenerator/ConfigMapGenerator.go b/plugin/builtin/configmapgenerator/ConfigMapGenerator.go index fd1e3f92e..6664a275f 100644 --- a/plugin/builtin/configmapgenerator/ConfigMapGenerator.go +++ b/plugin/builtin/configmapgenerator/ConfigMapGenerator.go @@ -31,8 +31,5 @@ func (p *plugin) Config( } func (p *plugin) Generate() (resmap.ResMap, error) { - argsList := make([]types.ConfigMapArgs, 1) - argsList[0] = p.ConfigMapArgs - return p.rf.NewResMapFromConfigMapArgs( - p.ldr, &p.GeneratorOptions, argsList) + return p.rf.FromConfigMapArgs(p.ldr, &p.GeneratorOptions, p.ConfigMapArgs) } diff --git a/plugin/builtin/imagetagtransformer/ImageTagTransformer.go b/plugin/builtin/imagetagtransformer/ImageTagTransformer.go index f15721f5e..62c7726f9 100644 --- a/plugin/builtin/imagetagtransformer/ImageTagTransformer.go +++ b/plugin/builtin/imagetagtransformer/ImageTagTransformer.go @@ -30,9 +30,8 @@ func (p *plugin) Config( } func (p *plugin) Transform(m resmap.ResMap) error { - argsList := make([]image.Image, 1) - argsList[0] = p.ImageTag - t, err := transformers.NewImageTransformer(argsList, p.FieldSpecs) + t, err := transformers.NewImageTransformer( + []image.Image{p.ImageTag}, p.FieldSpecs) if err != nil { return err } diff --git a/plugin/builtin/secretgenerator/SecretGenerator.go b/plugin/builtin/secretgenerator/SecretGenerator.go index c7a5baabd..6240ce1af 100644 --- a/plugin/builtin/secretgenerator/SecretGenerator.go +++ b/plugin/builtin/secretgenerator/SecretGenerator.go @@ -31,8 +31,5 @@ func (p *plugin) Config( } func (p *plugin) Generate() (resmap.ResMap, error) { - argsList := make([]types.SecretArgs, 1) - argsList[0] = p.SecretArgs - return p.rf.NewResMapFromSecretArgs( - p.ldr, &p.GeneratorOptions, argsList) + return p.rf.FromSecretArgs(p.ldr, &p.GeneratorOptions, p.SecretArgs) } diff --git a/plugin/someteam.example.com/v1/configmapgenerator/ConfigMapGenerator_test.go b/plugin/someteam.example.com/v1/configmapgenerator/ConfigMapGenerator_test.go new file mode 100644 index 000000000..d9ea5fd74 --- /dev/null +++ b/plugin/someteam.example.com/v1/configmapgenerator/ConfigMapGenerator_test.go @@ -0,0 +1,38 @@ +// Copyright 2019 The Kubernetes Authors. +// SPDX-License-Identifier: Apache-2.0 + +package main_test + +import ( + "testing" + + "sigs.k8s.io/kustomize/pkg/kusttest" + "sigs.k8s.io/kustomize/plugin" +) + +func TestConfigMapGeneratorPlugin(t *testing.T) { + tc := plugin.NewEnvForTest(t).Set() + defer tc.Reset() + + tc.BuildExecPlugin( + "someteam.example.com", "v1", "ConfigMapGenerator") + + th := kusttest_test.NewKustTestPluginHarness(t, "/app") + + m := th.LoadAndRunGenerator(` +apiVersion: someteam.example.com/v1 +kind: ConfigMapGenerator +metadata: + name: whatever +argsOneLiner: alice myMomsMaidenName +`) + th.AssertActualEqualsExpected(m, ` +apiVersion: v1 +data: + password: myMomsMaidenName + username: alice +kind: ConfigMap +metadata: + name: example-configmap-test +`) +} diff --git a/plugin/someteam.example.com/v1/dateprefixer/DatePrefixer_test.go b/plugin/someteam.example.com/v1/dateprefixer/DatePrefixer_test.go new file mode 100644 index 000000000..9771d9812 --- /dev/null +++ b/plugin/someteam.example.com/v1/dateprefixer/DatePrefixer_test.go @@ -0,0 +1,39 @@ +// Copyright 2019 The Kubernetes Authors. +// SPDX-License-Identifier: Apache-2.0 + +package main_test + +import ( + "testing" + + "sigs.k8s.io/kustomize/pkg/kusttest" + "sigs.k8s.io/kustomize/plugin" +) + +func TestDatePrefixerPlugin(t *testing.T) { + tc := plugin.NewEnvForTest(t).Set() + defer tc.Reset() + + tc.BuildGoPlugin( + "someteam.example.com", "v1", "DatePrefixer") + th := kusttest_test.NewKustTestPluginHarness(t, "/app") + + m := th.LoadAndRunTransformer(` +apiVersion: someteam.example.com/v1 +kind: DatePrefixer +metadata: + name: whatever +`, + `apiVersion: apps/v1 +kind: MeatBall +metadata: + name: meatball +`) + + th.AssertActualEqualsExpected(m, ` +apiVersion: apps/v1 +kind: MeatBall +metadata: + name: 2018-05-11-meatball +`) +} diff --git a/plugin/someteam.example.com/v1/kvmaker/kvMaker.go b/plugin/someteam.example.com/v1/kvmaker/kvMaker.go deleted file mode 100644 index 3af6d0631..000000000 --- a/plugin/someteam.example.com/v1/kvmaker/kvMaker.go +++ /dev/null @@ -1,25 +0,0 @@ -package kvmaker - -var database = map[string]string{ - "TREE": "oak", - "ROCKET": "Saturn V", - "FRUIT": "apple", - "VEGETABLE": "carrot", - "SIMPSON": "homer", -} - -type plugin struct{} - -var KVSource plugin - -func (p plugin) Get( - root string, args []string) (map[string]string, error) { - r := make(map[string]string) - for _, k := range args { - v, ok := database[k] - if ok { - r[k] = v - } - } - return r, nil -} diff --git a/plugin/someteam.example.com/v1/printworkdir/PrintWorkDir_test.go b/plugin/someteam.example.com/v1/printworkdir/PrintWorkDir_test.go new file mode 100644 index 000000000..3442e7e32 --- /dev/null +++ b/plugin/someteam.example.com/v1/printworkdir/PrintWorkDir_test.go @@ -0,0 +1,41 @@ +// Copyright 2019 The Kubernetes Authors. +// SPDX-License-Identifier: Apache-2.0 + +package main_test + +import ( + "strings" + "testing" + + "sigs.k8s.io/kustomize/pkg/kusttest" + "sigs.k8s.io/kustomize/plugin" +) + +func shouldContain(t *testing.T, s []byte, x string) { + if !strings.Contains(string(s), x) { + t.Fatalf("unable to find %s", x) + } +} + +func TestPrintWorkDirPlugin(t *testing.T) { + tc := plugin.NewEnvForTest(t).Set() + defer tc.Reset() + + tc.BuildExecPlugin( + "someteam.example.com", "v1", "PrintWorkDir") + + th := kusttest_test.NewKustTestPluginHarness(t, "/theAppRoot") + + m := th.LoadAndRunGenerator(` +apiVersion: someteam.example.com/v1 +kind: PrintWorkDir +metadata: + name: whatever +`) + a, err := m.EncodeAsYaml() + if err != nil { + t.Error(err) + } + shouldContain(t, a, "path: /theAppRoot") + shouldContain(t, a, "sigs.k8s.io/kustomize/plugin/someteam.example.com/v1/printworkdir") +} diff --git a/plugin/someteam.example.com/v1/secretsfromdatabase/SecretsFromDatabase.go b/plugin/someteam.example.com/v1/secretsfromdatabase/SecretsFromDatabase.go new file mode 100644 index 000000000..d3c08587f --- /dev/null +++ b/plugin/someteam.example.com/v1/secretsfromdatabase/SecretsFromDatabase.go @@ -0,0 +1,54 @@ +// Copyright 2019 The Kubernetes Authors. +// SPDX-License-Identifier: Apache-2.0 + +package main + +import ( + "sigs.k8s.io/kustomize/pkg/ifc" + "sigs.k8s.io/kustomize/pkg/resmap" + "sigs.k8s.io/kustomize/pkg/types" + "sigs.k8s.io/yaml" +) + +// A secret generator example that gets data +// from a database (simulated by a hardcoded map). +type plugin struct { + rf *resmap.Factory + ldr ifc.Loader + Name string `json:"name,omitempty" yaml:"name,omitempty"` + Namespace string `json:"namespace,omitempty" yaml:"namespace,omitempty"` + // List of keys to use in database lookups + Keys []string `json:"keys,omitempty" yaml:"keys,omitempty"` +} + +var KustomizePlugin plugin + +var database = map[string]string{ + "TREE": "oak", + "ROCKET": "SaturnV", + "FRUIT": "apple", + "VEGETABLE": "carrot", + "SIMPSON": "homer", +} + +func (p *plugin) Config( + ldr ifc.Loader, rf *resmap.Factory, c []byte) error { + p.rf = rf + return yaml.Unmarshal(c, p) +} + +// The plan here is to convert the plugin's input +// into the format used by the builtin secret generator plugin. +func (p *plugin) Generate() (resmap.ResMap, error) { + args := types.SecretArgs{} + args.Name = p.Name + args.Namespace = p.Namespace + for _, k := range p.Keys { + if v, ok := database[k]; ok { + args.LiteralSources = append( + args.LiteralSources, k+"="+v) + } + } + return p.rf.FromSecretArgs(p.ldr, nil, args) + +} diff --git a/plugin/someteam.example.com/v1/secretsfromdatabase/SecretsFromDatabase_test.go b/plugin/someteam.example.com/v1/secretsfromdatabase/SecretsFromDatabase_test.go new file mode 100644 index 000000000..2a4c467cc --- /dev/null +++ b/plugin/someteam.example.com/v1/secretsfromdatabase/SecretsFromDatabase_test.go @@ -0,0 +1,44 @@ +// Copyright 2019 The Kubernetes Authors. +// SPDX-License-Identifier: Apache-2.0 + +package main_test + +import ( + "testing" + + "sigs.k8s.io/kustomize/pkg/kusttest" + "sigs.k8s.io/kustomize/plugin" +) + +func TestSecretsFromDatabasePlugin(t *testing.T) { + tc := plugin.NewEnvForTest(t).Set() + defer tc.Reset() + + tc.BuildGoPlugin( + "someteam.example.com", "v1", "SecretsFromDatabase") + + th := kusttest_test.NewKustTestPluginHarness(t, "/app") + + m := th.LoadAndRunGenerator(` +apiVersion: someteam.example.com/v1 +kind: SecretsFromDatabase +metadata: + name: mySecretGenerator +name: forbiddenValues +namespace: production +keys: +- ROCKET +- VEGETABLE +`) + th.AssertActualEqualsExpected(m, ` +apiVersion: v1 +data: + ROCKET: U2F0dXJuVg== + VEGETABLE: Y2Fycm90 +kind: Secret +metadata: + name: forbiddenValues + namespace: production +type: Opaque +`) +} diff --git a/plugin/someteam.example.com/v1/someservicegenerator/SomeServiceGenerator.go b/plugin/someteam.example.com/v1/someservicegenerator/SomeServiceGenerator.go index e9adb0487..1104887e9 100644 --- a/plugin/someteam.example.com/v1/someservicegenerator/SomeServiceGenerator.go +++ b/plugin/someteam.example.com/v1/someservicegenerator/SomeServiceGenerator.go @@ -7,15 +7,14 @@ import ( "bytes" "text/template" - "sigs.k8s.io/kustomize/k8sdeps/kunstruct" "sigs.k8s.io/kustomize/pkg/ifc" "sigs.k8s.io/kustomize/pkg/resmap" - "sigs.k8s.io/kustomize/pkg/resource" "sigs.k8s.io/yaml" ) // A simple generator example. Makes one service. type plugin struct { + rf *resmap.Factory Name string `json:"name,omitempty" yaml:"name,omitempty"` Port string `json:"port,omitempty" yaml:"port,omitempty"` } @@ -38,6 +37,7 @@ spec: func (p *plugin) Config( ldr ifc.Loader, rf *resmap.Factory, config []byte) error { + p.rf = rf return yaml.Unmarshal(config, p) } @@ -48,6 +48,5 @@ func (p *plugin) Generate() (resmap.ResMap, error) { if err != nil { return nil, err } - rf := resmap.NewFactory(resource.NewFactory(kunstruct.NewKunstructuredFactoryImpl())) - return rf.NewResMapFromBytes(buf.Bytes()) + return p.rf.NewResMapFromBytes(buf.Bytes()) } diff --git a/plugin/someteam.example.com/v1/stringprefixer/StringPrefixer_test.go b/plugin/someteam.example.com/v1/stringprefixer/StringPrefixer_test.go new file mode 100644 index 000000000..687a0e142 --- /dev/null +++ b/plugin/someteam.example.com/v1/stringprefixer/StringPrefixer_test.go @@ -0,0 +1,39 @@ +// Copyright 2019 The Kubernetes Authors. +// SPDX-License-Identifier: Apache-2.0 + +package main_test + +import ( + "testing" + + "sigs.k8s.io/kustomize/pkg/kusttest" + "sigs.k8s.io/kustomize/plugin" +) + +func TestStringPrefixerPlugin(t *testing.T) { + tc := plugin.NewEnvForTest(t).Set() + defer tc.Reset() + + tc.BuildGoPlugin( + "someteam.example.com", "v1", "StringPrefixer") + th := kusttest_test.NewKustTestPluginHarness(t, "/app") + + m := th.LoadAndRunTransformer(` +apiVersion: someteam.example.com/v1 +kind: StringPrefixer +metadata: + name: wowsa +`, + `apiVersion: apps/v1 +kind: MeatBall +metadata: + name: meatball +`) + + th.AssertActualEqualsExpected(m, ` +apiVersion: apps/v1 +kind: MeatBall +metadata: + name: wowsa-meatball +`) +}