diff --git a/pkg/target/kusttarget.go b/pkg/target/kusttarget.go index c576c9824..06699f0ea 100644 --- a/pkg/target/kusttarget.go +++ b/pkg/target/kusttarget.go @@ -265,8 +265,6 @@ func (kt *KustTarget) runTransformers(ra *accumulator.ResAccumulator) error { } r = append(r, t) tConfig := ra.GetTransformerConfig() - r = append(r, transformers.NewNamespaceTransformer( - string(kt.kustomization.Namespace), tConfig.NameSpace)) lts, err := kt.configureBuiltinTransformers(tConfig) if err != nil { return err diff --git a/pkg/target/kusttarget_configplugin.go b/pkg/target/kusttarget_configplugin.go index 6f7e862f3..eb1bd78bd 100644 --- a/pkg/target/kusttarget_configplugin.go +++ b/pkg/target/kusttarget_configplugin.go @@ -63,8 +63,8 @@ func (kt *KustTarget) configureBuiltinTransformers( // TODO: Convert remaining legacy transformers to plugins // with tests: // - patch SMP - // - namespace configurators := []transformerConfigurator{ + kt.configureBuiltinNamespaceTransformer, kt.configureBuiltinNameTransformer, kt.configureBuiltinImageTagTransformer, kt.configureBuiltinLabelTransformer, @@ -124,6 +124,24 @@ func (kt *KustTarget) configureBuiltinConfigMapGenerator() ( return } +func (kt *KustTarget) configureBuiltinNamespaceTransformer( + tConfig *config.TransformerConfig) ( + result []transformers.Transformer, err error) { + var c struct { + Namespace string + FieldSpecs []config.FieldSpec + } + c.Namespace = kt.kustomization.Namespace + c.FieldSpecs = tConfig.NameSpace + p := builtin.NewNamespaceTransformerPlugin() + err = kt.configureBuiltinPlugin(p, c, "namespace") + if err != nil { + return nil, err + } + result = append(result, p) + return +} + func (kt *KustTarget) configureBuiltinPatchJson6902Transformer( tConfig *config.TransformerConfig) ( result []transformers.Transformer, err error) { diff --git a/pkg/transformers/namespace.go b/pkg/transformers/namespace.go index b47ccdede..6b06bf636 100644 --- a/pkg/transformers/namespace.go +++ b/pkg/transformers/namespace.go @@ -130,7 +130,10 @@ func (o *namespaceTransformer) updateClusterRoleBinding(m resmap.ResMap) { continue } objMap := m[id].Map() - subjects := objMap["subjects"].([]interface{}) + subjects, ok := objMap["subjects"].([]interface{}) + if subjects == nil || !ok { + continue + } for i := range subjects { subject := subjects[i].(map[string]interface{}) kind, foundk := subject["kind"] diff --git a/plugin/builtin/NamespaceTransformer.go b/plugin/builtin/NamespaceTransformer.go new file mode 100644 index 000000000..9fa0124a9 --- /dev/null +++ b/plugin/builtin/NamespaceTransformer.go @@ -0,0 +1,32 @@ +// Code generated by pluginator on NamespaceTransformer; DO NOT EDIT. +package builtin + +import ( + "sigs.k8s.io/kustomize/pkg/ifc" + "sigs.k8s.io/kustomize/pkg/resmap" + "sigs.k8s.io/kustomize/pkg/transformers" + "sigs.k8s.io/kustomize/pkg/transformers/config" + "sigs.k8s.io/yaml" +) + +// Change or set the namespace of non-cluster level resources. +type NamespaceTransformerPlugin struct { + Namespace string `json:"namespace,omitempty" yaml:"namespace,omitempty"` + FieldSpecs []config.FieldSpec `json:"fieldSpecs,omitempty" yaml:"fieldSpecs,omitempty"` +} + +func NewNamespaceTransformerPlugin() *NamespaceTransformerPlugin { + return &NamespaceTransformerPlugin{} +} + +func (p *NamespaceTransformerPlugin) Config( + ldr ifc.Loader, rf *resmap.Factory, c []byte) (err error) { + p.Namespace = "" + p.FieldSpecs = nil + return yaml.Unmarshal(c, p) +} + +func (p *NamespaceTransformerPlugin) Transform(m resmap.ResMap) error { + return transformers.NewNamespaceTransformer( + p.Namespace, p.FieldSpecs).Transform(m) +} diff --git a/plugin/builtin/namespacetransformer/NamespaceTransformer.go b/plugin/builtin/namespacetransformer/NamespaceTransformer.go new file mode 100644 index 000000000..e990f5700 --- /dev/null +++ b/plugin/builtin/namespacetransformer/NamespaceTransformer.go @@ -0,0 +1,33 @@ +// Copyright 2019 The Kubernetes Authors. +// SPDX-License-Identifier: Apache-2.0 + +//go:generate go run sigs.k8s.io/kustomize/plugin/pluginator +package main + +import ( + "sigs.k8s.io/kustomize/pkg/ifc" + "sigs.k8s.io/kustomize/pkg/resmap" + "sigs.k8s.io/kustomize/pkg/transformers" + "sigs.k8s.io/kustomize/pkg/transformers/config" + "sigs.k8s.io/yaml" +) + +// Change or set the namespace of non-cluster level resources. +type plugin struct { + Namespace string `json:"namespace,omitempty" yaml:"namespace,omitempty"` + FieldSpecs []config.FieldSpec `json:"fieldSpecs,omitempty" yaml:"fieldSpecs,omitempty"` +} + +var KustomizePlugin plugin + +func (p *plugin) Config( + ldr ifc.Loader, rf *resmap.Factory, c []byte) (err error) { + p.Namespace = "" + p.FieldSpecs = nil + return yaml.Unmarshal(c, p) +} + +func (p *plugin) Transform(m resmap.ResMap) error { + return transformers.NewNamespaceTransformer( + p.Namespace, p.FieldSpecs).Transform(m) +} diff --git a/plugin/builtin/namespacetransformer/NamespaceTransformer_test.go b/plugin/builtin/namespacetransformer/NamespaceTransformer_test.go new file mode 100644 index 000000000..f8669336d --- /dev/null +++ b/plugin/builtin/namespacetransformer/NamespaceTransformer_test.go @@ -0,0 +1,176 @@ +// 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 TestNamespaceTransformer1(t *testing.T) { + tc := plugin.NewEnvForTest(t).Set() + defer tc.Reset() + + tc.BuildGoPlugin( + "builtin", "", "NamespaceTransformer") + + th := kusttest_test.NewKustTestPluginHarness(t, "/app") + + rm := th.LoadAndRunTransformer(` +apiVersion: builtin +kind: NamespaceTransformer +metadata: + name: notImportantHere +namespace: test +fieldSpecs: +- path: metadata/namespace + create: true +`, ` +apiVersion: v1 +kind: ConfigMap +metadata: + name: cm1 +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: cm2 + namespace: foo +--- +apiVersion: v1 +kind: Namespace +metadata: + name: ns1 +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: default + namespace: system +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: service-account + namespace: system +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: manager-rolebinding +subjects: +- kind: ServiceAccount + name: default + namespace: system +- kind: ServiceAccount + name: service-account + namespace: system +- kind: ServiceAccount + name: another + namespace: random +--- +apiVersion: apiextensions.k8s.io/v1beta1 +kind: CustomResourceDefinition +metadata: + name: crd +`) + + th.AssertActualEqualsExpected(rm, ` +apiVersion: v1 +kind: Namespace +metadata: + name: ns1 +--- +apiVersion: apiextensions.k8s.io/v1beta1 +kind: CustomResourceDefinition +metadata: + name: crd +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: default + namespace: test +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: service-account + namespace: test +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: manager-rolebinding +subjects: +- kind: ServiceAccount + name: default + namespace: test +- kind: ServiceAccount + name: service-account + namespace: test +- kind: ServiceAccount + name: another + namespace: random +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: cm1 + namespace: test +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: cm2 + namespace: test +`) +} + +func TestNamespaceTransformerClusterLevelKinds(t *testing.T) { + tc := plugin.NewEnvForTest(t).Set() + defer tc.Reset() + + tc.BuildGoPlugin( + "builtin", "", "NamespaceTransformer") + + th := kusttest_test.NewKustTestPluginHarness(t, "/app") + + const noChangeExpected = ` +apiVersion: v1 +kind: Namespace +metadata: + name: ns1 +--- +kind: CustomResourceDefinition +metadata: + name: crd1 +--- +kind: ClusterRole +metadata: + name: cr1 +--- +kind: ClusterRoleBinding +metadata: + name: crb1 +--- +kind: PersistentVolume +metadata: + name: pv1 +` + rm := th.LoadAndRunTransformer(` +apiVersion: builtin +kind: NamespaceTransformer +metadata: + name: notImportantHere +namespace: test +fieldSpecs: +- path: metadata/namespace + create: true +`, noChangeExpected) + + th.AssertActualEqualsExpected(rm, noChangeExpected) +}