diff --git a/pkg/target/kusttarget.go b/pkg/target/kusttarget.go index 8e80de17a..565507516 100644 --- a/pkg/target/kusttarget.go +++ b/pkg/target/kusttarget.go @@ -275,7 +275,7 @@ func (kt *KustTarget) newTransformer(patches []*resource.Resource) (transformers } r = append(r, t) r = append(r, transformers.NewNamespaceTransformer( - string(kt.kustomization.Namespace), kt.tcfg.NameSpace)) + string(kt.kustomization.Namespace), kt.tcfg.NameSpace, kt.rf.RF())) t, err = transformers.NewNamePrefixTransformer( string(kt.kustomization.NamePrefix), kt.tcfg.NamePrefix) if err != nil { diff --git a/pkg/transformers/namespace.go b/pkg/transformers/namespace.go index 5f0c06482..fc0d5f727 100644 --- a/pkg/transformers/namespace.go +++ b/pkg/transformers/namespace.go @@ -18,7 +18,9 @@ package transformers import ( "sigs.k8s.io/kustomize/pkg/gvk" + "sigs.k8s.io/kustomize/pkg/resid" "sigs.k8s.io/kustomize/pkg/resmap" + "sigs.k8s.io/kustomize/pkg/resource" "sigs.k8s.io/kustomize/pkg/transformers/config" ) @@ -26,12 +28,13 @@ type namespaceTransformer struct { namespace string fieldSpecsToUse []config.FieldSpec fieldSpecsToSkip []config.FieldSpec + factory *resource.Factory } var _ Transformer = &namespaceTransformer{} // NewNamespaceTransformer construct a namespaceTransformer. -func NewNamespaceTransformer(ns string, cf []config.FieldSpec) Transformer { +func NewNamespaceTransformer(ns string, cf []config.FieldSpec, f *resource.Factory) Transformer { if len(ns) == 0 { return NewNoOpTransformer() } @@ -43,11 +46,13 @@ func NewNamespaceTransformer(ns string, cf []config.FieldSpec) Transformer { namespace: ns, fieldSpecsToUse: cf, fieldSpecsToSkip: skip, + factory: f, } } // Transform adds the namespace. func (o *namespaceTransformer) Transform(m resmap.ResMap) error { + o.createNamespaceIfNotFound(m) mf := resmap.ResMap{} for id := range m { @@ -119,3 +124,22 @@ func (o *namespaceTransformer) updateClusterRoleBinding(m resmap.ResMap) { objMap["subjects"] = subjects } } + +func (o *namespaceTransformer) createNamespaceIfNotFound(m resmap.ResMap) { + id := resid.NewResId(gvk.Gvk{ + Version: "v1", + Kind: "Namespace", + }, o.namespace) + ids := m.FindByGVKN(id) + if len(ids) == 0 { + m[id] = o.factory.FromMap( + map[string]interface{}{ + "apiVersion": "v1", + "kind": "Namespace", + "metadata": map[string]interface{}{ + "name": o.namespace, + }, + }, + ) + } +} diff --git a/pkg/transformers/namespace_test.go b/pkg/transformers/namespace_test.go index 7b63e0dcc..6f73cdae5 100644 --- a/pkg/transformers/namespace_test.go +++ b/pkg/transformers/namespace_test.go @@ -47,12 +47,12 @@ func TestNamespaceRun(t *testing.T) { "namespace": "foo", }, }), - resid.NewResId(ns, "ns1"): rf.FromMap( + resid.NewResId(ns, "test"): rf.FromMap( map[string]interface{}{ "apiVersion": "v1", "kind": "Namespace", "metadata": map[string]interface{}{ - "name": "ns1", + "name": "test", }, }), resid.NewResId(sa, "default"): rf.FromMap( @@ -108,12 +108,12 @@ func TestNamespaceRun(t *testing.T) { }), } expected := resmap.ResMap{ - resid.NewResIdWithPrefixNamespace(ns, "ns1", "", ""): rf.FromMap( + resid.NewResIdWithPrefixNamespace(ns, "test", "", ""): rf.FromMap( map[string]interface{}{ "apiVersion": "v1", "kind": "Namespace", "metadata": map[string]interface{}{ - "name": "ns1", + "name": "test", }, }), resid.NewResIdWithPrefixNamespace(cmap, "cm1", "", "test"): rf.FromMap( @@ -187,7 +187,7 @@ func TestNamespaceRun(t *testing.T) { }), } - nst := NewNamespaceTransformer("test", defaultTransformerConfig.NameSpace) + nst := NewNamespaceTransformer("test", defaultTransformerConfig.NameSpace, rf) err := nst.Transform(m) if err != nil { t.Fatalf("unexpected error: %v", err) @@ -243,7 +243,7 @@ func TestNamespaceRunForClusterLevelKind(t *testing.T) { expected := m.DeepCopy(rf) - nst := NewNamespaceTransformer("test", defaultTransformerConfig.NameSpace) + nst := NewNamespaceTransformer("ns1", defaultTransformerConfig.NameSpace, rf) err := nst.Transform(m) if err != nil { @@ -254,3 +254,30 @@ func TestNamespaceRunForClusterLevelKind(t *testing.T) { t.Fatalf("actual doesn't match expected: %v", err) } } + +func TestNamespaceNotFound(t *testing.T) { + rf := resource.NewFactory( + kunstruct.NewKunstructuredFactoryImpl()) + + m := resmap.ResMap{} + expected := resmap.ResMap{ + resid.NewResId(ns, "test"): rf.FromMap( + map[string]interface{}{ + "apiVersion": "v1", + "kind": "Namespace", + "metadata": map[string]interface{}{ + "name": "test", + }, + }), + } + + nst := NewNamespaceTransformer("test", defaultTransformerConfig.NameSpace, rf) + err := nst.Transform(m) + if err != nil { + t.Fatalf("unexpected error: %v", err) + } + if !reflect.DeepEqual(m, expected) { + err = expected.ErrorIfNotEqual(m) + t.Fatalf("actual doesn't match expected: %v", err) + } +}