diff --git a/api/builtins/ConfigMapGenerator.go b/api/builtins/ConfigMapGenerator.go index d84ee09d9..d853a1cfd 100644 --- a/api/builtins/ConfigMapGenerator.go +++ b/api/builtins/ConfigMapGenerator.go @@ -13,13 +13,10 @@ import ( type ConfigMapGeneratorPlugin struct { h *resmap.PluginHelpers types.ObjectMeta `json:"metadata,omitempty" yaml:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` - types.GeneratorOptions types.ConfigMapArgs } -func (p *ConfigMapGeneratorPlugin) Config( - h *resmap.PluginHelpers, config []byte) (err error) { - p.GeneratorOptions = types.GeneratorOptions{} +func (p *ConfigMapGeneratorPlugin) Config(h *resmap.PluginHelpers, config []byte) (err error) { p.ConfigMapArgs = types.ConfigMapArgs{} err = yaml.Unmarshal(config, p) if p.ConfigMapArgs.Name == "" { @@ -34,8 +31,7 @@ func (p *ConfigMapGeneratorPlugin) Config( func (p *ConfigMapGeneratorPlugin) Generate() (resmap.ResMap, error) { return p.h.ResmapFactory().FromConfigMapArgs( - kv.NewLoader(p.h.Loader(), p.h.Validator()), - &p.GeneratorOptions, p.ConfigMapArgs) + kv.NewLoader(p.h.Loader(), p.h.Validator()), p.ConfigMapArgs) } func NewConfigMapGeneratorPlugin() resmap.GeneratorPlugin { diff --git a/api/builtins/InventoryTransformer.go b/api/builtins/InventoryTransformer.go index 8052c99c0..4976e8916 100644 --- a/api/builtins/InventoryTransformer.go +++ b/api/builtins/InventoryTransformer.go @@ -55,26 +55,23 @@ func (p *InventoryTransformerPlugin) Config( // (e.g. some App object) become more desirable // for this purpose. func (p *InventoryTransformerPlugin) Transform(m resmap.ResMap) error { - inv, h, err := makeInventory(m) if err != nil { return err } - args := types.ConfigMapArgs{} args.Name = p.Name args.Namespace = p.Namespace - opts := &types.GeneratorOptions{ - Annotations: make(map[string]string), + args.Options = &types.GeneratorOptions{ + Annotations: map[string]string{inventory.HashAnnotation: h}, } - opts.Annotations[inventory.HashAnnotation] = h - err = inv.UpdateAnnotations(opts.Annotations) + err = inv.UpdateAnnotations(args.Options.Annotations) if err != nil { return err } cm, err := p.h.ResmapFactory().RF().MakeConfigMap( - kv.NewLoader(p.h.Loader(), p.h.Validator()), opts, &args) + kv.NewLoader(p.h.Loader(), p.h.Validator()), &args) if err != nil { return err } diff --git a/api/builtins/SecretGenerator.go b/api/builtins/SecretGenerator.go index 012d79830..5e8581eb9 100644 --- a/api/builtins/SecretGenerator.go +++ b/api/builtins/SecretGenerator.go @@ -13,12 +13,10 @@ import ( type SecretGeneratorPlugin struct { h *resmap.PluginHelpers types.ObjectMeta `json:"metadata,omitempty" yaml:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` - types.GeneratorOptions types.SecretArgs } func (p *SecretGeneratorPlugin) Config(h *resmap.PluginHelpers, config []byte) (err error) { - p.GeneratorOptions = types.GeneratorOptions{} p.SecretArgs = types.SecretArgs{} err = yaml.Unmarshal(config, p) if p.SecretArgs.Name == "" { @@ -33,8 +31,7 @@ func (p *SecretGeneratorPlugin) Config(h *resmap.PluginHelpers, config []byte) ( func (p *SecretGeneratorPlugin) Generate() (resmap.ResMap, error) { return p.h.ResmapFactory().FromSecretArgs( - kv.NewLoader(p.h.Loader(), p.h.Validator()), - &p.GeneratorOptions, p.SecretArgs) + kv.NewLoader(p.h.Loader(), p.h.Validator()), p.SecretArgs) } func NewSecretGeneratorPlugin() resmap.GeneratorPlugin { diff --git a/api/ifc/ifc.go b/api/ifc/ifc.go index 1a923bc8d..e0ac6679f 100644 --- a/api/ifc/ifc.go +++ b/api/ifc/ifc.go @@ -75,14 +75,8 @@ type KunstructuredFactory interface { SliceFromBytes([]byte) ([]Kunstructured, error) FromMap(m map[string]interface{}) Kunstructured Hasher() KunstructuredHasher - MakeConfigMap( - kvLdr KvLoader, - options *types.GeneratorOptions, - args *types.ConfigMapArgs) (Kunstructured, error) - MakeSecret( - kvLdr KvLoader, - options *types.GeneratorOptions, - args *types.SecretArgs) (Kunstructured, error) + MakeConfigMap(kvLdr KvLoader, args *types.ConfigMapArgs) (Kunstructured, error) + MakeSecret(kvLdr KvLoader, args *types.SecretArgs) (Kunstructured, error) } // KunstructuredHasher returns a hash of the argument diff --git a/api/internal/k8sdeps/configmapandsecret/configmapfactory.go b/api/internal/k8sdeps/configmapandsecret/configmapfactory.go index 74da4d381..4432c2320 100644 --- a/api/internal/k8sdeps/configmapandsecret/configmapfactory.go +++ b/api/internal/k8sdeps/configmapandsecret/configmapfactory.go @@ -25,8 +25,7 @@ func makeFreshConfigMap( } // MakeConfigMap returns a new ConfigMap, or nil and an error. -func (f *Factory) MakeConfigMap( - args *types.ConfigMapArgs) (*corev1.ConfigMap, error) { +func (f *Factory) MakeConfigMap(args *types.ConfigMapArgs) (*corev1.ConfigMap, error) { all, err := f.kvLdr.Load(args.KvPairSources) if err != nil { return nil, errors.Wrap(err, "loading KV pairs") @@ -38,7 +37,7 @@ func (f *Factory) MakeConfigMap( return nil, errors.Wrap(err, "trouble mapping") } } - f.setLabelsAndAnnnotations(cm, args.GeneratorOptions) + f.copyLabelsAndAnnotations(cm, args.Options) return cm, nil } diff --git a/api/internal/k8sdeps/configmapandsecret/configmapfactory_test.go b/api/internal/k8sdeps/configmapandsecret/configmapfactory_test.go index 023e00be2..c410568bd 100644 --- a/api/internal/k8sdeps/configmapandsecret/configmapfactory_test.go +++ b/api/internal/k8sdeps/configmapandsecret/configmapfactory_test.go @@ -82,7 +82,6 @@ func TestConstructConfigMap(t *testing.T) { type testCase struct { description string input types.ConfigMapArgs - options *types.GeneratorOptions expected *corev1.ConfigMap } @@ -99,7 +98,6 @@ func TestConstructConfigMap(t *testing.T) { }, }, }, - options: nil, expected: makeEnvConfigMap("envConfigMap"), }, { @@ -115,7 +113,6 @@ func TestConstructConfigMap(t *testing.T) { }, }, }, - options: nil, expected: makeFileConfigMap("fileConfigMap"), }, { @@ -126,11 +123,11 @@ func TestConstructConfigMap(t *testing.T) { KvPairSources: types.KvPairSources{ LiteralSources: []string{"a=x", "b=y", "c=\"Hello World\"", "d='true'"}, }, - }, - }, - options: &types.GeneratorOptions{ - Labels: map[string]string{ - "foo": "bar", + Options: &types.GeneratorOptions{ + Labels: map[string]string{ + "foo": "bar", + }, + }, }, }, expected: makeLiteralConfigMap("literalConfigMap", map[string]string{ @@ -145,7 +142,7 @@ func TestConstructConfigMap(t *testing.T) { KvPairSources: types.KvPairSources{ LiteralSources: []string{"a=x", "b=y", "c=\"Hello World\"", "d='true'"}, }, - GeneratorOptions: &types.GeneratorOptions{ + Options: &types.GeneratorOptions{ Labels: map[string]string{ "foo": "changed", "cat": "dog", @@ -157,18 +154,6 @@ func TestConstructConfigMap(t *testing.T) { }, }, }, - options: &types.GeneratorOptions{ - Labels: map[string]string{ - "foo": "bar", - }, - Annotations: map[string]string{ - "foo": "bar", - }, - }, - // GeneratorOptions from the ConfigMapArgs take precedence over the - // factory level GeneratorOptions and should overwrite - // labels/annotations set in the factory level if there are common - // labels/annotations expected: makeLiteralConfigMap("literalConfigMap", map[string]string{ "foo": "changed", "cat": "dog", @@ -193,8 +178,7 @@ func TestConstructConfigMap(t *testing.T) { loader.NewFileLoaderAtRoot(fSys), valtest_test.MakeFakeValidator()) for _, tc := range testCases { - f := NewFactory(kvLdr, tc.options) - cm, err := f.MakeConfigMap(&tc.input) + cm, err := NewFactory(kvLdr).MakeConfigMap(&tc.input) if err != nil { t.Fatalf("unexpected error: %v", err) } diff --git a/api/internal/k8sdeps/configmapandsecret/factory.go b/api/internal/k8sdeps/configmapandsecret/factory.go index 2576b4449..a6da8c4f0 100644 --- a/api/internal/k8sdeps/configmapandsecret/factory.go +++ b/api/internal/k8sdeps/configmapandsecret/factory.go @@ -11,44 +11,26 @@ import ( // Factory makes ConfigMaps and Secrets. type Factory struct { - kvLdr ifc.KvLoader - options *types.GeneratorOptions + kvLdr ifc.KvLoader } // NewFactory returns a new factory that makes ConfigMaps and Secrets. -func NewFactory( - kvLdr ifc.KvLoader, o *types.GeneratorOptions) *Factory { - return &Factory{kvLdr: kvLdr, options: o} +func NewFactory(kvLdr ifc.KvLoader) *Factory { + return &Factory{kvLdr: kvLdr} } -// setLabelsAndAnnnotations will take the labels and annotations from -// global GeneratorOptions and resource level GeneratorOptions and merge them -// with the resource level taking precedence, and then set them on the provided -// obj. -func (f *Factory) setLabelsAndAnnnotations(obj metav1.Object, opts *types.GeneratorOptions) { - labels := make(map[string]string) - annotations := make(map[string]string) - if f.options != nil { - for k, v := range f.options.Labels { - labels[k] = v - } - for k, v := range f.options.Annotations { - annotations[k] = v - } +// copyLabelsAndAnnotations copies labels and annotations from +// GeneratorOptions into the given object. +func (f *Factory) copyLabelsAndAnnotations( + obj metav1.Object, opts *types.GeneratorOptions) { + if opts == nil { + return } - if opts != nil { - for k, v := range opts.Labels { - labels[k] = v - } - for k, v := range opts.Annotations { - annotations[k] = v - } + if opts.Labels != nil { + obj.SetLabels(types.CopyMap(opts.Labels)) } - if len(labels) != 0 { - obj.SetLabels(labels) - } - if len(annotations) != 0 { - obj.SetAnnotations(annotations) + if opts.Annotations != nil { + obj.SetAnnotations(types.CopyMap(opts.Annotations)) } } diff --git a/api/internal/k8sdeps/configmapandsecret/secretfactory.go b/api/internal/k8sdeps/configmapandsecret/secretfactory.go index 487273620..d51609043 100644 --- a/api/internal/k8sdeps/configmapandsecret/secretfactory.go +++ b/api/internal/k8sdeps/configmapandsecret/secretfactory.go @@ -26,8 +26,7 @@ func makeFreshSecret( } // MakeSecret returns a new secret. -func (f *Factory) MakeSecret( - args *types.SecretArgs) (*corev1.Secret, error) { +func (f *Factory) MakeSecret(args *types.SecretArgs) (*corev1.Secret, error) { all, err := f.kvLdr.Load(args.KvPairSources) if err != nil { return nil, err @@ -39,7 +38,7 @@ func (f *Factory) MakeSecret( return nil, err } } - f.setLabelsAndAnnnotations(s, args.GeneratorOptions) + f.copyLabelsAndAnnotations(s, args.Options) return s, nil } diff --git a/api/internal/k8sdeps/configmapandsecret/secretfactory_test.go b/api/internal/k8sdeps/configmapandsecret/secretfactory_test.go index beb51c7c9..0720e8386 100644 --- a/api/internal/k8sdeps/configmapandsecret/secretfactory_test.go +++ b/api/internal/k8sdeps/configmapandsecret/secretfactory_test.go @@ -79,7 +79,6 @@ func TestConstructSecret(t *testing.T) { type testCase struct { description string input types.SecretArgs - options *types.GeneratorOptions expected *corev1.Secret } @@ -94,7 +93,6 @@ func TestConstructSecret(t *testing.T) { }, }, }, - options: nil, expected: makeEnvSecret("envSecret"), }, { @@ -107,7 +105,6 @@ func TestConstructSecret(t *testing.T) { }, }, }, - options: nil, expected: makeFileSecret("fileSecret"), }, { @@ -118,55 +115,22 @@ func TestConstructSecret(t *testing.T) { KvPairSources: types.KvPairSources{ LiteralSources: []string{"a=x", "b=y"}, }, - }, - }, - options: &types.GeneratorOptions{ - Labels: map[string]string{ - "foo": "bar", + Options: &types.GeneratorOptions{ + Labels: map[string]string{ + "foo": "bar", + }, + Annotations: map[string]string{ + "fruit": "banana", + "pet": "dog", + }, + }, }, }, expected: makeLiteralSecret("literalSecret", map[string]string{ "foo": "bar", - }, nil), - }, - { - description: "construct secret from literal with GeneratorOptions in SecretArgs", - input: types.SecretArgs{ - GeneratorArgs: types.GeneratorArgs{ - Name: "literalSecret", - KvPairSources: types.KvPairSources{ - LiteralSources: []string{"a=x", "b=y"}, - }, - GeneratorOptions: &types.GeneratorOptions{ - Labels: map[string]string{ - "foo": "changed", - "cat": "dog", - }, - Annotations: map[string]string{ - "foo": "changed", - "cat": "dog", - }, - }, - }, - }, - options: &types.GeneratorOptions{ - Labels: map[string]string{ - "foo": "bar", - }, - Annotations: map[string]string{ - "foo": "bar", - }, - }, - // GeneratorOptions from the SecretArgs take precedence over the - // factory level GeneratorOptions and should overwrite - // labels/annotations set in the factory level if there are common - // labels/annotations - expected: makeLiteralSecret("literalSecret", map[string]string{ - "foo": "changed", - "cat": "dog", }, map[string]string{ - "foo": "changed", - "cat": "dog", + "fruit": "banana", + "pet": "dog", }), }, } @@ -178,7 +142,7 @@ func TestConstructSecret(t *testing.T) { loader.NewFileLoaderAtRoot(fSys), valtest_test.MakeFakeValidator()) for _, tc := range testCases { - f := NewFactory(kvLdr, tc.options) + f := NewFactory(kvLdr) cm, err := f.MakeSecret(&tc.input) if err != nil { t.Fatalf("unexpected error: %v", err) diff --git a/api/internal/plugins/execplugin/execplugin.go b/api/internal/plugins/execplugin/execplugin.go index c8fc8e25d..d780121e6 100644 --- a/api/internal/plugins/execplugin/execplugin.go +++ b/api/internal/plugins/execplugin/execplugin.go @@ -266,8 +266,9 @@ func (p *ExecPlugin) UpdateResourceOptions(rm resmap.ResMap) (resmap.ResMap, err } r.SetAnnotations(annotations) r.SetOptions(types.NewGenArgs( - &types.GeneratorArgs{Behavior: behavior}, - &types.GeneratorOptions{DisableNameSuffixHash: !needsHash})) + &types.GeneratorArgs{ + Behavior: behavior, + Options: &types.GeneratorOptions{DisableNameSuffixHash: !needsHash}})) } return rm, nil } diff --git a/api/internal/plugins/execplugin/execplugin_test.go b/api/internal/plugins/execplugin/execplugin_test.go index bb261297c..249571dd7 100644 --- a/api/internal/plugins/execplugin/execplugin_test.go +++ b/api/internal/plugins/execplugin/execplugin_test.go @@ -116,7 +116,9 @@ func makeConfigMapOptions(rf *resource.Factory, name, behavior string, disableHa "apiVersion": "v1", "kind": "ConfigMap", "metadata": map[string]interface{}{"name": name}, - }, &types.GeneratorArgs{Behavior: behavior}, &types.GeneratorOptions{DisableNameSuffixHash: disableHash}) + }, &types.GeneratorArgs{ + Behavior: behavior, + Options: &types.GeneratorOptions{DisableNameSuffixHash: disableHash}}) } func strptr(s string) *string { diff --git a/api/internal/target/kusttarget_configplugin.go b/api/internal/target/kusttarget_configplugin.go index 60fb9afa5..320072423 100644 --- a/api/internal/target/kusttarget_configplugin.go +++ b/api/internal/target/kusttarget_configplugin.go @@ -74,14 +74,12 @@ var generatorConfigurators = map[builtinhelpers.BuiltinPluginType]func( builtinhelpers.SecretGenerator: func(kt *KustTarget, bpt builtinhelpers.BuiltinPluginType, f gFactory) ( result []resmap.Generator, err error) { var c struct { - types.GeneratorOptions types.SecretArgs } - if kt.kustomization.GeneratorOptions != nil { - c.GeneratorOptions = *kt.kustomization.GeneratorOptions - } for _, args := range kt.kustomization.SecretGenerator { c.SecretArgs = args + c.SecretArgs.Options = types.MergeGlobalOptionsIntoLocal( + c.SecretArgs.Options, kt.kustomization.GeneratorOptions) p := f() err := kt.configureBuiltinPlugin(p, c, bpt) if err != nil { @@ -95,14 +93,12 @@ var generatorConfigurators = map[builtinhelpers.BuiltinPluginType]func( builtinhelpers.ConfigMapGenerator: func(kt *KustTarget, bpt builtinhelpers.BuiltinPluginType, f gFactory) ( result []resmap.Generator, err error) { var c struct { - types.GeneratorOptions types.ConfigMapArgs } - if kt.kustomization.GeneratorOptions != nil { - c.GeneratorOptions = *kt.kustomization.GeneratorOptions - } for _, args := range kt.kustomization.ConfigMapGenerator { c.ConfigMapArgs = args + c.ConfigMapArgs.Options = types.MergeGlobalOptionsIntoLocal( + c.ConfigMapArgs.Options, kt.kustomization.GeneratorOptions) p := f() err := kt.configureBuiltinPlugin(p, c, bpt) if err != nil { diff --git a/api/k8sdeps/kunstruct/factory.go b/api/k8sdeps/kunstruct/factory.go index 392ba55ea..f26f93dd4 100644 --- a/api/k8sdeps/kunstruct/factory.go +++ b/api/k8sdeps/kunstruct/factory.go @@ -75,11 +75,8 @@ func (kf *KunstructuredFactoryImpl) FromMap( // MakeConfigMap returns an instance of Kunstructured for ConfigMap func (kf *KunstructuredFactoryImpl) MakeConfigMap( - kvLdr ifc.KvLoader, - options *types.GeneratorOptions, - args *types.ConfigMapArgs) (ifc.Kunstructured, error) { - o, err := configmapandsecret.NewFactory( - kvLdr, options).MakeConfigMap(args) + kvLdr ifc.KvLoader, args *types.ConfigMapArgs) (ifc.Kunstructured, error) { + o, err := configmapandsecret.NewFactory(kvLdr).MakeConfigMap(args) if err != nil { return nil, err } @@ -88,11 +85,8 @@ func (kf *KunstructuredFactoryImpl) MakeConfigMap( // MakeSecret returns an instance of Kunstructured for Secret func (kf *KunstructuredFactoryImpl) MakeSecret( - kvLdr ifc.KvLoader, - options *types.GeneratorOptions, - args *types.SecretArgs) (ifc.Kunstructured, error) { - o, err := configmapandsecret.NewFactory( - kvLdr, options).MakeSecret(args) + kvLdr ifc.KvLoader, args *types.SecretArgs) (ifc.Kunstructured, error) { + o, err := configmapandsecret.NewFactory(kvLdr).MakeSecret(args) if err != nil { return nil, err } diff --git a/api/krusty/complexcomposition_test.go b/api/krusty/complexcomposition_test.go index d680be96c..f1a50eab7 100644 --- a/api/krusty/complexcomposition_test.go +++ b/api/krusty/complexcomposition_test.go @@ -143,7 +143,8 @@ apiVersion: builtin kind: ConfigMapGenerator metadata: name: my-config -disableNameSuffixHash: true +options: + disableNameSuffixHash: true literals: - MY_ENV=foo `) diff --git a/api/resmap/factory.go b/api/resmap/factory.go index 0975ca1e8..b779bb67f 100644 --- a/api/resmap/factory.go +++ b/api/resmap/factory.go @@ -66,12 +66,10 @@ func (rmF *Factory) NewResMapFromBytes(b []byte) (ResMap, error) { // NewResMapFromConfigMapArgs returns a Resource slice given // a configmap metadata slice from kustomization file. func (rmF *Factory) NewResMapFromConfigMapArgs( - kvLdr ifc.KvLoader, - options *types.GeneratorOptions, - argList []types.ConfigMapArgs) (ResMap, error) { + kvLdr ifc.KvLoader, argList []types.ConfigMapArgs) (ResMap, error) { var resources []*resource.Resource for _, args := range argList { - res, err := rmF.resF.MakeConfigMap(kvLdr, options, &args) + res, err := rmF.resF.MakeConfigMap(kvLdr, &args) if err != nil { return nil, errors.Wrap(err, "NewResMapFromConfigMapArgs") } @@ -81,10 +79,8 @@ func (rmF *Factory) NewResMapFromConfigMapArgs( } func (rmF *Factory) FromConfigMapArgs( - kvLdr ifc.KvLoader, - options *types.GeneratorOptions, - args types.ConfigMapArgs) (ResMap, error) { - res, err := rmF.resF.MakeConfigMap(kvLdr, options, &args) + kvLdr ifc.KvLoader, args types.ConfigMapArgs) (ResMap, error) { + res, err := rmF.resF.MakeConfigMap(kvLdr, &args) if err != nil { return nil, err } @@ -94,12 +90,10 @@ func (rmF *Factory) FromConfigMapArgs( // NewResMapFromSecretArgs takes a SecretArgs slice, generates // secrets from each entry, and accumulates them in a ResMap. func (rmF *Factory) NewResMapFromSecretArgs( - kvLdr ifc.KvLoader, - options *types.GeneratorOptions, - argsList []types.SecretArgs) (ResMap, error) { + kvLdr ifc.KvLoader, argsList []types.SecretArgs) (ResMap, error) { var resources []*resource.Resource for _, args := range argsList { - res, err := rmF.resF.MakeSecret(kvLdr, options, &args) + res, err := rmF.resF.MakeSecret(kvLdr, &args) if err != nil { return nil, errors.Wrap(err, "NewResMapFromSecretArgs") } @@ -109,10 +103,8 @@ func (rmF *Factory) NewResMapFromSecretArgs( } func (rmF *Factory) FromSecretArgs( - kvLdr ifc.KvLoader, - options *types.GeneratorOptions, - args types.SecretArgs) (ResMap, error) { - res, err := rmF.resF.MakeSecret(kvLdr, options, &args) + kvLdr ifc.KvLoader, args types.SecretArgs) (ResMap, error) { + res, err := rmF.resF.MakeSecret(kvLdr, &args) if err != nil { return nil, err } diff --git a/api/resmap/factory_test.go b/api/resmap/factory_test.go index 3959086cf..aee067ee5 100644 --- a/api/resmap/factory_test.go +++ b/api/resmap/factory_test.go @@ -227,7 +227,7 @@ BAR=baz t.Fatalf("error adding file '%s': %v\n", tc.filepath, fErr) } } - r, err := rmF.NewResMapFromConfigMapArgs(kvLdr, nil, tc.input) + r, err := rmF.NewResMapFromConfigMapArgs(kvLdr, tc.input) if err != nil { t.Fatalf("unexpected error: %v", err) } @@ -258,7 +258,7 @@ func TestNewResMapFromSecretArgs(t *testing.T) { actual, err := rmF.NewResMapFromSecretArgs( kv.NewLoader( loader.NewFileLoaderAtRoot(fSys), - valtest_test.MakeFakeValidator()), nil, secrets) + valtest_test.MakeFakeValidator()), secrets) if err != nil { t.Fatalf("unexpected error: %v", err) } diff --git a/api/resmap/resmap_test.go b/api/resmap/resmap_test.go index 29b4f7815..ee6af8e1b 100644 --- a/api/resmap/resmap_test.go +++ b/api/resmap/resmap_test.go @@ -826,7 +826,7 @@ func makeMap1() ResMap { }, }, &types.GeneratorArgs{ Behavior: "create", - }, nil)) + })) } func makeMap2(b types.GenerationBehavior) ResMap { @@ -844,7 +844,7 @@ func makeMap2(b types.GenerationBehavior) ResMap { }, }, &types.GeneratorArgs{ Behavior: b.String(), - }, nil)) + })) } func TestAbsorbAll(t *testing.T) { @@ -864,7 +864,7 @@ func TestAbsorbAll(t *testing.T) { }, }, &types.GeneratorArgs{ Behavior: "create", - }, nil)) + })) w := makeMap1() if err := w.AbsorbAll(makeMap2(types.BehaviorMerge)); err != nil { t.Fatalf("unexpected error: %v", err) diff --git a/api/resource/factory.go b/api/resource/factory.go index ab823fae5..29affd36a 100644 --- a/api/resource/factory.go +++ b/api/resource/factory.go @@ -50,8 +50,8 @@ func (rf *Factory) FromMapWithNamespaceAndName(ns string, n string, m map[string // FromMapAndOption returns a new instance of Resource with given options. func (rf *Factory) FromMapAndOption( - m map[string]interface{}, args *types.GeneratorArgs, option *types.GeneratorOptions) *Resource { - return rf.makeOne(rf.kf.FromMap(m), types.NewGenArgs(args, option)) + m map[string]interface{}, args *types.GeneratorArgs) *Resource { + return rf.makeOne(rf.kf.FromMap(m), types.NewGenArgs(args)) } // FromKunstructured returns a new instance of Resource. @@ -66,7 +66,7 @@ func (rf *Factory) makeOne( log.Fatal("unstruct ifc must not be null") } if o == nil { - o = types.NewGenArgs(nil, nil) + o = types.NewGenArgs(nil) } r := &Resource{ Kunstructured: u, @@ -147,33 +147,19 @@ func (rf *Factory) SliceFromBytes(in []byte) ([]*Resource, error) { } // MakeConfigMap makes an instance of Resource for ConfigMap -func (rf *Factory) MakeConfigMap( - kvLdr ifc.KvLoader, - options *types.GeneratorOptions, - args *types.ConfigMapArgs) (*Resource, error) { - u, err := rf.kf.MakeConfigMap(kvLdr, options, args) +func (rf *Factory) MakeConfigMap(kvLdr ifc.KvLoader, args *types.ConfigMapArgs) (*Resource, error) { + u, err := rf.kf.MakeConfigMap(kvLdr, args) if err != nil { return nil, err } - return rf.makeOne( - u, - types.NewGenArgs( - &types.GeneratorArgs{Behavior: args.Behavior}, - options)), nil + return rf.makeOne(u, types.NewGenArgs(&args.GeneratorArgs)), nil } // MakeSecret makes an instance of Resource for Secret -func (rf *Factory) MakeSecret( - kvLdr ifc.KvLoader, - options *types.GeneratorOptions, - args *types.SecretArgs) (*Resource, error) { - u, err := rf.kf.MakeSecret(kvLdr, options, args) +func (rf *Factory) MakeSecret(kvLdr ifc.KvLoader, args *types.SecretArgs) (*Resource, error) { + u, err := rf.kf.MakeSecret(kvLdr, args) if err != nil { return nil, err } - return rf.makeOne( - u, - types.NewGenArgs( - &types.GeneratorArgs{Behavior: args.Behavior}, - options)), nil + return rf.makeOne(u, types.NewGenArgs(&args.GeneratorArgs)), nil } diff --git a/api/types/genargs.go b/api/types/genargs.go index a80955b36..a3229c8e3 100644 --- a/api/types/genargs.go +++ b/api/types/genargs.go @@ -8,18 +8,14 @@ import ( "strings" ) -// GenArgs contains both GeneratorArgs and GeneratorOptions. +// GenArgs is a facade over GeneratorArgs, exposing a few readonly properties. type GenArgs struct { args *GeneratorArgs - opts *GeneratorOptions } -// NewGenArgs returns a new object of GenArgs -func NewGenArgs(args *GeneratorArgs, opts *GeneratorOptions) *GenArgs { - return &GenArgs{ - args: args, - opts: opts, - } +// NewGenArgs returns a new instance of GenArgs. +func NewGenArgs(args *GeneratorArgs) *GenArgs { + return &GenArgs{args: args} } func (g *GenArgs) String() string { @@ -38,7 +34,7 @@ func (g *GenArgs) String() string { // content hash should be appended to the name of the resource. func (g *GenArgs) ShouldAddHashSuffixToName() bool { return g.args != nil && - (g.opts == nil || !g.opts.DisableNameSuffixHash) + (g.args.Options == nil || !g.args.Options.DisableNameSuffixHash) } // Behavior returns Behavior field of GeneratorArgs diff --git a/api/types/genargs_test.go b/api/types/genargs_test.go index 47ca9e564..4d2a0cbee 100644 --- a/api/types/genargs_test.go +++ b/api/types/genargs_test.go @@ -24,8 +24,10 @@ func TestGenArgs_String(t *testing.T) { }, { ga: NewGenArgs( - &GeneratorArgs{Behavior: "merge"}, - &GeneratorOptions{DisableNameSuffixHash: false}), + &GeneratorArgs{ + Behavior: "merge", + Options: &GeneratorOptions{DisableNameSuffixHash: false}, + }), expected: "{nsfx:true,beh:merge}", }, } diff --git a/api/types/generatorargs.go b/api/types/generatorargs.go index 22f64d505..be3954ce1 100644 --- a/api/types/generatorargs.go +++ b/api/types/generatorargs.go @@ -22,6 +22,6 @@ type GeneratorArgs struct { // KvPairSources for the generator. KvPairSources `json:",inline,omitempty" yaml:",inline,omitempty"` - // GeneratorOptions modify this generator - GeneratorOptions *GeneratorOptions `json:"generatorOptions,omitempty" yaml:"generatorOptions,omitempty"` + // Local overrides to global generator options + Options *GeneratorOptions `json:"options,omitempty" yaml:"options,omitempty"` } diff --git a/api/types/generatoroptions.go b/api/types/generatoroptions.go index 82778efc1..c30f6517d 100644 --- a/api/types/generatoroptions.go +++ b/api/types/generatoroptions.go @@ -16,3 +16,55 @@ type GeneratorOptions struct { // resource contents. DisableNameSuffixHash bool `json:"disableNameSuffixHash,omitempty" yaml:"disableNameSuffixHash,omitempty"` } + +// MergeGlobalOptionsIntoLocal merges two instances of GeneratorOptions. +// Values in the first 'local' argument cannot be overridden by the second +// 'global' argument, except in the case of booleans. +// +// With booleans, there's no way to distinguish an 'intentional' +// false from 'default' false. So the rule is, if the global value +// of the value of a boolean is true, i.e. disable, it trumps the +// local value. If the global value is false, then the local value is +// respected. Bottom line: a local false cannot override a global true. +// +// boolean fields are always a bad idea; should always use enums instead. +func MergeGlobalOptionsIntoLocal( + localOpts *GeneratorOptions, + globalOpts *GeneratorOptions) *GeneratorOptions { + if globalOpts == nil { + return localOpts + } + if localOpts == nil { + localOpts = &GeneratorOptions{} + } + overrideMap(&localOpts.Labels, globalOpts.Labels) + overrideMap(&localOpts.Annotations, globalOpts.Annotations) + if globalOpts.DisableNameSuffixHash { + localOpts.DisableNameSuffixHash = true + } + return localOpts +} + +func overrideMap(localMap *map[string]string, globalMap map[string]string) { + if *localMap == nil { + if globalMap != nil { + *localMap = CopyMap(globalMap) + } + return + } + for k, v := range globalMap { + _, ok := (*localMap)[k] + if !ok { + (*localMap)[k] = v + } + } +} + +// CopyMap copies a map. +func CopyMap(in map[string]string) map[string]string { + out := make(map[string]string) + for k, v := range in { + out[k] = v + } + return out +} diff --git a/api/types/generatoroptions_test.go b/api/types/generatoroptions_test.go new file mode 100644 index 000000000..e4a0ae2c0 --- /dev/null +++ b/api/types/generatoroptions_test.go @@ -0,0 +1,125 @@ +// Copyright 2019 The Kubernetes Authors. +// SPDX-License-Identifier: Apache-2.0 + +package types_test + +import ( + "reflect" + "testing" + + . "sigs.k8s.io/kustomize/api/types" +) + +func TestMergeGlobalOptionsIntoLocal(t *testing.T) { + tests := []struct { + name string + local *GeneratorOptions + global *GeneratorOptions + expected *GeneratorOptions + }{ + { + name: "everything nil", + local: nil, + global: nil, + expected: nil, + }, + { + name: "nil global", + local: &GeneratorOptions{ + Labels: map[string]string{"pet": "dog"}, + Annotations: map[string]string{"fruit": "apple"}, + }, + global: nil, + expected: &GeneratorOptions{ + Labels: map[string]string{"pet": "dog"}, + Annotations: map[string]string{"fruit": "apple"}, + DisableNameSuffixHash: false, + }, + }, + { + name: "nil local", + local: nil, + global: &GeneratorOptions{ + Labels: map[string]string{"pet": "dog"}, + Annotations: map[string]string{"fruit": "apple"}, + }, + expected: &GeneratorOptions{ + Labels: map[string]string{"pet": "dog"}, + Annotations: map[string]string{"fruit": "apple"}, + DisableNameSuffixHash: false, + }, + }, + { + name: "global doesn't damage local", + local: &GeneratorOptions{ + Labels: map[string]string{"pet": "dog"}, + Annotations: map[string]string{ + "fruit": "apple"}, + }, + global: &GeneratorOptions{ + Labels: map[string]string{ + "pet": "cat", + "simpson": "homer", + }, + Annotations: map[string]string{ + "fruit": "peach", + "tesla": "Y", + }, + }, + expected: &GeneratorOptions{ + Labels: map[string]string{ + "pet": "dog", + "simpson": "homer", + }, + Annotations: map[string]string{ + "fruit": "apple", + "tesla": "Y", + }, + DisableNameSuffixHash: false, + }, + }, + { + name: "global disable trumps local", + local: &GeneratorOptions{ + DisableNameSuffixHash: false, + }, + global: &GeneratorOptions{ + DisableNameSuffixHash: true, + }, + expected: &GeneratorOptions{ + DisableNameSuffixHash: true, + }, + }, + { + name: "local disable works", + local: &GeneratorOptions{ + DisableNameSuffixHash: true, + }, + global: &GeneratorOptions{ + DisableNameSuffixHash: false, + }, + expected: &GeneratorOptions{ + DisableNameSuffixHash: true, + }, + }, + { + name: "everyone wants disable", + local: &GeneratorOptions{ + DisableNameSuffixHash: true, + }, + global: &GeneratorOptions{ + DisableNameSuffixHash: true, + }, + expected: &GeneratorOptions{ + DisableNameSuffixHash: true, + }, + }, + } + for _, tc := range tests { + actual := MergeGlobalOptionsIntoLocal(tc.local, tc.global) + if !reflect.DeepEqual(tc.expected, actual) { + t.Fatalf("%s annotations: Expected '%v', got '%v'", + tc.name, tc.expected, *actual) + } + } +} diff --git a/kustomize/go.sum b/kustomize/go.sum index 8db0d8299..ba2956b5e 100644 --- a/kustomize/go.sum +++ b/kustomize/go.sum @@ -153,8 +153,6 @@ github.com/go-openapi/spec v0.17.0/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsd github.com/go-openapi/spec v0.18.0/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsdfssdxcBI= github.com/go-openapi/spec v0.19.2/go.mod h1:sCxk3jxKgioEJikev4fgkNmwS+3kuYdJtcsZsD5zxMY= github.com/go-openapi/spec v0.19.3/go.mod h1:FpwSN1ksY1eteniUU7X0N/BgJ7a4WvBFVA8Lj9mJglo= -github.com/go-openapi/spec v0.19.4 h1:ixzUSnHTd6hCemgtAJgluaTSGYpLNpJY4mA2DIkdOAo= -github.com/go-openapi/spec v0.19.4/go.mod h1:FpwSN1ksY1eteniUU7X0N/BgJ7a4WvBFVA8Lj9mJglo= github.com/go-openapi/spec v0.19.5 h1:Xm0Ao53uqnk9QE/LlYV5DEU09UAgpliA85QoT9LzqPw= github.com/go-openapi/spec v0.19.5/go.mod h1:Hm2Jr4jv8G1ciIAo+frC/Ft+rR2kQDh8JHKHb3gWUSk= github.com/go-openapi/strfmt v0.17.0/go.mod h1:P82hnJI0CXkErkXi8IKjPbNBM6lV6+5pLP5l494TcyU= @@ -757,12 +755,6 @@ sigs.k8s.io/kustomize/cmd/config v0.0.5 h1:mFJowsk9IGvwm5dUpVB+ZM63on2JjgaCy+YcV sigs.k8s.io/kustomize/cmd/config v0.0.5/go.mod h1:L47nDnZDfGFQG3gnPJLG2UABn0nVb9v+ndceyMH0jjU= sigs.k8s.io/kustomize/kyaml v0.0.2/go.mod h1:rywm/rcR5LmCBghz9956tE45OdUPChFoXVVs+WmhMTI= sigs.k8s.io/kustomize/kyaml v0.0.5/go.mod h1:waxTrzQRK9i6/5fR5HNo8xa4YwvWn8t85vMnOGFEZik= -sigs.k8s.io/kustomize/kyaml v0.0.6 h1:KhQr7JwpCseFTSWCwqp4CJ4mY6Kx+i34tF4e0eNkcXw= -sigs.k8s.io/kustomize/kyaml v0.0.6/go.mod h1:tDOfJjL6slQVBLHJ76XfXAFgAOEdfm04AW2HehYOp8k= -sigs.k8s.io/kustomize/kyaml v0.1.1 h1:nGUNYINljZNmlAS8uoobUv/wx/s3Pg8dNxYo+W7uYh0= -sigs.k8s.io/kustomize/kyaml v0.1.1/go.mod h1:/NdPPfrperSCGjm55cwEro1loBVtbtVIXSb7FguK6uk= -sigs.k8s.io/kustomize/kyaml v0.1.3 h1:zbeHVTMCQPtWgjIH/YYJZC45mm7coTdw2TblyJ79BrY= -sigs.k8s.io/kustomize/kyaml v0.1.3/go.mod h1:461i94nj0h0ylJ6w83jLkR4SqqVhn1iY6fjD0JSTQeE= sigs.k8s.io/kustomize/kyaml v0.1.5 h1:NicBWYTwkuOfVyZDbNkfSBSCwSgin4uirkedtyZltIc= sigs.k8s.io/kustomize/kyaml v0.1.5/go.mod h1:461i94nj0h0ylJ6w83jLkR4SqqVhn1iY6fjD0JSTQeE= sigs.k8s.io/structured-merge-diff v0.0.0-20190525122527-15d366b2352e/go.mod h1:wWxsB5ozmmv/SG7nM11ayaAW51xMvak/t1r0CSlcokI= diff --git a/kustomize/internal/commands/edit/add/configmap.go b/kustomize/internal/commands/edit/add/configmap.go index 0d2606738..11feb5c69 100644 --- a/kustomize/internal/commands/edit/add/configmap.go +++ b/kustomize/internal/commands/edit/add/configmap.go @@ -95,11 +95,10 @@ func addConfigMap( args := findOrMakeConfigMapArgs(k, flags.Name) mergeFlagsIntoCmArgs(args, flags) // Validate by trying to create corev1.configmap. - _, err := kf.MakeConfigMap(ldr, k.GeneratorOptions, args) - if err != nil { - return err - } - return nil + args.Options = types.MergeGlobalOptionsIntoLocal( + args.Options, k.GeneratorOptions) + _, err := kf.MakeConfigMap(ldr, args) + return err } func findOrMakeConfigMapArgs(m *types.Kustomization, name string) *types.ConfigMapArgs { diff --git a/kustomize/internal/commands/edit/add/secret.go b/kustomize/internal/commands/edit/add/secret.go index ceb9650bf..39d96f41c 100644 --- a/kustomize/internal/commands/edit/add/secret.go +++ b/kustomize/internal/commands/edit/add/secret.go @@ -105,11 +105,10 @@ func addSecret( args := findOrMakeSecretArgs(k, flags.Name, flags.Namespace, flags.Type) mergeFlagsIntoGeneratorArgs(&args.GeneratorArgs, flags) // Validate by trying to create corev1.secret. - _, err := kf.MakeSecret(ldr, k.GeneratorOptions, args) - if err != nil { - return err - } - return nil + args.Options = types.MergeGlobalOptionsIntoLocal( + args.Options, k.GeneratorOptions) + _, err := kf.MakeSecret(ldr, args) + return err } func findOrMakeSecretArgs(m *types.Kustomization, name, namespace, secretType string) *types.SecretArgs { diff --git a/plugin/builtin/configmapgenerator/ConfigMapGenerator.go b/plugin/builtin/configmapgenerator/ConfigMapGenerator.go index 87f91933f..0ab9a7241 100644 --- a/plugin/builtin/configmapgenerator/ConfigMapGenerator.go +++ b/plugin/builtin/configmapgenerator/ConfigMapGenerator.go @@ -14,16 +14,13 @@ import ( type plugin struct { h *resmap.PluginHelpers types.ObjectMeta `json:"metadata,omitempty" yaml:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` - types.GeneratorOptions types.ConfigMapArgs } //noinspection GoUnusedGlobalVariable var KustomizePlugin plugin -func (p *plugin) Config( - h *resmap.PluginHelpers, config []byte) (err error) { - p.GeneratorOptions = types.GeneratorOptions{} +func (p *plugin) Config(h *resmap.PluginHelpers, config []byte) (err error) { p.ConfigMapArgs = types.ConfigMapArgs{} err = yaml.Unmarshal(config, p) if p.ConfigMapArgs.Name == "" { @@ -38,6 +35,5 @@ func (p *plugin) Config( func (p *plugin) Generate() (resmap.ResMap, error) { return p.h.ResmapFactory().FromConfigMapArgs( - kv.NewLoader(p.h.Loader(), p.h.Validator()), - &p.GeneratorOptions, p.ConfigMapArgs) + kv.NewLoader(p.h.Loader(), p.h.Validator()), p.ConfigMapArgs) } diff --git a/plugin/builtin/inventorytransformer/InventoryTransformer.go b/plugin/builtin/inventorytransformer/InventoryTransformer.go index 5ca394e16..4e127548e 100644 --- a/plugin/builtin/inventorytransformer/InventoryTransformer.go +++ b/plugin/builtin/inventorytransformer/InventoryTransformer.go @@ -59,26 +59,23 @@ func (p *plugin) Config( // (e.g. some App object) become more desirable // for this purpose. func (p *plugin) Transform(m resmap.ResMap) error { - inv, h, err := makeInventory(m) if err != nil { return err } - args := types.ConfigMapArgs{} args.Name = p.Name args.Namespace = p.Namespace - opts := &types.GeneratorOptions{ - Annotations: make(map[string]string), + args.Options = &types.GeneratorOptions{ + Annotations: map[string]string{inventory.HashAnnotation: h}, } - opts.Annotations[inventory.HashAnnotation] = h - err = inv.UpdateAnnotations(opts.Annotations) + err = inv.UpdateAnnotations(args.Options.Annotations) if err != nil { return err } cm, err := p.h.ResmapFactory().RF().MakeConfigMap( - kv.NewLoader(p.h.Loader(), p.h.Validator()), opts, &args) + kv.NewLoader(p.h.Loader(), p.h.Validator()), &args) if err != nil { return err } diff --git a/plugin/builtin/secretgenerator/SecretGenerator.go b/plugin/builtin/secretgenerator/SecretGenerator.go index 932b055ec..a3c1955ad 100644 --- a/plugin/builtin/secretgenerator/SecretGenerator.go +++ b/plugin/builtin/secretgenerator/SecretGenerator.go @@ -14,7 +14,6 @@ import ( type plugin struct { h *resmap.PluginHelpers types.ObjectMeta `json:"metadata,omitempty" yaml:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` - types.GeneratorOptions types.SecretArgs } @@ -22,7 +21,6 @@ type plugin struct { var KustomizePlugin plugin func (p *plugin) Config(h *resmap.PluginHelpers, config []byte) (err error) { - p.GeneratorOptions = types.GeneratorOptions{} p.SecretArgs = types.SecretArgs{} err = yaml.Unmarshal(config, p) if p.SecretArgs.Name == "" { @@ -37,6 +35,5 @@ func (p *plugin) Config(h *resmap.PluginHelpers, config []byte) (err error) { func (p *plugin) Generate() (resmap.ResMap, error) { return p.h.ResmapFactory().FromSecretArgs( - kv.NewLoader(p.h.Loader(), p.h.Validator()), - &p.GeneratorOptions, p.SecretArgs) + kv.NewLoader(p.h.Loader(), p.h.Validator()), p.SecretArgs) } diff --git a/plugin/someteam.example.com/v1/secretsfromdatabase/SecretsFromDatabase.go b/plugin/someteam.example.com/v1/secretsfromdatabase/SecretsFromDatabase.go index 1352d3308..ae45bd57a 100644 --- a/plugin/someteam.example.com/v1/secretsfromdatabase/SecretsFromDatabase.go +++ b/plugin/someteam.example.com/v1/secretsfromdatabase/SecretsFromDatabase.go @@ -49,5 +49,5 @@ func (p *plugin) Generate() (resmap.ResMap, error) { } } return p.h.ResmapFactory().FromSecretArgs( - kv.NewLoader(p.h.Loader(), p.h.Validator()), nil, args) + kv.NewLoader(p.h.Loader(), p.h.Validator()), args) }