Add some utilities.

This commit is contained in:
jregan
2019-06-12 18:56:58 -07:00
parent ba49fd4c18
commit 755dd3d024
5 changed files with 96 additions and 49 deletions

View File

@@ -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 {

View File

@@ -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)

View File

@@ -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)
}

View File

@@ -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)

View File

@@ -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(),