From 90c88d7f96c0b1c8bc5b3790650fabe69dac4232 Mon Sep 17 00:00:00 2001 From: Jingfang Liu Date: Wed, 17 Oct 2018 13:35:20 -0700 Subject: [PATCH] skip filtering resmap when the resource is a cluster level resource --- pkg/gvk/gvk.go | 27 +++++++++ pkg/resmap/resmap.go | 4 ++ pkg/resmap/resmap_test.go | 5 ++ pkg/transformers/labelsandannotations_test.go | 2 + pkg/transformers/namereference_test.go | 39 +++++++++++++ pkg/transformers/namespace.go | 30 ++-------- pkg/transformers/namespace_test.go | 57 +++++++++++++++++++ 7 files changed, 139 insertions(+), 25 deletions(-) diff --git a/pkg/gvk/gvk.go b/pkg/gvk/gvk.go index ec846dfa7..8eaf7fafd 100644 --- a/pkg/gvk/gvk.go +++ b/pkg/gvk/gvk.go @@ -136,3 +136,30 @@ func (x Gvk) IsSelected(selector *Gvk) bool { } return true } + +var clusterLevelKinds = []string{ + "ClusterRoleBinding", + "ClusterRole", + "CustomResourceDefinition", + "Namespace", + "PersistentVolume", +} + +// IsClusterKind returns true if x is a cluster-level Gvk +func (x Gvk) IsClusterKind() bool { + for _, k := range clusterLevelKinds { + if k == x.Kind { + return true + } + } + return false +} + +// ClusterLevelGvks returns a slice of cluster-level Gvks +func ClusterLevelGvks() []Gvk { + var result []Gvk + for _, k := range clusterLevelKinds { + result = append(result, Gvk{Kind: k}) + } + return result +} diff --git a/pkg/resmap/resmap.go b/pkg/resmap/resmap.go index 4b22e8a54..190f87174 100644 --- a/pkg/resmap/resmap.go +++ b/pkg/resmap/resmap.go @@ -123,7 +123,11 @@ func (m ResMap) DeepCopy(rf *resource.Factory) ResMap { // FilterBy returns a ResMap containing ResIds with the same namespace and nameprefix // with the inputId +// If inputId is a cluster level resource, return the original resmap func (m ResMap) FilterBy(inputId resid.ResId) ResMap { + if inputId.Gvk().IsClusterKind() { + return m + } result := ResMap{} for id, res := range m { if id.Namespace() == inputId.Namespace() && id.HasSameLeftmostPrefix(inputId) { diff --git a/pkg/resmap/resmap_test.go b/pkg/resmap/resmap_test.go index 341c93887..a4bbbe377 100644 --- a/pkg/resmap/resmap_test.go +++ b/pkg/resmap/resmap_test.go @@ -160,6 +160,11 @@ func TestFilterBy(t *testing.T) { if !reflect.DeepEqual(rm, ns1map) { t.Fatalf("Expected %v but got back %v", rm, ns1map) } + + clmap := rm1.FilterBy(resid.NewResId(gvk.Gvk{Kind: "ClusterRoleBinding"}, "crb")) + if !reflect.DeepEqual(rm1, clmap) { + t.Fatalf("Expected %v but got back %v", rm1, clmap) + } } func TestDeepCopy(t *testing.T) { rm1 := ResMap{ diff --git a/pkg/transformers/labelsandannotations_test.go b/pkg/transformers/labelsandannotations_test.go index 1ee62acd6..48cf2a90a 100644 --- a/pkg/transformers/labelsandannotations_test.go +++ b/pkg/transformers/labelsandannotations_test.go @@ -37,7 +37,9 @@ var statefulset = gvk.Gvk{Group: "apps", Version: "v1", Kind: "StatefulSet"} var crd = gvk.Gvk{Group: "apiwctensions.k8s.io", Version: "v1beta1", Kind: "CustomResourceDefinition"} var job = gvk.Gvk{Group: "batch", Version: "v1", Kind: "Job"} var cronjob = gvk.Gvk{Group: "batch", Version: "v1beta1", Kind: "CronJob"} +var pv = gvk.Gvk{Version: "v1", Kind: "PersistentVolume"} var pvc = gvk.Gvk{Version: "v1", Kind: "PersistentVolumeClaim"} +var cr = gvk.Gvk{Group: "rbac.authorization.k8s.io", Version: "v1", Kind: "ClusterRole"} var crb = gvk.Gvk{Group: "rbac.authorization.k8s.io", Version: "v1", Kind: "ClusterRoleBinding"} var sa = gvk.Gvk{Version: "v1", Kind: "ServiceAccount"} var ingress = gvk.Gvk{Kind: "Ingress"} diff --git a/pkg/transformers/namereference_test.go b/pkg/transformers/namereference_test.go index 81ea8a7fb..3a03c46bf 100644 --- a/pkg/transformers/namereference_test.go +++ b/pkg/transformers/namereference_test.go @@ -190,6 +190,30 @@ func TestNameReferenceRun(t *testing.T) { }, }, }), + resid.NewResIdWithPrefixNamespace(sa, "sa", "", "test"): rf.FromMap( + map[string]interface{}{ + "apiVersion": "v1", + "kind": "ServiceAccount", + "metadata": map[string]interface{}{ + "name": "someprefix-sa", + "namespace": "test", + }, + }), + resid.NewResId(crb, "crb"): rf.FromMap( + map[string]interface{}{ + "apiVersion": "rbac.authorization.k8s.io/v1", + "kind": "ClusterRoleBinding", + "metadata": map[string]interface{}{ + "name": "crb", + }, + "subjects": []interface{}{ + map[string]interface{}{ + "kind": "ServiceAccount", + "name": "sa", + "namespace": "test", + }, + }, + }), } expected := resmap.ResMap{} @@ -325,6 +349,21 @@ func TestNameReferenceRun(t *testing.T) { }, }, ) + expected[resid.NewResId(crb, "crb")] = rf.FromMap( + map[string]interface{}{ + "apiVersion": "rbac.authorization.k8s.io/v1", + "kind": "ClusterRoleBinding", + "metadata": map[string]interface{}{ + "name": "crb", + }, + "subjects": []interface{}{ + map[string]interface{}{ + "kind": "ServiceAccount", + "name": "someprefix-sa", + "namespace": "test", + }, + }, + }) nrt, err := NewNameReferenceTransformer(defaultTransformerConfig.NameReference) if err != nil { t.Fatalf("unexpected error: %v", err) diff --git a/pkg/transformers/namespace.go b/pkg/transformers/namespace.go index 0452b5da8..5f0c06482 100644 --- a/pkg/transformers/namespace.go +++ b/pkg/transformers/namespace.go @@ -28,29 +28,6 @@ type namespaceTransformer struct { fieldSpecsToSkip []config.FieldSpec } -var namespaceFieldSpecsToSkip = []config.FieldSpec{ - { - Gvk: gvk.Gvk{ - Kind: "Namespace", - }, - }, - { - Gvk: gvk.Gvk{ - Kind: "ClusterRoleBinding", - }, - }, - { - Gvk: gvk.Gvk{ - Kind: "ClusterRole", - }, - }, - { - Gvk: gvk.Gvk{ - Kind: "CustomResourceDefinition", - }, - }, -} - var _ Transformer = &namespaceTransformer{} // NewNamespaceTransformer construct a namespaceTransformer. @@ -58,11 +35,14 @@ func NewNamespaceTransformer(ns string, cf []config.FieldSpec) Transformer { if len(ns) == 0 { return NewNoOpTransformer() } - + var skip []config.FieldSpec + for _, g := range gvk.ClusterLevelGvks() { + skip = append(skip, config.FieldSpec{Gvk: g}) + } return &namespaceTransformer{ namespace: ns, fieldSpecsToUse: cf, - fieldSpecsToSkip: namespaceFieldSpecsToSkip, + fieldSpecsToSkip: skip, } } diff --git a/pkg/transformers/namespace_test.go b/pkg/transformers/namespace_test.go index c9926ee59..7b63e0dcc 100644 --- a/pkg/transformers/namespace_test.go +++ b/pkg/transformers/namespace_test.go @@ -197,3 +197,60 @@ func TestNamespaceRun(t *testing.T) { t.Fatalf("actual doesn't match expected: %v", err) } } + +func TestNamespaceRunForClusterLevelKind(t *testing.T) { + rf := resource.NewFactory( + kunstruct.NewKunstructuredFactoryImpl()) + m := resmap.ResMap{ + resid.NewResId(ns, "ns1"): rf.FromMap( + map[string]interface{}{ + "apiVersion": "v1", + "kind": "Namespace", + "metadata": map[string]interface{}{ + "name": "ns1", + }, + }), + resid.NewResId(crd, "crd1"): rf.FromMap( + map[string]interface{}{ + "kind": "CustomResourceDefinition", + "metadata": map[string]interface{}{ + "name": "crd1", + }, + }), + resid.NewResId(pv, "pv1"): rf.FromMap( + map[string]interface{}{ + "kind": "PersistentVolume", + "metadata": map[string]interface{}{ + "name": "pv1", + }, + }), + resid.NewResId(cr, "cr1"): rf.FromMap( + map[string]interface{}{ + "kind": "ClusterRole", + "metadata": map[string]interface{}{ + "name": "cr1", + }, + }), + resid.NewResId(crb, "crb1"): rf.FromMap( + map[string]interface{}{ + "kind": "ClusterRoleBinding", + "metadata": map[string]interface{}{ + "name": "crb1", + }, + "subjects": []interface{}{}, + }), + } + + expected := m.DeepCopy(rf) + + nst := NewNamespaceTransformer("test", defaultTransformerConfig.NameSpace) + + 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) + } +}