diff --git a/api/filters/nameref/nameref.go b/api/filters/nameref/nameref.go index 4815f10a29..ff83420cb1 100644 --- a/api/filters/nameref/nameref.go +++ b/api/filters/nameref/nameref.go @@ -284,9 +284,9 @@ func (f Filter) roleRefFilter() sieveFunc { return previousIdSelectedByGvk(roleRefGvk) } -func prefixSuffixEquals(other resource.ResCtx) sieveFunc { +func prefixSuffixEquals(other resource.ResCtx, allowEmpty bool) sieveFunc { return func(r *resource.Resource) bool { - return r.PrefixesSuffixesEquals(other) + return r.PrefixesSuffixesEquals(other, allowEmpty) } } @@ -325,7 +325,10 @@ func (f Filter) selectReferral( if len(candidates) == 1 { return candidates[0], nil } - candidates = doSieve(candidates, prefixSuffixEquals(f.Referrer)) + candidates = doSieve(candidates, prefixSuffixEquals(f.Referrer, true)) + if len(candidates) > 1 { + candidates = doSieve(candidates, prefixSuffixEquals(f.Referrer, false)) + } if len(candidates) == 1 { return candidates[0], nil } diff --git a/api/krusty/configmaps_test.go b/api/krusty/configmaps_test.go index b161d88b35..e36767fa74 100644 --- a/api/krusty/configmaps_test.go +++ b/api/krusty/configmaps_test.go @@ -591,3 +591,184 @@ metadata: name: test-m8t7bmb6g2 `) } + +// Regression test for https://github.com/kubernetes-sigs/kustomize/issues/5047 +func TestPrefixSuffix(t *testing.T) { + th := kusttest_test.MakeHarness(t) + th.WriteF("kustomization.yaml", ` +resources: +- a +- b +`) + + th.WriteF("a/kustomization.yaml", ` +resources: +- ../common + +namePrefix: a +`) + + th.WriteF("b/kustomization.yaml", ` +resources: +- ../common + +namePrefix: b +`) + + th.WriteF("common/kustomization.yaml", ` +resources: +- service + +configMapGenerator: +- name: "-example-configmap" +`) + + th.WriteF("common/service/deployment.yaml", ` +kind: Deployment +apiVersion: apps/v1 + +metadata: + name: "-" + +spec: + template: + spec: + containers: + - name: app + envFrom: + - configMapRef: + name: "-example-configmap" +`) + + th.WriteF("common/service/kustomization.yaml", ` +resources: +- deployment.yaml + +nameSuffix: api +`) + + m := th.Run(".", th.MakeDefaultOptions()) + th.AssertActualEqualsExpected(m, ` +apiVersion: apps/v1 +kind: Deployment +metadata: + name: a-api +spec: + template: + spec: + containers: + - envFrom: + - configMapRef: + name: a-example-configmap-6ct58987ht + name: app +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: a-example-configmap-6ct58987ht +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: b-api +spec: + template: + spec: + containers: + - envFrom: + - configMapRef: + name: b-example-configmap-6ct58987ht + name: app +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: b-example-configmap-6ct58987ht +`) +} + +// Regression test for https://github.com/kubernetes-sigs/kustomize/issues/5047 +func TestPrefixSuffix2(t *testing.T) { + th := kusttest_test.MakeHarness(t) + th.WriteF("kustomization.yaml", ` +resources: +- a +- b +`) + + th.WriteF("a/kustomization.yaml", ` +resources: +- ../common + +namePrefix: a +`) + + th.WriteF("b/kustomization.yaml", ` +resources: +- ../common + +namePrefix: b +`) + + th.WriteF("common/deployment.yaml", ` +apiVersion: apps/v1 +kind: Deployment +metadata: + name: "-example" +spec: + template: + spec: + containers: + - name: app + envFrom: + - configMapRef: + name: "-example-configmap" +`) + + th.WriteF("common/kustomization.yaml", ` +resources: +- deployment.yaml + +configMapGenerator: +- name: "-example-configmap" +`) + + m := th.Run(".", th.MakeDefaultOptions()) + th.AssertActualEqualsExpected(m, ` +apiVersion: apps/v1 +kind: Deployment +metadata: + name: a-example +spec: + template: + spec: + containers: + - envFrom: + - configMapRef: + name: a-example-configmap-6ct58987ht + name: app +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: a-example-configmap-6ct58987ht +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: b-example +spec: + template: + spec: + containers: + - envFrom: + - configMapRef: + name: b-example-configmap-6ct58987ht + name: app +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: b-example-configmap-6ct58987ht +`) +} diff --git a/api/resource/resource.go b/api/resource/resource.go index ae1a98be0e..9884a672c5 100644 --- a/api/resource/resource.go +++ b/api/resource/resource.go @@ -287,12 +287,25 @@ func (r *Resource) getCsvAnnotation(name string) []string { return strings.Split(annotations[name], ",") } -// PrefixesSuffixesEquals is conceptually doing the same task -// as OutermostPrefixSuffix but performs a deeper comparison -// of the suffix and prefix slices. -func (r *Resource) PrefixesSuffixesEquals(o ResCtx) bool { - return utils.SameEndingSubSlice(r.GetNamePrefixes(), o.GetNamePrefixes()) && - utils.SameEndingSubSlice(r.GetNameSuffixes(), o.GetNameSuffixes()) +// PrefixesSuffixesEquals is conceptually doing the same task as +// OutermostPrefixSuffix but performs a deeper comparison of the suffix and +// prefix slices. +// The allowEmpty flag determines whether an empty prefix/suffix +// should be considered a match on anything. +// This is used when filtering, starting with a coarser pass allowing empty +// matches, before requiring exact matches if there are multiple +// remaining candidates. +func (r *Resource) PrefixesSuffixesEquals(o ResCtx, allowEmpty bool) bool { + if allowEmpty { + eitherPrefixEmpty := len(r.GetNamePrefixes()) == 0 || len(o.GetNamePrefixes()) == 0 + eitherSuffixEmpty := len(r.GetNameSuffixes()) == 0 || len(o.GetNameSuffixes()) == 0 + + return (eitherPrefixEmpty || utils.SameEndingSubSlice(r.GetNamePrefixes(), o.GetNamePrefixes())) && + (eitherSuffixEmpty || utils.SameEndingSubSlice(r.GetNameSuffixes(), o.GetNameSuffixes())) + } else { + return utils.SameEndingSubSlice(r.GetNamePrefixes(), o.GetNamePrefixes()) && + utils.SameEndingSubSlice(r.GetNameSuffixes(), o.GetNameSuffixes()) + } } // RemoveBuildAnnotations removes annotations created by the build process.