From 4325401fe7d3e8791a424fc904e91c476041650c Mon Sep 17 00:00:00 2001 From: Jingfang Liu Date: Fri, 13 Jul 2018 11:41:01 -0700 Subject: [PATCH] Add namespace transformation for subjects.namespace in ClusterRoleBinding --- .../in/overlay/kustomization.yaml | 3 +- pkg/transformers/labelsandannotations_test.go | 2 + pkg/transformers/namespace.go | 36 ++++++++ pkg/transformers/namespace_test.go | 86 +++++++++++++++++++ 4 files changed, 126 insertions(+), 1 deletion(-) diff --git a/pkg/commands/testdata/testcase-multiple-patches-noconflict/in/overlay/kustomization.yaml b/pkg/commands/testdata/testcase-multiple-patches-noconflict/in/overlay/kustomization.yaml index d05ba42aeb..555bda1573 100644 --- a/pkg/commands/testdata/testcase-multiple-patches-noconflict/in/overlay/kustomization.yaml +++ b/pkg/commands/testdata/testcase-multiple-patches-noconflict/in/overlay/kustomization.yaml @@ -2,7 +2,8 @@ namePrefix: staging- commonLabels: env: staging patches: - - patches/deployment-patch*.yaml + - patches/deployment-patch1.yaml + - patches/deployment-patch2.yaml bases: - ../package/ configMapGenerator: diff --git a/pkg/transformers/labelsandannotations_test.go b/pkg/transformers/labelsandannotations_test.go index 25e364ecf0..67c719b054 100644 --- a/pkg/transformers/labelsandannotations_test.go +++ b/pkg/transformers/labelsandannotations_test.go @@ -36,6 +36,8 @@ var crd = schema.GroupVersionKind{Group: "apiwctensions.k8s.io", Version: "v1bet var job = schema.GroupVersionKind{Group: "batch", Version: "v1", Kind: "Job"} var cronjob = schema.GroupVersionKind{Group: "batch", Version: "v1beta1", Kind: "CronJob"} var pvc = schema.GroupVersionKind{Version: "v1", Kind: "PersistentVolumeClaim"} +var crb = schema.GroupVersionKind{Group: "rbac.authorization.k8s.io", Version: "v1", Kind: "ClusterRoleBinding"} +var sa = schema.GroupVersionKind{Version: "v1", Kind: "ServiceAccount"} func TestLabelsRun(t *testing.T) { m := resmap.ResMap{ diff --git a/pkg/transformers/namespace.go b/pkg/transformers/namespace.go index 244626dfba..a875894be1 100644 --- a/pkg/transformers/namespace.go +++ b/pkg/transformers/namespace.go @@ -97,5 +97,41 @@ func (o *namespaceTransformer) Transform(m resmap.ResMap) error { } } + o.updateClusterRoleBinding(m) return nil } + +func (o *namespaceTransformer) updateClusterRoleBinding(m resmap.ResMap) { + saMap := map[string]bool{} + saGVK := schema.GroupVersionKind{Version: "v1", Kind: "ServiceAccount"} + for id := range m { + if id.Gvk().String() == saGVK.String() { + saMap[id.Name()] = true + } + } + + for id := range m { + if id.Gvk().Kind != "ClusterRoleBinding" && id.Gvk().Kind != "RoleBinding" { + continue + } + objMap := m[id].UnstructuredContent() + subjects := objMap["subjects"].([]interface{}) + for i := range subjects { + subject := subjects[i].(map[string]interface{}) + kind, foundk := subject["kind"] + name, foundn := subject["name"] + if !foundk || !foundn || kind.(string) != "ServiceAccount" { + continue + } + // a ServiceAccount named “default” exists in every active namespace + if name.(string) == "default" || saMap[name.(string)] { + subject := subjects[i].(map[string]interface{}) + mutateField(subject, []string{"namespace"}, true, func(_ interface{}) (interface{}, error) { + return o.namespace, nil + }) + subjects[i] = subject + } + } + objMap["subjects"] = subjects + } +} diff --git a/pkg/transformers/namespace_test.go b/pkg/transformers/namespace_test.go index faf502b30d..8155d304ae 100644 --- a/pkg/transformers/namespace_test.go +++ b/pkg/transformers/namespace_test.go @@ -51,6 +51,49 @@ func TestNamespaceRun(t *testing.T) { "name": "ns1", }, }), + resource.NewResId(sa, "default"): resource.NewResourceFromMap( + map[string]interface{}{ + "apiVersion": "v1", + "kind": "ServiceAccount", + "metadata": map[string]interface{}{ + "name": "default", + "namespace": "system", + }, + }), + resource.NewResId(sa, "service-account"): resource.NewResourceFromMap( + map[string]interface{}{ + "apiVersion": "v1", + "kind": "ServiceAccount", + "metadata": map[string]interface{}{ + "name": "service-account", + "namespace": "system", + }, + }), + resource.NewResId(crb, "crb"): resource.NewResourceFromMap( + map[string]interface{}{ + "apiVersion": "rbac.authorization.k8s.io/v1", + "kind": "ClusterRoleBinding", + "metadata": map[string]interface{}{ + "name": "manager-rolebinding", + }, + "subjects": []interface{}{ + map[string]interface{}{ + "kind": "ServiceAccount", + "name": "default", + "namespace": "system", + }, + map[string]interface{}{ + "kind": "ServiceAccount", + "name": "service-account", + "namespace": "system", + }, + map[string]interface{}{ + "kind": "ServiceAccount", + "name": "another", + "namespace": "random", + }, + }, + }), } expected := resmap.ResMap{ resource.NewResId(ns, "ns1"): resource.NewResourceFromMap( @@ -79,6 +122,49 @@ func TestNamespaceRun(t *testing.T) { "namespace": "test", }, }), + resource.NewResId(sa, "default"): resource.NewResourceFromMap( + map[string]interface{}{ + "apiVersion": "v1", + "kind": "ServiceAccount", + "metadata": map[string]interface{}{ + "name": "default", + "namespace": "test", + }, + }), + resource.NewResId(sa, "service-account"): resource.NewResourceFromMap( + map[string]interface{}{ + "apiVersion": "v1", + "kind": "ServiceAccount", + "metadata": map[string]interface{}{ + "name": "service-account", + "namespace": "test", + }, + }), + resource.NewResId(crb, "crb"): resource.NewResourceFromMap( + map[string]interface{}{ + "apiVersion": "rbac.authorization.k8s.io/v1", + "kind": "ClusterRoleBinding", + "metadata": map[string]interface{}{ + "name": "manager-rolebinding", + }, + "subjects": []interface{}{ + map[string]interface{}{ + "kind": "ServiceAccount", + "name": "default", + "namespace": "test", + }, + map[string]interface{}{ + "kind": "ServiceAccount", + "name": "service-account", + "namespace": "test", + }, + map[string]interface{}{ + "kind": "ServiceAccount", + "name": "another", + "namespace": "random", + }, + }, + }), } nst := NewNamespaceTransformer("test")