diff --git a/pkg/resmap/resmap.go b/pkg/resmap/resmap.go index b83ecebd7..4f901174b 100644 --- a/pkg/resmap/resmap.go +++ b/pkg/resmap/resmap.go @@ -134,13 +134,21 @@ type ResMap interface { // Clear removes all resources and Ids. Clear() - // SubsetThatCouldBeReferencedBy returns a ResMap subset + // SubsetThatCouldBeReferencedById returns a ResMap subset // of self with resources that could be referenced by the // resource represented by the argument Id. // This is a filter; it excludes things that cannot be // referenced by the Id's resource, e.g. objects in other // namespaces. Cluster wide objects are never excluded. - SubsetThatCouldBeReferencedBy(resid.ResId) ResMap + SubsetThatCouldBeReferencedById(resid.ResId) ResMap + + // SubsetThatCouldBeReferencedByResource returns a ResMap subset + // of self with resources that could be referenced by the + // resource argument. + // This is a filter; it excludes things that cannot be + // referenced by the resource, e.g. objects in other + // namespaces. Cluster wide objects are never excluded. + SubsetThatCouldBeReferencedByResource(*resource.Resource) ResMap // DeepCopy copies the ResMap and underlying resources. DeepCopy() ResMap @@ -161,6 +169,14 @@ type ResMap interface { // TODO: - and replace this with a stricter equals. ErrorIfNotEqualSets(ResMap) error + // ErrorIfNotEqualLists returns an error if the + // argument doesn't have the resource objects + // data as self, in the same order. + // Meta information is ignored; this is similar + // to comparing the AsYaml() strings, but allows + // for printing pointers, etc. + ErrorIfNotEqualLists(ResMap) error + // Debug prints the ResMap. Debug(title string) } @@ -420,6 +436,28 @@ func (m *resWrangler) ErrorIfNotEqualSets(other ResMap) error { return nil } +// ErrorIfNotEqualList implements ResMap. +func (m *resWrangler) ErrorIfNotEqualLists(other ResMap) error { + m2, ok := other.(*resWrangler) + if !ok { + panic("bad cast") + } + if m.Size() != m2.Size() { + return fmt.Errorf( + "lists have different number of entries: %#v doesn't equal %#v", + m.rList, m2.rList) + } + for i, r1 := range m.rList { + r2 := m2.rList[i] + if !r1.KunstructEqual(r2) { + return fmt.Errorf( + "Item i=%d differs:\n n1 = %s\n n2 = %s\n", + i, r1.Id(), r2.Id()) + } + } + return nil +} + type resCopier func(r *resource.Resource) *resource.Resource // ShallowCopy implements ResMap. @@ -454,8 +492,8 @@ func (m *resWrangler) makeCopy(copier resCopier) ResMap { return result } -// SubsetThatCouldBeReferencedBy implements ResMap. -func (m *resWrangler) SubsetThatCouldBeReferencedBy(inputId resid.ResId) ResMap { +// SubsetThatCouldBeReferencedById implements ResMap. +func (m *resWrangler) SubsetThatCouldBeReferencedById(inputId resid.ResId) ResMap { if inputId.Gvk().IsClusterKind() { return m } @@ -473,6 +511,25 @@ func (m *resWrangler) SubsetThatCouldBeReferencedBy(inputId resid.ResId) ResMap return result } +// SubsetThatCouldBeReferencedByResource implements ResMap. +func (m *resWrangler) SubsetThatCouldBeReferencedByResource( + inputRes *resource.Resource) ResMap { + inputId := inputRes.Id() + if inputId.Gvk().IsClusterKind() { + return m + } + result := New() + for _, r := range m.Resources() { + if r.Id().Gvk().IsClusterKind() || inputRes.InSameFuzzyNamespace(r) { + err := result.Append(r) + if err != nil { + panic(err) + } + } + } + return result +} + // AppendAll implements ResMap. func (m *resWrangler) AppendAll(other ResMap) error { if other == nil { diff --git a/pkg/resmap/resmap_test.go b/pkg/resmap/resmap_test.go index 2b326400f..b092277c6 100644 --- a/pkg/resmap/resmap_test.go +++ b/pkg/resmap/resmap_test.go @@ -381,7 +381,7 @@ func TestFilterBy(t *testing.T) { for name, test := range tests { test := test t.Run(name, func(t *testing.T) { - got := test.resMap.SubsetThatCouldBeReferencedBy(test.filter) + got := test.resMap.SubsetThatCouldBeReferencedById(test.filter) err := test.expected.ErrorIfNotEqualSets(got) if err != nil { t.Fatalf("Expected %v but got back %v", test.expected, got) diff --git a/pkg/resource/resource.go b/pkg/resource/resource.go index 23b9f3565..00c1013a7 100644 --- a/pkg/resource/resource.go +++ b/pkg/resource/resource.go @@ -80,6 +80,10 @@ func (r *Resource) copyRefVarNames() []string { return s } +func (r *Resource) InSameFuzzyNamespace(o *Resource) bool { + return r.GetNamespace() == o.GetNamespace() +} + func (r *Resource) KunstructEqual(o *Resource) bool { return reflect.DeepEqual(r.Kunstructured, o.Kunstructured) } diff --git a/pkg/target/kusttarget_test.go b/pkg/target/kusttarget_test.go index 37241141a..323c4d783 100644 --- a/pkg/target/kusttarget_test.go +++ b/pkg/target/kusttarget_test.go @@ -1,18 +1,5 @@ -/* -Copyright 2018 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ +// Copyright 2019 The Kubernetes Authors. +// SPDX-License-Identifier: Apache-2.0 package target_test @@ -93,10 +80,11 @@ func TestResources(t *testing.T) { th.WriteF("/whatever/namespace.yaml", namespaceContent) th.WriteF("/whatever/jsonpatch.json", jsonpatchContent) - expected := resmap.FromMap(map[resid.ResId]*resource.Resource{ + expected := resmap.New() + expected.AppendWithId( resid.NewResIdWithPrefixSuffixNamespace( gvk.Gvk{Group: "apps", Version: "v1", Kind: "Deployment"}, - "dply1", "foo-", "-bar", "ns1"): th.FromMap( + "dply1", "foo-", "-bar", "ns1"), th.FromMap( map[string]interface{}{ "apiVersion": "apps/v1", "kind": "Deployment", @@ -128,10 +116,28 @@ func TestResources(t *testing.T) { }, }, }, - }), + })) + expected.AppendWithId( + resid.NewResIdWithPrefixSuffixNamespace( + gvk.Gvk{Version: "v1", Kind: "Namespace"}, + "ns1", "foo-", "-bar", ""), th.FromMap( + map[string]interface{}{ + "apiVersion": "v1", + "kind": "Namespace", + "metadata": map[string]interface{}{ + "name": "foo-ns1-bar", + "labels": map[string]interface{}{ + "app": "nginx", + }, + "annotations": map[string]interface{}{ + "note": "This is a test annotation", + }, + }, + })) + expected.AppendWithId( resid.NewResIdWithPrefixSuffixNamespace( gvk.Gvk{Version: "v1", Kind: "ConfigMap"}, - "literalConfigMap", "foo-", "-bar", "ns1"): th.FromMapAndOption( + "literalConfigMap", "foo-", "-bar", "ns1"), th.FromMap( map[string]interface{}{ "apiVersion": "v1", "kind": "ConfigMap", @@ -149,12 +155,11 @@ func TestResources(t *testing.T) { "DB_USERNAME": "admin", "DB_PASSWORD": "somepw", }, - }, - &types.GeneratorArgs{}, - &types.GeneratorOptions{}), + })) + expected.AppendWithId( resid.NewResIdWithPrefixSuffixNamespace( gvk.Gvk{Version: "v1", Kind: "Secret"}, - "secret", "foo-", "-bar", "ns1"): th.FromMapAndOption( + "secret", "foo-", "-bar", "ns1"), th.FromMap( map[string]interface{}{ "apiVersion": "v1", "kind": "Secret", @@ -173,26 +178,7 @@ func TestResources(t *testing.T) { "DB_USERNAME": base64.StdEncoding.EncodeToString([]byte("admin")), "DB_PASSWORD": base64.StdEncoding.EncodeToString([]byte("somepw")), }, - }, - &types.GeneratorArgs{}, - &types.GeneratorOptions{}), - resid.NewResIdWithPrefixSuffixNamespace( - gvk.Gvk{Version: "v1", Kind: "Namespace"}, - "ns1", "foo-", "-bar", ""): th.FromMap( - map[string]interface{}{ - "apiVersion": "v1", - "kind": "Namespace", - "metadata": map[string]interface{}{ - "name": "foo-ns1-bar", - "labels": map[string]interface{}{ - "app": "nginx", - }, - "annotations": map[string]interface{}{ - "note": "This is a test annotation", - }, - }, - }), - }) + })) actual, err := th.MakeKustTarget().MakeCustomizedResMap() if err != nil { t.Fatalf("unexpected Resources error %v", err) diff --git a/pkg/transformers/namereference.go b/pkg/transformers/namereference.go index 82e1941f7..ef3ca1958 100644 --- a/pkg/transformers/namereference.go +++ b/pkg/transformers/namereference.go @@ -82,7 +82,7 @@ func (o *nameReferenceTransformer) Transform(m resmap.ResMap) error { for _, fSpec := range target.FieldSpecs { if referrer.Gvk().IsSelected(&fSpec.Gvk) { if candidates == nil { - candidates = m.SubsetThatCouldBeReferencedBy(referrer) + candidates = m.SubsetThatCouldBeReferencedById(referrer) } err := MutateField( res.Map(),