mirror of
https://github.com/kubernetes-sigs/kustomize.git
synced 2026-05-17 18:25:26 +00:00
Refactored resource to store all previous names and namespaces
This commit is contained in:
@@ -47,7 +47,7 @@ func (m *merginator) ConflatePatches(in []*resource.Resource) (ResMap, error) {
|
||||
|
||||
func (m *merginator) appendIfNoMatch(index int) (*resource.Resource, error) {
|
||||
candidate := m.incoming[index]
|
||||
matchedResources := m.result.GetMatchingResourcesByOriginalId(
|
||||
matchedResources := m.result.GetMatchingResourcesByAnyId(
|
||||
candidate.OrgId().Equals)
|
||||
if len(matchedResources) == 0 {
|
||||
m.result.Append(candidate)
|
||||
|
||||
@@ -142,24 +142,18 @@ type ResMap interface {
|
||||
// who's CurId is matched by the argument.
|
||||
GetMatchingResourcesByCurrentId(matches IdMatcher) []*resource.Resource
|
||||
|
||||
// GetMatchingResourcesByOriginalId returns the resources
|
||||
// who's OriginalId is matched by the argument.
|
||||
GetMatchingResourcesByOriginalId(matches IdMatcher) []*resource.Resource
|
||||
// GetMatchingResourcesByAnyId returns the resources
|
||||
// who's current or previous IDs is matched by the argument.
|
||||
GetMatchingResourcesByAnyId(matches IdMatcher) []*resource.Resource
|
||||
|
||||
// GetByCurrentId is shorthand for calling
|
||||
// GetMatchingResourcesByCurrentId with a matcher requiring
|
||||
// an exact match, returning an error on multiple or no matches.
|
||||
GetByCurrentId(resid.ResId) (*resource.Resource, error)
|
||||
|
||||
// GetByOriginalId is shorthand for calling
|
||||
// GetMatchingResourcesByOriginalId with a matcher requiring
|
||||
// GetByPreviousId is shorthand for calling
|
||||
// GetMatchingResourcesByAnyId with a matcher requiring
|
||||
// an exact match, returning an error on multiple or no matches.
|
||||
GetByOriginalId(resid.ResId) (*resource.Resource, error)
|
||||
|
||||
// GetById is a helper function which first
|
||||
// attempts GetByOriginalId, then GetByCurrentId,
|
||||
// returning an error if both fail to find a single
|
||||
// match.
|
||||
GetById(resid.ResId) (*resource.Resource, error)
|
||||
|
||||
// GroupedByCurrentNamespace returns a map of namespace
|
||||
|
||||
@@ -155,8 +155,7 @@ func (m *resWrangler) GetIndexOfCurrentId(id resid.ResId) (int, error) {
|
||||
|
||||
type IdFromResource func(r *resource.Resource) resid.ResId
|
||||
|
||||
func GetOriginalId(r *resource.Resource) resid.ResId { return r.OrgId() }
|
||||
func GetCurrentId(r *resource.Resource) resid.ResId { return r.CurId() }
|
||||
func GetCurrentId(r *resource.Resource) resid.ResId { return r.CurId() }
|
||||
|
||||
// GetMatchingResourcesByCurrentId implements ResMap.
|
||||
func (m *resWrangler) GetMatchingResourcesByCurrentId(
|
||||
@@ -164,10 +163,21 @@ func (m *resWrangler) GetMatchingResourcesByCurrentId(
|
||||
return m.filteredById(matches, GetCurrentId)
|
||||
}
|
||||
|
||||
// GetMatchingResourcesByOriginalId implements ResMap.
|
||||
func (m *resWrangler) GetMatchingResourcesByOriginalId(
|
||||
// GetMatchingResourcesByAnyId implements ResMap.
|
||||
func (m *resWrangler) GetMatchingResourcesByAnyId(
|
||||
matches IdMatcher) []*resource.Resource {
|
||||
return m.filteredById(matches, GetOriginalId)
|
||||
var result []*resource.Resource
|
||||
for _, r := range m.rList {
|
||||
prevIds := r.PrevIds()
|
||||
prevIds = append(prevIds, r.CurId())
|
||||
for _, prevId := range prevIds {
|
||||
if matches(prevId) {
|
||||
result = append(result, r)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func (m *resWrangler) filteredById(
|
||||
@@ -187,26 +197,16 @@ func (m *resWrangler) GetByCurrentId(
|
||||
return demandOneMatch(m.GetMatchingResourcesByCurrentId, id, "Current")
|
||||
}
|
||||
|
||||
// GetByOriginalId implements ResMap.
|
||||
func (m *resWrangler) GetByOriginalId(
|
||||
id resid.ResId) (*resource.Resource, error) {
|
||||
return demandOneMatch(m.GetMatchingResourcesByOriginalId, id, "Original")
|
||||
}
|
||||
|
||||
// GetById implements ResMap.
|
||||
func (m *resWrangler) GetById(
|
||||
id resid.ResId) (*resource.Resource, error) {
|
||||
match, err1 := m.GetByOriginalId(id)
|
||||
if err1 == nil {
|
||||
return match, nil
|
||||
r, err := demandOneMatch(m.GetMatchingResourcesByAnyId, id, "Id")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf(
|
||||
"%s; failed to find unique target for patch %s",
|
||||
err.Error(), id.GvknString())
|
||||
}
|
||||
match, err2 := m.GetByCurrentId(id)
|
||||
if err2 == nil {
|
||||
return match, nil
|
||||
}
|
||||
return nil, fmt.Errorf(
|
||||
"%s; %s; failed to find unique target for patch %s",
|
||||
err1.Error(), err2.Error(), id.GvknString())
|
||||
return r, nil
|
||||
}
|
||||
|
||||
type resFinder func(IdMatcher) []*resource.Resource
|
||||
@@ -465,10 +465,7 @@ func (m *resWrangler) AbsorbAll(other ResMap) error {
|
||||
|
||||
func (m *resWrangler) appendReplaceOrMerge(res *resource.Resource) error {
|
||||
id := res.CurId()
|
||||
matches := m.GetMatchingResourcesByOriginalId(id.Equals)
|
||||
if len(matches) == 0 {
|
||||
matches = m.GetMatchingResourcesByCurrentId(id.Equals)
|
||||
}
|
||||
matches := m.GetMatchingResourcesByAnyId(id.Equals)
|
||||
switch len(matches) {
|
||||
case 0:
|
||||
switch res.Behavior() {
|
||||
@@ -593,10 +590,8 @@ func (m *resWrangler) ApplySmPatch(
|
||||
continue
|
||||
}
|
||||
patchCopy := patch.DeepCopy()
|
||||
patchCopy.SetName(res.GetName())
|
||||
patchCopy.SetNamespace(res.GetNamespace())
|
||||
patchCopy.CopyMergeMetaDataFieldsFrom(patch)
|
||||
patchCopy.SetGvk(res.GetGvk())
|
||||
patchCopy.SetOriginalName(res.GetOriginalName(), true)
|
||||
err := res.ApplySmPatch(patchCopy)
|
||||
if err != nil {
|
||||
// Check for an error string from UnmarshalJSON that's indicative
|
||||
|
||||
@@ -331,6 +331,134 @@ func TestGetMatchingResourcesByCurrentId(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetMatchingResourcesByPreviousId(t *testing.T) {
|
||||
r1 := rf.FromMap(
|
||||
map[string]interface{}{
|
||||
"apiVersion": "v1",
|
||||
"kind": "ConfigMap",
|
||||
"metadata": map[string]interface{}{
|
||||
"name": "new-alice",
|
||||
"annotations": map[string]interface{}{
|
||||
"config.kubernetes.io/originalName": "alice",
|
||||
"config.kubernetes.io/originalNs": "default",
|
||||
},
|
||||
},
|
||||
})
|
||||
r2 := rf.FromMap(
|
||||
map[string]interface{}{
|
||||
"apiVersion": "v1",
|
||||
"kind": "ConfigMap",
|
||||
"metadata": map[string]interface{}{
|
||||
"name": "new-bob",
|
||||
"annotations": map[string]interface{}{
|
||||
"config.kubernetes.io/originalName": "bob,bob2",
|
||||
"config.kubernetes.io/originalNs": "default,default",
|
||||
},
|
||||
},
|
||||
})
|
||||
r3 := rf.FromMap(
|
||||
map[string]interface{}{
|
||||
"apiVersion": "v1",
|
||||
"kind": "ConfigMap",
|
||||
"metadata": map[string]interface{}{
|
||||
"name": "new-bob",
|
||||
"namespace": "new-happy",
|
||||
"annotations": map[string]interface{}{
|
||||
"config.kubernetes.io/originalName": "bob",
|
||||
"config.kubernetes.io/originalNs": "happy",
|
||||
},
|
||||
},
|
||||
})
|
||||
r4 := rf.FromMap(
|
||||
map[string]interface{}{
|
||||
"apiVersion": "v1",
|
||||
"kind": "ConfigMap",
|
||||
"metadata": map[string]interface{}{
|
||||
"name": "charlie",
|
||||
"namespace": "happy",
|
||||
"annotations": map[string]interface{}{
|
||||
"config.kubernetes.io/originalName": "charlie",
|
||||
"config.kubernetes.io/originalNs": "default",
|
||||
},
|
||||
},
|
||||
})
|
||||
r5 := rf.FromMap(
|
||||
map[string]interface{}{
|
||||
"apiVersion": "v1",
|
||||
"kind": "Deployment",
|
||||
"metadata": map[string]interface{}{
|
||||
"name": "charlie",
|
||||
"namespace": "happy",
|
||||
},
|
||||
})
|
||||
|
||||
m := resmaptest_test.NewRmBuilder(t, rf).
|
||||
AddR(r1).AddR(r2).AddR(r3).AddR(r4).AddR(r5).ResMap()
|
||||
|
||||
// nolint:goconst
|
||||
tests := []struct {
|
||||
name string
|
||||
matcher IdMatcher
|
||||
count int
|
||||
}{
|
||||
{
|
||||
"match everything",
|
||||
func(resid.ResId) bool { return true },
|
||||
5,
|
||||
},
|
||||
{
|
||||
"match nothing",
|
||||
func(resid.ResId) bool { return false },
|
||||
0,
|
||||
},
|
||||
{
|
||||
"name is alice",
|
||||
func(x resid.ResId) bool { return x.Name == "alice" },
|
||||
1,
|
||||
},
|
||||
{
|
||||
"name is charlie",
|
||||
func(x resid.ResId) bool { return x.Name == "charlie" },
|
||||
2,
|
||||
},
|
||||
{
|
||||
"name is bob",
|
||||
func(x resid.ResId) bool { return x.Name == "bob" },
|
||||
2,
|
||||
},
|
||||
{
|
||||
"happy namespace",
|
||||
func(x resid.ResId) bool {
|
||||
return x.Namespace == "happy"
|
||||
},
|
||||
3,
|
||||
},
|
||||
{
|
||||
"happy deployment",
|
||||
func(x resid.ResId) bool {
|
||||
return x.Namespace == "happy" &&
|
||||
x.Gvk.Kind == "Deployment"
|
||||
},
|
||||
1,
|
||||
},
|
||||
{
|
||||
"happy ConfigMap",
|
||||
func(x resid.ResId) bool {
|
||||
return x.Namespace == "happy" &&
|
||||
x.Gvk.Kind == "ConfigMap"
|
||||
},
|
||||
2,
|
||||
},
|
||||
}
|
||||
for _, tst := range tests {
|
||||
result := m.GetMatchingResourcesByAnyId(tst.matcher)
|
||||
if len(result) != tst.count {
|
||||
t.Fatalf("test '%s'; actual: %d, expected: %d",
|
||||
tst.name, len(result), tst.count)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestSubsetThatCouldBeReferencedByResource(t *testing.T) {
|
||||
r1 := rf.FromMap(
|
||||
map[string]interface{}{
|
||||
|
||||
Reference in New Issue
Block a user