mirror of
https://github.com/kubernetes-sigs/kustomize.git
synced 2026-06-14 10:30:59 +00:00
Add test for issue 3489 and improve error messages.
This commit is contained in:
@@ -41,7 +41,7 @@ func (fltr Filter) Filter(obj *yaml.RNode) (*yaml.RNode, error) {
|
|||||||
if err := fltr.filter(obj); err != nil {
|
if err := fltr.filter(obj); err != nil {
|
||||||
s, _ := obj.String()
|
s, _ := obj.String()
|
||||||
return nil, errors.WrapPrefixf(err,
|
return nil, errors.WrapPrefixf(err,
|
||||||
"obj '%s' at path '%v'", s, fltr.FieldSpec.Path)
|
"considering field '%s' of object\n%v", fltr.FieldSpec.Path, s)
|
||||||
}
|
}
|
||||||
return obj, nil
|
return obj, nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -176,8 +176,11 @@ kind: Bar
|
|||||||
a:
|
a:
|
||||||
b: a
|
b: a
|
||||||
`,
|
`,
|
||||||
error: "obj 'kind: Bar\na:\n b: a\n' at path 'a/b/c': " +
|
error: `considering field 'a/b/c' of object
|
||||||
"expected sequence or mapping node",
|
kind: Bar
|
||||||
|
a:
|
||||||
|
b: a
|
||||||
|
: expected sequence or mapping node`,
|
||||||
filter: fieldspec.Filter{
|
filter: fieldspec.Filter{
|
||||||
SetValue: filtersutil.SetScalar("e"),
|
SetValue: filtersutil.SetScalar("e"),
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -5,12 +5,13 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/pkg/errors"
|
||||||
"sigs.k8s.io/kustomize/api/filters/fieldspec"
|
"sigs.k8s.io/kustomize/api/filters/fieldspec"
|
||||||
"sigs.k8s.io/kustomize/api/resid"
|
"sigs.k8s.io/kustomize/api/resid"
|
||||||
"sigs.k8s.io/kustomize/api/resmap"
|
"sigs.k8s.io/kustomize/api/resmap"
|
||||||
"sigs.k8s.io/kustomize/api/resource"
|
"sigs.k8s.io/kustomize/api/resource"
|
||||||
"sigs.k8s.io/kustomize/api/types"
|
"sigs.k8s.io/kustomize/api/types"
|
||||||
kyaml_filtersutil "sigs.k8s.io/kustomize/kyaml/filtersutil"
|
"sigs.k8s.io/kustomize/kyaml/filtersutil"
|
||||||
"sigs.k8s.io/kustomize/kyaml/kio"
|
"sigs.k8s.io/kustomize/kyaml/kio"
|
||||||
"sigs.k8s.io/kustomize/kyaml/yaml"
|
"sigs.k8s.io/kustomize/kyaml/yaml"
|
||||||
)
|
)
|
||||||
@@ -38,18 +39,28 @@ func (f Filter) Filter(nodes []*yaml.RNode) ([]*yaml.RNode, error) {
|
|||||||
return kio.FilterAll(yaml.FilterFunc(f.run)).Filter(nodes)
|
return kio.FilterAll(yaml.FilterFunc(f.run)).Filter(nodes)
|
||||||
}
|
}
|
||||||
|
|
||||||
// The node passed in here is the same node as held in Referrer, and
|
// The node passed in here is the same node as held in Referrer;
|
||||||
// that's how the referrer's name field is updated.
|
// that's how the referrer's name field is updated.
|
||||||
// However, this filter still needs the extra methods on Referrer
|
// Currently, however, this filter still needs the extra methods on Referrer
|
||||||
// to consult things like the resource Id, its namespace, etc.
|
// to consult things like the resource Id, its namespace, etc.
|
||||||
|
// TODO(3455): No filter should use the Resource api; all information
|
||||||
|
// about names should come from annotations, with helper methods
|
||||||
|
// on the RNode object. Resource should get stupider, RNode smarter.
|
||||||
func (f Filter) run(node *yaml.RNode) (*yaml.RNode, error) {
|
func (f Filter) run(node *yaml.RNode) (*yaml.RNode, error) {
|
||||||
err := node.PipeE(fieldspec.Filter{
|
if err := node.PipeE(fieldspec.Filter{
|
||||||
FieldSpec: f.NameFieldToUpdate,
|
FieldSpec: f.NameFieldToUpdate,
|
||||||
SetValue: f.set,
|
SetValue: f.set,
|
||||||
})
|
}); err != nil {
|
||||||
return node, err
|
return nil, errors.Wrapf(
|
||||||
|
err, "updating name reference in '%s' field of '%s'",
|
||||||
|
f.NameFieldToUpdate.Path, f.Referrer.CurId().String())
|
||||||
|
}
|
||||||
|
return node, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This function is called at many nodes in the YAML doc tree.
|
||||||
|
// Only on first entry can one expect the argument to match the
|
||||||
|
// top-level node backing the Referrer.
|
||||||
func (f Filter) set(node *yaml.RNode) error {
|
func (f Filter) set(node *yaml.RNode) error {
|
||||||
if yaml.IsMissingOrNull(node) {
|
if yaml.IsMissingOrNull(node) {
|
||||||
return nil
|
return nil
|
||||||
@@ -65,8 +76,7 @@ func (f Filter) set(node *yaml.RNode) error {
|
|||||||
setMappingFn: f.setMapping,
|
setMappingFn: f.setMapping,
|
||||||
}, node)
|
}, node)
|
||||||
default:
|
default:
|
||||||
return fmt.Errorf(
|
return fmt.Errorf("node must be a scalar, sequence or map")
|
||||||
"node is expected to be either a string or a slice of string or a map of string")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -76,16 +86,19 @@ func (f Filter) setMapping(node *yaml.RNode) error {
|
|||||||
return fmt.Errorf("expect a mapping node")
|
return fmt.Errorf("expect a mapping node")
|
||||||
}
|
}
|
||||||
nameNode, err := node.Pipe(yaml.FieldMatcher{Name: "name"})
|
nameNode, err := node.Pipe(yaml.FieldMatcher{Name: "name"})
|
||||||
if err != nil || nameNode == nil {
|
if err != nil {
|
||||||
return fmt.Errorf("cannot find field 'name' in node")
|
return errors.Wrap(err, "trying to match 'name' field")
|
||||||
|
}
|
||||||
|
if nameNode == nil {
|
||||||
|
return fmt.Errorf("no 'name' field in node")
|
||||||
}
|
}
|
||||||
namespaceNode, err := node.Pipe(yaml.FieldMatcher{Name: "namespace"})
|
namespaceNode, err := node.Pipe(yaml.FieldMatcher{Name: "namespace"})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("error when find field 'namespace'")
|
return errors.Wrap(err, "trying to match 'namespace' field")
|
||||||
}
|
}
|
||||||
|
|
||||||
// name will not be updated if the namespace doesn't match
|
// name will not be updated if the namespace doesn't match
|
||||||
subset := f.ReferralCandidates.Resources()
|
candidates := f.ReferralCandidates.Resources()
|
||||||
if namespaceNode != nil {
|
if namespaceNode != nil {
|
||||||
namespace := namespaceNode.YNode().Value
|
namespace := namespaceNode.YNode().Value
|
||||||
bynamespace := f.ReferralCandidates.GroupedByOriginalNamespace()
|
bynamespace := f.ReferralCandidates.GroupedByOriginalNamespace()
|
||||||
@@ -95,57 +108,57 @@ func (f Filter) setMapping(node *yaml.RNode) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
subset = bynamespace[namespace]
|
candidates = bynamespace[namespace]
|
||||||
}
|
}
|
||||||
|
|
||||||
oldName := nameNode.YNode().Value
|
oldName := nameNode.YNode().Value
|
||||||
res, err := f.selectReferral(oldName, subset)
|
referral, err := f.selectReferral(oldName, candidates)
|
||||||
if err != nil || res == nil {
|
if err != nil || referral == nil {
|
||||||
// Nil res means nothing to do.
|
// Nil referral means nothing to do.
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
f.recordTheReferral(res)
|
f.recordTheReferral(referral)
|
||||||
if res.GetName() == oldName && res.GetNamespace() == "" {
|
if referral.GetName() == oldName && referral.GetNamespace() == "" {
|
||||||
// The name has not changed, nothing to do.
|
// The name has not changed, nothing to do.
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
err = node.PipeE(yaml.FieldSetter{
|
err = node.PipeE(yaml.FieldSetter{
|
||||||
Name: "name",
|
Name: "name",
|
||||||
StringValue: res.GetName(),
|
StringValue: referral.GetName(),
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if res.GetNamespace() != "" {
|
if referral.GetNamespace() != "" {
|
||||||
// We don't want value "" to replace value "default" since
|
// We don't want value "" to replace value "default" since
|
||||||
// the empty string is handled as a wild card here not default namespace
|
// the empty string is handled as a wild card here not default namespace
|
||||||
// by kubernetes.
|
// by kubernetes.
|
||||||
err = node.PipeE(yaml.FieldSetter{
|
err = node.PipeE(yaml.FieldSetter{
|
||||||
Name: "namespace",
|
Name: "namespace",
|
||||||
StringValue: res.GetNamespace(),
|
StringValue: referral.GetNamespace(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f Filter) setScalar(node *yaml.RNode) error {
|
func (f Filter) setScalar(node *yaml.RNode) error {
|
||||||
res, err := f.selectReferral(
|
referral, err := f.selectReferral(
|
||||||
node.YNode().Value, f.ReferralCandidates.Resources())
|
node.YNode().Value, f.ReferralCandidates.Resources())
|
||||||
if err != nil || res == nil {
|
if err != nil || referral == nil {
|
||||||
// Nil res means nothing to do.
|
// Nil referral means nothing to do.
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
f.recordTheReferral(res)
|
f.recordTheReferral(referral)
|
||||||
if res.GetName() == node.YNode().Value {
|
if referral.GetName() == node.YNode().Value {
|
||||||
// The name has not changed, nothing to do.
|
// The name has not changed, nothing to do.
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return node.PipeE(yaml.FieldSetter{StringValue: res.GetName()})
|
return node.PipeE(yaml.FieldSetter{StringValue: referral.GetName()})
|
||||||
}
|
}
|
||||||
|
|
||||||
// In the resource, make a note that it is referred to by the referrer.
|
// In the resource, make a note that it is referred to by the Referrer.
|
||||||
func (f Filter) recordTheReferral(res *resource.Resource) {
|
func (f Filter) recordTheReferral(referral *resource.Resource) {
|
||||||
res.AppendRefBy(f.Referrer.CurId())
|
referral.AppendRefBy(f.Referrer.CurId())
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f Filter) isRoleRef() bool {
|
func (f Filter) isRoleRef() bool {
|
||||||
@@ -155,7 +168,7 @@ func (f Filter) isRoleRef() bool {
|
|||||||
// getRoleRefGvk returns a Gvk in the roleRef field. Return error
|
// getRoleRefGvk returns a Gvk in the roleRef field. Return error
|
||||||
// if the roleRef, roleRef/apiGroup or roleRef/kind is missing.
|
// if the roleRef, roleRef/apiGroup or roleRef/kind is missing.
|
||||||
func getRoleRefGvk(res json.Marshaler) (*resid.Gvk, error) {
|
func getRoleRefGvk(res json.Marshaler) (*resid.Gvk, error) {
|
||||||
n, err := kyaml_filtersutil.GetRNode(res)
|
n, err := filtersutil.GetRNode(res)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -213,7 +226,7 @@ func (f Filter) filterReferralCandidates(
|
|||||||
// namespace.
|
// namespace.
|
||||||
func (f Filter) selectReferral(
|
func (f Filter) selectReferral(
|
||||||
oldName string,
|
oldName string,
|
||||||
candidateSubset []*resource.Resource) (*resource.Resource, error) {
|
referralCandidates []*resource.Resource) (*resource.Resource, error) {
|
||||||
var roleRefGvk *resid.Gvk
|
var roleRefGvk *resid.Gvk
|
||||||
if f.isRoleRef() {
|
if f.isRoleRef() {
|
||||||
var err error
|
var err error
|
||||||
@@ -222,11 +235,11 @@ func (f Filter) selectReferral(
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for _, res := range candidateSubset {
|
for _, candidate := range referralCandidates {
|
||||||
if res.GetOriginalName() != oldName {
|
if candidate.GetOriginalName() != oldName {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
id := res.OrgId()
|
id := candidate.OrgId()
|
||||||
if !id.IsSelected(&f.ReferralTarget) {
|
if !id.IsSelected(&f.ReferralTarget) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@@ -242,28 +255,26 @@ func (f Filter) selectReferral(
|
|||||||
filteredMatches := f.filterReferralCandidates(matches)
|
filteredMatches := f.filterReferralCandidates(matches)
|
||||||
if len(filteredMatches) > 1 {
|
if len(filteredMatches) > 1 {
|
||||||
return nil, fmt.Errorf(
|
return nil, fmt.Errorf(
|
||||||
"multiple matches for %s:\n %v",
|
"cannot fix name in '%s' field of referrer '%s';"+
|
||||||
id, getIds(filteredMatches))
|
" found multiple possible referrals: %v",
|
||||||
|
f.NameFieldToUpdate.Path,
|
||||||
|
f.Referrer.CurId(),
|
||||||
|
getIds(filteredMatches))
|
||||||
}
|
}
|
||||||
// Check is the match the resource we are working on
|
// Check is the match the resource we are working on
|
||||||
if len(filteredMatches) == 0 || res != filteredMatches[0] {
|
if len(filteredMatches) == 0 || candidate != filteredMatches[0] {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// In the resource, note that it is referenced
|
return candidate, nil
|
||||||
// by the referrer.
|
|
||||||
res.AppendRefBy(f.Referrer.CurId())
|
|
||||||
// Return transformed name of the object,
|
|
||||||
// complete with prefixes, hashes, etc.
|
|
||||||
return res, nil
|
|
||||||
}
|
}
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func getIds(rs []*resource.Resource) []string {
|
func getIds(rs []*resource.Resource) string {
|
||||||
var result []string
|
var result []string
|
||||||
for _, r := range rs {
|
for _, r := range rs {
|
||||||
result = append(result, r.CurId().String()+"\n")
|
result = append(result, r.CurId().String())
|
||||||
}
|
}
|
||||||
return result
|
return strings.Join(result, ", ")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,14 +14,14 @@ import (
|
|||||||
|
|
||||||
func TestNamerefFilter(t *testing.T) {
|
func TestNamerefFilter(t *testing.T) {
|
||||||
testCases := map[string]struct {
|
testCases := map[string]struct {
|
||||||
input string
|
referrerOriginal string
|
||||||
candidates string
|
candidates string
|
||||||
expected string
|
referrerFinal string
|
||||||
filter Filter
|
filter Filter
|
||||||
originalNames []string
|
originalNames []string
|
||||||
}{
|
}{
|
||||||
"simple scalar": {
|
"simple scalar": {
|
||||||
input: `
|
referrerOriginal: `
|
||||||
apiVersion: apps/v1
|
apiVersion: apps/v1
|
||||||
kind: Deployment
|
kind: Deployment
|
||||||
metadata:
|
metadata:
|
||||||
@@ -41,7 +41,7 @@ metadata:
|
|||||||
name: newName2
|
name: newName2
|
||||||
`,
|
`,
|
||||||
originalNames: []string{"oldName", ""},
|
originalNames: []string{"oldName", ""},
|
||||||
expected: `
|
referrerFinal: `
|
||||||
apiVersion: apps/v1
|
apiVersion: apps/v1
|
||||||
kind: Deployment
|
kind: Deployment
|
||||||
metadata:
|
metadata:
|
||||||
@@ -59,7 +59,7 @@ ref:
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
"sequence": {
|
"sequence": {
|
||||||
input: `
|
referrerOriginal: `
|
||||||
apiVersion: apps/v1
|
apiVersion: apps/v1
|
||||||
kind: Deployment
|
kind: Deployment
|
||||||
metadata:
|
metadata:
|
||||||
@@ -80,7 +80,7 @@ metadata:
|
|||||||
name: newName2
|
name: newName2
|
||||||
`,
|
`,
|
||||||
originalNames: []string{"oldName1", ""},
|
originalNames: []string{"oldName1", ""},
|
||||||
expected: `
|
referrerFinal: `
|
||||||
apiVersion: apps/v1
|
apiVersion: apps/v1
|
||||||
kind: Deployment
|
kind: Deployment
|
||||||
metadata:
|
metadata:
|
||||||
@@ -99,7 +99,7 @@ seq:
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
"mapping": {
|
"mapping": {
|
||||||
input: `
|
referrerOriginal: `
|
||||||
apiVersion: apps/v1
|
apiVersion: apps/v1
|
||||||
kind: Deployment
|
kind: Deployment
|
||||||
metadata:
|
metadata:
|
||||||
@@ -119,7 +119,7 @@ metadata:
|
|||||||
name: newName2
|
name: newName2
|
||||||
`,
|
`,
|
||||||
originalNames: []string{"oldName", ""},
|
originalNames: []string{"oldName", ""},
|
||||||
expected: `
|
referrerFinal: `
|
||||||
apiVersion: apps/v1
|
apiVersion: apps/v1
|
||||||
kind: Deployment
|
kind: Deployment
|
||||||
metadata:
|
metadata:
|
||||||
@@ -137,7 +137,7 @@ map:
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
"mapping with namespace": {
|
"mapping with namespace": {
|
||||||
input: `
|
referrerOriginal: `
|
||||||
apiVersion: apps/v1
|
apiVersion: apps/v1
|
||||||
kind: Deployment
|
kind: Deployment
|
||||||
metadata:
|
metadata:
|
||||||
@@ -159,7 +159,7 @@ metadata:
|
|||||||
name: newName2
|
name: newName2
|
||||||
`,
|
`,
|
||||||
originalNames: []string{"oldName", ""},
|
originalNames: []string{"oldName", ""},
|
||||||
expected: `
|
referrerFinal: `
|
||||||
apiVersion: apps/v1
|
apiVersion: apps/v1
|
||||||
kind: Deployment
|
kind: Deployment
|
||||||
metadata:
|
metadata:
|
||||||
@@ -178,7 +178,7 @@ map:
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
"null value": {
|
"null value": {
|
||||||
input: `
|
referrerOriginal: `
|
||||||
apiVersion: apps/v1
|
apiVersion: apps/v1
|
||||||
kind: Deployment
|
kind: Deployment
|
||||||
metadata:
|
metadata:
|
||||||
@@ -198,7 +198,7 @@ metadata:
|
|||||||
name: newName2
|
name: newName2
|
||||||
`,
|
`,
|
||||||
originalNames: []string{"oldName", ""},
|
originalNames: []string{"oldName", ""},
|
||||||
expected: `
|
referrerFinal: `
|
||||||
apiVersion: apps/v1
|
apiVersion: apps/v1
|
||||||
kind: Deployment
|
kind: Deployment
|
||||||
metadata:
|
metadata:
|
||||||
@@ -220,7 +220,7 @@ map:
|
|||||||
for tn, tc := range testCases {
|
for tn, tc := range testCases {
|
||||||
t.Run(tn, func(t *testing.T) {
|
t.Run(tn, func(t *testing.T) {
|
||||||
factory := provider.NewDefaultDepProvider().GetResourceFactory()
|
factory := provider.NewDefaultDepProvider().GetResourceFactory()
|
||||||
referrer, err := factory.FromBytes([]byte(tc.input))
|
referrer, err := factory.FromBytes([]byte(tc.referrerOriginal))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
@@ -237,9 +237,9 @@ map:
|
|||||||
tc.filter.ReferralCandidates = candidates
|
tc.filter.ReferralCandidates = candidates
|
||||||
|
|
||||||
if !assert.Equal(t,
|
if !assert.Equal(t,
|
||||||
strings.TrimSpace(tc.expected),
|
strings.TrimSpace(tc.referrerFinal),
|
||||||
strings.TrimSpace(
|
strings.TrimSpace(
|
||||||
filtertest_test.RunFilter(t, tc.input, tc.filter))) {
|
filtertest_test.RunFilter(t, tc.referrerOriginal, tc.filter))) {
|
||||||
t.FailNow()
|
t.FailNow()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -248,14 +248,14 @@ map:
|
|||||||
|
|
||||||
func TestNamerefFilterUnhappy(t *testing.T) {
|
func TestNamerefFilterUnhappy(t *testing.T) {
|
||||||
testCases := map[string]struct {
|
testCases := map[string]struct {
|
||||||
input string
|
referrerOriginal string
|
||||||
candidates string
|
candidates string
|
||||||
expected string
|
referrerFinal string
|
||||||
filter Filter
|
filter Filter
|
||||||
originalNames []string
|
originalNames []string
|
||||||
}{
|
}{
|
||||||
"multiple match": {
|
"multiple match": {
|
||||||
input: `
|
referrerOriginal: `
|
||||||
apiVersion: apps/v1
|
apiVersion: apps/v1
|
||||||
kind: Deployment
|
kind: Deployment
|
||||||
metadata:
|
metadata:
|
||||||
@@ -275,7 +275,7 @@ metadata:
|
|||||||
name: newName2
|
name: newName2
|
||||||
`,
|
`,
|
||||||
originalNames: []string{"oldName", "oldName"},
|
originalNames: []string{"oldName", "oldName"},
|
||||||
expected: "",
|
referrerFinal: "",
|
||||||
filter: Filter{
|
filter: Filter{
|
||||||
NameFieldToUpdate: types.FieldSpec{Path: "ref/name"},
|
NameFieldToUpdate: types.FieldSpec{Path: "ref/name"},
|
||||||
ReferralTarget: resid.Gvk{
|
ReferralTarget: resid.Gvk{
|
||||||
@@ -286,7 +286,7 @@ metadata:
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
"no name": {
|
"no name": {
|
||||||
input: `
|
referrerOriginal: `
|
||||||
apiVersion: apps/v1
|
apiVersion: apps/v1
|
||||||
kind: Deployment
|
kind: Deployment
|
||||||
metadata:
|
metadata:
|
||||||
@@ -306,7 +306,7 @@ metadata:
|
|||||||
name: newName2
|
name: newName2
|
||||||
`,
|
`,
|
||||||
originalNames: []string{"oldName", "oldName"},
|
originalNames: []string{"oldName", "oldName"},
|
||||||
expected: "",
|
referrerFinal: "",
|
||||||
filter: Filter{
|
filter: Filter{
|
||||||
NameFieldToUpdate: types.FieldSpec{Path: "ref"},
|
NameFieldToUpdate: types.FieldSpec{Path: "ref"},
|
||||||
ReferralTarget: resid.Gvk{
|
ReferralTarget: resid.Gvk{
|
||||||
@@ -321,7 +321,7 @@ metadata:
|
|||||||
for tn, tc := range testCases {
|
for tn, tc := range testCases {
|
||||||
t.Run(tn, func(t *testing.T) {
|
t.Run(tn, func(t *testing.T) {
|
||||||
factory := provider.NewDefaultDepProvider().GetResourceFactory()
|
factory := provider.NewDefaultDepProvider().GetResourceFactory()
|
||||||
referrer, err := factory.FromBytes([]byte(tc.input))
|
referrer, err := factory.FromBytes([]byte(tc.referrerOriginal))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
@@ -337,11 +337,11 @@ metadata:
|
|||||||
candidates := resMapFactory.FromResourceSlice(candidatesRes)
|
candidates := resMapFactory.FromResourceSlice(candidatesRes)
|
||||||
tc.filter.ReferralCandidates = candidates
|
tc.filter.ReferralCandidates = candidates
|
||||||
|
|
||||||
_, err = filtertest_test.RunFilterE(t, tc.input, tc.filter)
|
_, err = filtertest_test.RunFilterE(t, tc.referrerOriginal, tc.filter)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
t.Fatalf("expect an error")
|
t.Fatalf("expect an error")
|
||||||
}
|
}
|
||||||
if tc.expected != "" && !assert.EqualError(t, err, tc.expected) {
|
if tc.referrerFinal != "" && !assert.EqualError(t, err, tc.referrerFinal) {
|
||||||
t.FailNow()
|
t.FailNow()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -350,19 +350,19 @@ metadata:
|
|||||||
|
|
||||||
func TestCandidatesWithDifferentPrefixSuffix(t *testing.T) {
|
func TestCandidatesWithDifferentPrefixSuffix(t *testing.T) {
|
||||||
testCases := map[string]struct {
|
testCases := map[string]struct {
|
||||||
input string
|
referrerOriginal string
|
||||||
candidates string
|
candidates string
|
||||||
expected string
|
referrerFinal string
|
||||||
filter Filter
|
filter Filter
|
||||||
originalNames []string
|
originalNames []string
|
||||||
prefix []string
|
prefix []string
|
||||||
suffix []string
|
suffix []string
|
||||||
inputPrefix string
|
inputPrefix string
|
||||||
inputSuffix string
|
inputSuffix string
|
||||||
err bool
|
err bool
|
||||||
}{
|
}{
|
||||||
"prefix match": {
|
"prefix match": {
|
||||||
input: `
|
referrerOriginal: `
|
||||||
apiVersion: apps/v1
|
apiVersion: apps/v1
|
||||||
kind: Deployment
|
kind: Deployment
|
||||||
metadata:
|
metadata:
|
||||||
@@ -386,7 +386,7 @@ metadata:
|
|||||||
suffix: []string{"", "suffix2"},
|
suffix: []string{"", "suffix2"},
|
||||||
inputPrefix: "prefix1",
|
inputPrefix: "prefix1",
|
||||||
inputSuffix: "",
|
inputSuffix: "",
|
||||||
expected: `
|
referrerFinal: `
|
||||||
apiVersion: apps/v1
|
apiVersion: apps/v1
|
||||||
kind: Deployment
|
kind: Deployment
|
||||||
metadata:
|
metadata:
|
||||||
@@ -405,7 +405,7 @@ ref:
|
|||||||
err: false,
|
err: false,
|
||||||
},
|
},
|
||||||
"suffix match": {
|
"suffix match": {
|
||||||
input: `
|
referrerOriginal: `
|
||||||
apiVersion: apps/v1
|
apiVersion: apps/v1
|
||||||
kind: Deployment
|
kind: Deployment
|
||||||
metadata:
|
metadata:
|
||||||
@@ -429,7 +429,7 @@ metadata:
|
|||||||
suffix: []string{"suffix1", "suffix2"},
|
suffix: []string{"suffix1", "suffix2"},
|
||||||
inputPrefix: "",
|
inputPrefix: "",
|
||||||
inputSuffix: "suffix1",
|
inputSuffix: "suffix1",
|
||||||
expected: `
|
referrerFinal: `
|
||||||
apiVersion: apps/v1
|
apiVersion: apps/v1
|
||||||
kind: Deployment
|
kind: Deployment
|
||||||
metadata:
|
metadata:
|
||||||
@@ -448,7 +448,7 @@ ref:
|
|||||||
err: false,
|
err: false,
|
||||||
},
|
},
|
||||||
"prefix suffix both match": {
|
"prefix suffix both match": {
|
||||||
input: `
|
referrerOriginal: `
|
||||||
apiVersion: apps/v1
|
apiVersion: apps/v1
|
||||||
kind: Deployment
|
kind: Deployment
|
||||||
metadata:
|
metadata:
|
||||||
@@ -472,7 +472,7 @@ metadata:
|
|||||||
suffix: []string{"suffix1", "suffix2"},
|
suffix: []string{"suffix1", "suffix2"},
|
||||||
inputPrefix: "prefix1",
|
inputPrefix: "prefix1",
|
||||||
inputSuffix: "suffix1",
|
inputSuffix: "suffix1",
|
||||||
expected: `
|
referrerFinal: `
|
||||||
apiVersion: apps/v1
|
apiVersion: apps/v1
|
||||||
kind: Deployment
|
kind: Deployment
|
||||||
metadata:
|
metadata:
|
||||||
@@ -491,7 +491,7 @@ ref:
|
|||||||
err: false,
|
err: false,
|
||||||
},
|
},
|
||||||
"multiple match: both": {
|
"multiple match: both": {
|
||||||
input: `
|
referrerOriginal: `
|
||||||
apiVersion: apps/v1
|
apiVersion: apps/v1
|
||||||
kind: Deployment
|
kind: Deployment
|
||||||
metadata:
|
metadata:
|
||||||
@@ -515,7 +515,7 @@ metadata:
|
|||||||
suffix: []string{"suffix", "suffix"},
|
suffix: []string{"suffix", "suffix"},
|
||||||
inputPrefix: "prefix",
|
inputPrefix: "prefix",
|
||||||
inputSuffix: "suffix",
|
inputSuffix: "suffix",
|
||||||
expected: "",
|
referrerFinal: "",
|
||||||
filter: Filter{
|
filter: Filter{
|
||||||
NameFieldToUpdate: types.FieldSpec{Path: "ref/name"},
|
NameFieldToUpdate: types.FieldSpec{Path: "ref/name"},
|
||||||
ReferralTarget: resid.Gvk{
|
ReferralTarget: resid.Gvk{
|
||||||
@@ -527,7 +527,7 @@ metadata:
|
|||||||
err: true,
|
err: true,
|
||||||
},
|
},
|
||||||
"multiple match: only prefix": {
|
"multiple match: only prefix": {
|
||||||
input: `
|
referrerOriginal: `
|
||||||
apiVersion: apps/v1
|
apiVersion: apps/v1
|
||||||
kind: Deployment
|
kind: Deployment
|
||||||
metadata:
|
metadata:
|
||||||
@@ -551,7 +551,7 @@ metadata:
|
|||||||
suffix: []string{"", ""},
|
suffix: []string{"", ""},
|
||||||
inputPrefix: "prefix",
|
inputPrefix: "prefix",
|
||||||
inputSuffix: "",
|
inputSuffix: "",
|
||||||
expected: "",
|
referrerFinal: "",
|
||||||
filter: Filter{
|
filter: Filter{
|
||||||
NameFieldToUpdate: types.FieldSpec{Path: "ref/name"},
|
NameFieldToUpdate: types.FieldSpec{Path: "ref/name"},
|
||||||
ReferralTarget: resid.Gvk{
|
ReferralTarget: resid.Gvk{
|
||||||
@@ -563,7 +563,7 @@ metadata:
|
|||||||
err: true,
|
err: true,
|
||||||
},
|
},
|
||||||
"multiple match: only suffix": {
|
"multiple match: only suffix": {
|
||||||
input: `
|
referrerOriginal: `
|
||||||
apiVersion: apps/v1
|
apiVersion: apps/v1
|
||||||
kind: Deployment
|
kind: Deployment
|
||||||
metadata:
|
metadata:
|
||||||
@@ -587,7 +587,7 @@ metadata:
|
|||||||
suffix: []string{"suffix", "suffix"},
|
suffix: []string{"suffix", "suffix"},
|
||||||
inputPrefix: "",
|
inputPrefix: "",
|
||||||
inputSuffix: "suffix",
|
inputSuffix: "suffix",
|
||||||
expected: "",
|
referrerFinal: "",
|
||||||
filter: Filter{
|
filter: Filter{
|
||||||
NameFieldToUpdate: types.FieldSpec{Path: "ref/name"},
|
NameFieldToUpdate: types.FieldSpec{Path: "ref/name"},
|
||||||
ReferralTarget: resid.Gvk{
|
ReferralTarget: resid.Gvk{
|
||||||
@@ -599,7 +599,7 @@ metadata:
|
|||||||
err: true,
|
err: true,
|
||||||
},
|
},
|
||||||
"no match: neither match": {
|
"no match: neither match": {
|
||||||
input: `
|
referrerOriginal: `
|
||||||
apiVersion: apps/v1
|
apiVersion: apps/v1
|
||||||
kind: Deployment
|
kind: Deployment
|
||||||
metadata:
|
metadata:
|
||||||
@@ -623,7 +623,7 @@ metadata:
|
|||||||
suffix: []string{"suffix1", "suffix2"},
|
suffix: []string{"suffix1", "suffix2"},
|
||||||
inputPrefix: "prefix",
|
inputPrefix: "prefix",
|
||||||
inputSuffix: "suffix",
|
inputSuffix: "suffix",
|
||||||
expected: `
|
referrerFinal: `
|
||||||
apiVersion: apps/v1
|
apiVersion: apps/v1
|
||||||
kind: Deployment
|
kind: Deployment
|
||||||
metadata:
|
metadata:
|
||||||
@@ -642,7 +642,7 @@ ref:
|
|||||||
err: false,
|
err: false,
|
||||||
},
|
},
|
||||||
"no match: prefix doesn't match": {
|
"no match: prefix doesn't match": {
|
||||||
input: `
|
referrerOriginal: `
|
||||||
apiVersion: apps/v1
|
apiVersion: apps/v1
|
||||||
kind: Deployment
|
kind: Deployment
|
||||||
metadata:
|
metadata:
|
||||||
@@ -666,7 +666,7 @@ metadata:
|
|||||||
suffix: []string{"suffix", "suffix"},
|
suffix: []string{"suffix", "suffix"},
|
||||||
inputPrefix: "prefix",
|
inputPrefix: "prefix",
|
||||||
inputSuffix: "suffix",
|
inputSuffix: "suffix",
|
||||||
expected: `
|
referrerFinal: `
|
||||||
apiVersion: apps/v1
|
apiVersion: apps/v1
|
||||||
kind: Deployment
|
kind: Deployment
|
||||||
metadata:
|
metadata:
|
||||||
@@ -685,7 +685,7 @@ ref:
|
|||||||
err: false,
|
err: false,
|
||||||
},
|
},
|
||||||
"no match: suffix doesn't match": {
|
"no match: suffix doesn't match": {
|
||||||
input: `
|
referrerOriginal: `
|
||||||
apiVersion: apps/v1
|
apiVersion: apps/v1
|
||||||
kind: Deployment
|
kind: Deployment
|
||||||
metadata:
|
metadata:
|
||||||
@@ -709,7 +709,7 @@ metadata:
|
|||||||
suffix: []string{"suffix1", "suffix2"},
|
suffix: []string{"suffix1", "suffix2"},
|
||||||
inputPrefix: "prefix",
|
inputPrefix: "prefix",
|
||||||
inputSuffix: "suffix",
|
inputSuffix: "suffix",
|
||||||
expected: `
|
referrerFinal: `
|
||||||
apiVersion: apps/v1
|
apiVersion: apps/v1
|
||||||
kind: Deployment
|
kind: Deployment
|
||||||
metadata:
|
metadata:
|
||||||
@@ -732,7 +732,7 @@ ref:
|
|||||||
for tn, tc := range testCases {
|
for tn, tc := range testCases {
|
||||||
t.Run(tn, func(t *testing.T) {
|
t.Run(tn, func(t *testing.T) {
|
||||||
factory := provider.NewDefaultDepProvider().GetResourceFactory()
|
factory := provider.NewDefaultDepProvider().GetResourceFactory()
|
||||||
referrer, err := factory.FromBytes([]byte(tc.input))
|
referrer, err := factory.FromBytes([]byte(tc.referrerOriginal))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
@@ -764,13 +764,15 @@ ref:
|
|||||||
|
|
||||||
if !tc.err {
|
if !tc.err {
|
||||||
if !assert.Equal(t,
|
if !assert.Equal(t,
|
||||||
strings.TrimSpace(tc.expected),
|
strings.TrimSpace(tc.referrerFinal),
|
||||||
strings.TrimSpace(
|
strings.TrimSpace(
|
||||||
filtertest_test.RunFilter(t, tc.input, tc.filter))) {
|
filtertest_test.RunFilter(
|
||||||
|
t, tc.referrerOriginal, tc.filter))) {
|
||||||
t.FailNow()
|
t.FailNow()
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
_, err := filtertest_test.RunFilterE(t, tc.input, tc.filter)
|
_, err := filtertest_test.RunFilterE(
|
||||||
|
t, tc.referrerOriginal, tc.filter)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
t.Fatalf("an error is expected")
|
t.Fatalf("an error is expected")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -243,7 +243,8 @@ metadata:
|
|||||||
data:
|
data:
|
||||||
slice:
|
slice:
|
||||||
- false`,
|
- false`,
|
||||||
expectedError: `obj 'apiVersion: apps/v1
|
expectedError: `considering field 'data/slice' of object
|
||||||
|
apiVersion: apps/v1
|
||||||
kind: Deployment
|
kind: Deployment
|
||||||
metadata:
|
metadata:
|
||||||
name: dep
|
name: dep
|
||||||
@@ -252,7 +253,7 @@ metadata:
|
|||||||
data:
|
data:
|
||||||
slice:
|
slice:
|
||||||
- false
|
- false
|
||||||
' at path 'data/slice': invalid value type expect a string`,
|
: invalid value type expect a string`,
|
||||||
filter: Filter{
|
filter: Filter{
|
||||||
MappingFunc: makeMf(map[string]interface{}{
|
MappingFunc: makeMf(map[string]interface{}{
|
||||||
"VAR": int64(5),
|
"VAR": int64(5),
|
||||||
@@ -268,7 +269,8 @@ metadata:
|
|||||||
name: dep
|
name: dep
|
||||||
data:
|
data:
|
||||||
1: str`,
|
1: str`,
|
||||||
expectedError: `obj 'apiVersion: apps/v1
|
expectedError: `considering field 'data' of object
|
||||||
|
apiVersion: apps/v1
|
||||||
kind: Deployment
|
kind: Deployment
|
||||||
metadata:
|
metadata:
|
||||||
name: dep
|
name: dep
|
||||||
@@ -276,7 +278,7 @@ metadata:
|
|||||||
config.kubernetes.io/index: '0'
|
config.kubernetes.io/index: '0'
|
||||||
data:
|
data:
|
||||||
1: str
|
1: str
|
||||||
' at path 'data': invalid map key: value='1', tag='` + yaml.NodeTagInt + `'`,
|
: invalid map key: value='1', tag='` + yaml.NodeTagInt + `'`,
|
||||||
filter: Filter{
|
filter: Filter{
|
||||||
MappingFunc: makeMf(map[string]interface{}{
|
MappingFunc: makeMf(map[string]interface{}{
|
||||||
"VAR": int64(5),
|
"VAR": int64(5),
|
||||||
|
|||||||
@@ -7,6 +7,8 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"sigs.k8s.io/kustomize/api/konfig"
|
||||||
|
|
||||||
"sigs.k8s.io/kustomize/api/internal/plugins/builtinconfig"
|
"sigs.k8s.io/kustomize/api/internal/plugins/builtinconfig"
|
||||||
"sigs.k8s.io/kustomize/api/provider"
|
"sigs.k8s.io/kustomize/api/provider"
|
||||||
"sigs.k8s.io/kustomize/api/resid"
|
"sigs.k8s.io/kustomize/api/resid"
|
||||||
@@ -518,7 +520,27 @@ func TestNameReferenceUnhappyRun(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
}).ResMap(),
|
}).ResMap(),
|
||||||
expectedErr: "cannot find field 'name' in node"},
|
// TODO(#3304): DECISION - kyaml better; not a bug.
|
||||||
|
expectedErr: konfig.IfApiMachineryElseKyaml(
|
||||||
|
`updating name reference in 'rules/resourceNames' field of `+
|
||||||
|
`'rbac.authorization.k8s.io_v1_ClusterRole|~X|cr'`+
|
||||||
|
`: considering field 'rules/resourceNames' of object
|
||||||
|
{"apiVersion": "rbac.authorization.k8s.io/v1", "kind": "ClusterRole", "metadata": {
|
||||||
|
"name": "cr"}, "rules": [{"resourceNames": {"foo": "bar"}, "resources": ["secrets"]}]}
|
||||||
|
: visit traversal on path: [resourceNames]: no 'name' field in node`,
|
||||||
|
`updating name reference in 'rules/resourceNames' field of `+
|
||||||
|
`'rbac.authorization.k8s.io_v1_ClusterRole|~X|cr'`+
|
||||||
|
`: considering field 'rules/resourceNames' of object
|
||||||
|
apiVersion: rbac.authorization.k8s.io/v1
|
||||||
|
kind: ClusterRole
|
||||||
|
metadata:
|
||||||
|
name: cr
|
||||||
|
rules:
|
||||||
|
- resourceNames:
|
||||||
|
foo: bar
|
||||||
|
resources:
|
||||||
|
- secrets
|
||||||
|
: visit traversal on path: [resourceNames]: no 'name' field in node`)},
|
||||||
}
|
}
|
||||||
|
|
||||||
nrt := newNameReferenceTransformer(builtinconfig.MakeDefaultConfig().NameReference)
|
nrt := newNameReferenceTransformer(builtinconfig.MakeDefaultConfig().NameReference)
|
||||||
@@ -529,7 +551,7 @@ func TestNameReferenceUnhappyRun(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if !strings.Contains(err.Error(), test.expectedErr) {
|
if !strings.Contains(err.Error(), test.expectedErr) {
|
||||||
t.Fatalf("Incorrect error.\nExpected: %s, but got %v",
|
t.Fatalf("Incorrect error.\nExpected:\n %s\nGot:\n%v",
|
||||||
test.expectedErr, err)
|
test.expectedErr, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,14 +24,12 @@ func TestRefVarTransformer(t *testing.T) {
|
|||||||
res resmap.ResMap
|
res resmap.ResMap
|
||||||
unused []string
|
unused []string
|
||||||
}
|
}
|
||||||
testCases := []struct {
|
testCases := map[string]struct {
|
||||||
description string
|
given given
|
||||||
given given
|
expected expected
|
||||||
expected expected
|
errMessage string
|
||||||
errMessage string
|
|
||||||
}{
|
}{
|
||||||
{
|
"var replacement in map[string]": {
|
||||||
description: "var replacement in map[string]",
|
|
||||||
given: given{
|
given: given{
|
||||||
varMap: map[string]interface{}{
|
varMap: map[string]interface{}{
|
||||||
"FOO": "replacementForFoo",
|
"FOO": "replacementForFoo",
|
||||||
@@ -106,8 +104,7 @@ func TestRefVarTransformer(t *testing.T) {
|
|||||||
unused: []string{"BAR"},
|
unused: []string{"BAR"},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
"var replacement panic in map[string]": {
|
||||||
description: "var replacement panic in map[string]",
|
|
||||||
given: given{
|
given: given{
|
||||||
varMap: map[string]interface{}{},
|
varMap: map[string]interface{}{},
|
||||||
fs: []types.FieldSpec{
|
fs: []types.FieldSpec{
|
||||||
@@ -126,20 +123,21 @@ func TestRefVarTransformer(t *testing.T) {
|
|||||||
},
|
},
|
||||||
// TODO(#3304): DECISION - kyaml better; not a bug.
|
// TODO(#3304): DECISION - kyaml better; not a bug.
|
||||||
errMessage: konfig.IfApiMachineryElseKyaml(
|
errMessage: konfig.IfApiMachineryElseKyaml(
|
||||||
`obj '{"apiVersion": "v1", "data": {"slice": [5]}, "kind": "ConfigMap", "metadata": {"name": "cm1"}}
|
`considering field 'data/slice' of object
|
||||||
' at path 'data/slice': invalid value type expect a string`,
|
{"apiVersion": "v1", "data": {"slice": [5]}, "kind": "ConfigMap", "metadata": {"name": "cm1"}}
|
||||||
`obj 'apiVersion: v1
|
: invalid value type expect a string`,
|
||||||
|
`considering field 'data/slice' of object
|
||||||
|
apiVersion: v1
|
||||||
data:
|
data:
|
||||||
slice:
|
slice:
|
||||||
- 5
|
- 5
|
||||||
kind: ConfigMap
|
kind: ConfigMap
|
||||||
metadata:
|
metadata:
|
||||||
name: cm1
|
name: cm1
|
||||||
' at path 'data/slice': invalid value type expect a string`,
|
: invalid value type expect a string`,
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
{
|
"var replacement in nil": {
|
||||||
description: "var replacement in nil",
|
|
||||||
given: given{
|
given: given{
|
||||||
varMap: map[string]interface{}{},
|
varMap: map[string]interface{}{},
|
||||||
fs: []types.FieldSpec{
|
fs: []types.FieldSpec{
|
||||||
@@ -171,20 +169,18 @@ metadata:
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, tc := range testCases {
|
for tn, tc := range testCases {
|
||||||
t.Run(tc.description, func(t *testing.T) {
|
t.Run(tn, func(t *testing.T) {
|
||||||
// arrange
|
|
||||||
tr := newRefVarTransformer(tc.given.varMap, tc.given.fs)
|
tr := newRefVarTransformer(tc.given.varMap, tc.given.fs)
|
||||||
|
|
||||||
// act
|
|
||||||
err := tr.Transform(tc.given.res)
|
err := tr.Transform(tc.given.res)
|
||||||
|
|
||||||
// assert
|
|
||||||
if tc.errMessage != "" {
|
if tc.errMessage != "" {
|
||||||
if err == nil {
|
if err == nil {
|
||||||
t.Fatalf("missing expected error %v", tc.errMessage)
|
t.Fatalf("missing expected error %v", tc.errMessage)
|
||||||
} else if err.Error() != tc.errMessage {
|
} else if err.Error() != tc.errMessage {
|
||||||
t.Fatalf("actual error doesn't match expected error: \nACTUAL: %v\nEXPECTED: %v", err.Error(), tc.errMessage)
|
t.Fatalf(`actual error doesn't match expected error:
|
||||||
|
ACTUAL: %v
|
||||||
|
EXPECTED: %v`,
|
||||||
|
err.Error(), tc.errMessage)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -194,7 +190,13 @@ metadata:
|
|||||||
a, e := tc.given.res, tc.expected.res
|
a, e := tc.given.res, tc.expected.res
|
||||||
if !reflect.DeepEqual(a, e) {
|
if !reflect.DeepEqual(a, e) {
|
||||||
err = e.ErrorIfNotEqualLists(a)
|
err = e.ErrorIfNotEqualLists(a)
|
||||||
t.Fatalf("actual doesn't match expected: \nACTUAL:\n%v\nEXPECTED:\n%v\nERR: %v", a, e, err)
|
t.Fatalf(`actual doesn't match expected:
|
||||||
|
ACTUAL:
|
||||||
|
%v
|
||||||
|
EXPECTED:
|
||||||
|
%v
|
||||||
|
ERR: %v`,
|
||||||
|
a, e, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -1,11 +1,194 @@
|
|||||||
package krusty_test
|
package krusty_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
kusttest_test "sigs.k8s.io/kustomize/api/testutils/kusttest"
|
kusttest_test "sigs.k8s.io/kustomize/api/testutils/kusttest"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func TestIssue3489(t *testing.T) {
|
||||||
|
const assets = `{
|
||||||
|
"tenantId": "XXXXX-XXXXXX-XXXXX-XXXXXX-XXXXXX",
|
||||||
|
"subscriptionId": "XXXXX-XXXXXX-XXXXX-XXXXXX-XXXXXX",
|
||||||
|
"resourceGroup": "DNS-EUW-XXX-RG",
|
||||||
|
"useManagedIdentityExtension": true,
|
||||||
|
"userAssignedIdentityID": "XXXXX-XXXXXX-XXXXX-XXXXXX-XXXXXX"
|
||||||
|
}
|
||||||
|
`
|
||||||
|
th := kusttest_test.MakeHarness(t)
|
||||||
|
th.WriteK(".", `
|
||||||
|
namespace: kube-system
|
||||||
|
resources:
|
||||||
|
- external-dns
|
||||||
|
- external-dns-private
|
||||||
|
`)
|
||||||
|
th.WriteK("external-dns", `
|
||||||
|
resources:
|
||||||
|
- ../base
|
||||||
|
commonLabels:
|
||||||
|
app: external-dns
|
||||||
|
instance: public
|
||||||
|
images:
|
||||||
|
- name: k8s.gcr.io/external-dns/external-dns
|
||||||
|
newName: xxx.azurecr.io/external-dns
|
||||||
|
newTag: v0.7.4_sylr.1
|
||||||
|
- name: quay.io/sylr/external-dns
|
||||||
|
newName: xxx.azurecr.io/external-dns
|
||||||
|
newTag: v0.7.4_sylr.1
|
||||||
|
secretGenerator:
|
||||||
|
- name: azure-config-file
|
||||||
|
behavior: replace
|
||||||
|
files:
|
||||||
|
- assets/azure.json
|
||||||
|
patches:
|
||||||
|
- target:
|
||||||
|
group: apps
|
||||||
|
version: v1
|
||||||
|
kind: Deployment
|
||||||
|
name: external-dns
|
||||||
|
patch: |-
|
||||||
|
- op: replace
|
||||||
|
path: /spec/template/spec/containers/0/args
|
||||||
|
value:
|
||||||
|
- --txt-owner-id="aks"
|
||||||
|
- --txt-prefix=external-dns-
|
||||||
|
- --source=service
|
||||||
|
- --provider=azure
|
||||||
|
- --registry=txt
|
||||||
|
- --domain-filter=dev.company.com
|
||||||
|
`)
|
||||||
|
|
||||||
|
th.WriteF("external-dns/assets/azure.json", assets)
|
||||||
|
th.WriteK("external-dns-private", `
|
||||||
|
resources:
|
||||||
|
- ../base
|
||||||
|
nameSuffix: -private
|
||||||
|
commonLabels:
|
||||||
|
app: external-dns
|
||||||
|
instance: private
|
||||||
|
images:
|
||||||
|
- name: k8s.gcr.io/external-dns/external-dns
|
||||||
|
newName: xxx.azurecr.io/external-dns
|
||||||
|
newTag: v0.7.4_sylr.1
|
||||||
|
- name: quay.io/sylr/external-dns
|
||||||
|
newName: xxx.azurecr.io/external-dns
|
||||||
|
newTag: v0.7.4_sylr.1
|
||||||
|
secretGenerator:
|
||||||
|
- name: azure-config-file
|
||||||
|
behavior: replace
|
||||||
|
files:
|
||||||
|
- assets/azure.json
|
||||||
|
patches:
|
||||||
|
- target:
|
||||||
|
group: apps
|
||||||
|
version: v1
|
||||||
|
kind: Deployment
|
||||||
|
name: external-dns
|
||||||
|
patch: |-
|
||||||
|
- op: replace
|
||||||
|
path: /spec/template/spec/containers/0/args
|
||||||
|
value:
|
||||||
|
- --txt-owner-id="aks"
|
||||||
|
- --txt-prefix=external-dns-private-
|
||||||
|
- --source=service
|
||||||
|
- --provider=azure-private-dns
|
||||||
|
- --registry=txt
|
||||||
|
- --domain-filter=static.company.az
|
||||||
|
`)
|
||||||
|
th.WriteF("external-dns-private/assets/azure.json", assets)
|
||||||
|
th.WriteK("base", `
|
||||||
|
resources:
|
||||||
|
- clusterrole.yaml
|
||||||
|
- clusterrolebinding.yaml
|
||||||
|
- deployment.yaml
|
||||||
|
- serviceaccount.yaml
|
||||||
|
commonLabels:
|
||||||
|
app: external-dns
|
||||||
|
instance: public
|
||||||
|
images:
|
||||||
|
- name: k8s.gcr.io/external-dns/external-dns
|
||||||
|
newName: quay.io/sylr/external-dns
|
||||||
|
newTag: v0.7.4-73-g00a9a0c7
|
||||||
|
secretGenerator:
|
||||||
|
- name: azure-config-file
|
||||||
|
files:
|
||||||
|
- assets/azure.json
|
||||||
|
`)
|
||||||
|
th.WriteF("base/assets/azure.json", assets)
|
||||||
|
th.WriteF("base/clusterrolebinding.yaml", `
|
||||||
|
apiVersion: rbac.authorization.k8s.io/v1
|
||||||
|
kind: ClusterRoleBinding
|
||||||
|
metadata:
|
||||||
|
name: external-dns-viewer
|
||||||
|
roleRef:
|
||||||
|
apiGroup: rbac.authorization.k8s.io
|
||||||
|
kind: ClusterRole
|
||||||
|
name: external-dns
|
||||||
|
subjects:
|
||||||
|
- kind: ServiceAccount
|
||||||
|
name: external-dns
|
||||||
|
`)
|
||||||
|
th.WriteF("base/clusterrole.yaml", `
|
||||||
|
apiVersion: rbac.authorization.k8s.io/v1
|
||||||
|
kind: ClusterRole
|
||||||
|
metadata:
|
||||||
|
name: external-dns
|
||||||
|
rules:
|
||||||
|
- apiGroups: ['']
|
||||||
|
resources: ['endpoints', 'pods', 'services', 'nodes']
|
||||||
|
verbs: ['get', 'watch', 'list']
|
||||||
|
- apiGroups: ['extensions', 'networking.k8s.io']
|
||||||
|
resources: ['ingresses']
|
||||||
|
verbs: ['get', 'watch', 'list']
|
||||||
|
`)
|
||||||
|
th.WriteF("base/deployment.yaml", `
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: external-dns
|
||||||
|
spec:
|
||||||
|
strategy:
|
||||||
|
type: Recreate
|
||||||
|
selector:
|
||||||
|
matchLabels: {}
|
||||||
|
template:
|
||||||
|
metadata: {}
|
||||||
|
spec:
|
||||||
|
serviceAccountName: external-dns
|
||||||
|
containers:
|
||||||
|
- name: external-dns
|
||||||
|
image: k8s.gcr.io/external-dns/external-dns
|
||||||
|
args:
|
||||||
|
- --domain-filter=""
|
||||||
|
- --txt-owner-id=""
|
||||||
|
- --txt-prefix=external-dns-
|
||||||
|
- --source=service
|
||||||
|
- --provider=azure
|
||||||
|
- --registry=txt
|
||||||
|
resources: {}
|
||||||
|
volumeMounts:
|
||||||
|
- name: azure-config-file
|
||||||
|
mountPath: /etc/kubernetes
|
||||||
|
readOnly: true
|
||||||
|
volumes:
|
||||||
|
- name: azure-config-file
|
||||||
|
secret:
|
||||||
|
secretName: azure-config-file
|
||||||
|
`)
|
||||||
|
th.WriteF("base/serviceaccount.yaml", `
|
||||||
|
apiVersion: v1
|
||||||
|
kind: ServiceAccount
|
||||||
|
metadata:
|
||||||
|
name: external-dns
|
||||||
|
`)
|
||||||
|
// TODO(3489): This shouldn't be an error.
|
||||||
|
err := th.RunWithErr(".", th.MakeDefaultOptions())
|
||||||
|
if !strings.Contains(err.Error(), "found multiple possible referrals") {
|
||||||
|
t.Fatalf("unexpected error: %q", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestEmptyFieldSpecValue(t *testing.T) {
|
func TestEmptyFieldSpecValue(t *testing.T) {
|
||||||
th := kusttest_test.MakeHarness(t)
|
th := kusttest_test.MakeHarness(t)
|
||||||
th.WriteK("/app", `
|
th.WriteK("/app", `
|
||||||
|
|||||||
@@ -362,7 +362,7 @@ metadata:
|
|||||||
if err == nil {
|
if err == nil {
|
||||||
t.Fatalf("expected error")
|
t.Fatalf("expected error")
|
||||||
}
|
}
|
||||||
if !strings.Contains(err.Error(), "multiple matches for ~G_v1_ServiceAccount|~X|serviceaccount") {
|
if !strings.Contains(err.Error(), "found multiple possible referrals") {
|
||||||
t.Fatalf("unexpected error %v", err)
|
t.Fatalf("unexpected error %v", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user