Introduce ResId and ResMap.

This commit is contained in:
jregan
2018-05-31 23:22:46 -07:00
committed by Jeffrey Regan
parent 9a5c0f5a25
commit ef71cb478f
39 changed files with 1063 additions and 1447 deletions

View File

@@ -20,7 +20,7 @@ import (
"errors"
"fmt"
"github.com/kubernetes-sigs/kustomize/pkg/resource"
"github.com/kubernetes-sigs/kustomize/pkg/resmap"
"github.com/kubernetes-sigs/kustomize/pkg/types"
)
@@ -56,12 +56,12 @@ func NewMapTransformer(pc []PathConfig, m map[string]string) (Transformer, error
// Transform apply each <key, value> pair in the mapTransformer to the
// fields specified in mapTransformer.
func (o *mapTransformer) Transform(m resource.ResourceCollection) error {
for gvkn := range m {
obj := m[gvkn].Data
func (o *mapTransformer) Transform(m resmap.ResMap) error {
for id := range m {
obj := m[id].Unstruct()
objMap := obj.UnstructuredContent()
for _, path := range o.pathConfigs {
if !types.SelectByGVK(gvkn.GVK, path.GroupVersionKind) {
if !types.SelectByGVK(id.Gvk(), path.GroupVersionKind) {
continue
}
err := mutateField(objMap, path.Path, path.CreateIfNotPresent, o.addMap)

View File

@@ -20,18 +20,23 @@ import (
"reflect"
"testing"
"github.com/kubernetes-sigs/kustomize/pkg/resmap"
"github.com/kubernetes-sigs/kustomize/pkg/resource"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime/schema"
)
var service = schema.GroupVersionKind{Version: "v1", Kind: "Service"}
var secret = schema.GroupVersionKind{Version: "v1", Kind: "Secret"}
var cmap = schema.GroupVersionKind{Version: "v1", Kind: "ConfigMap"}
var deploy = schema.GroupVersionKind{Group: "apps", Version: "v1", Kind: "Deployment"}
var statefulset = schema.GroupVersionKind{Group: "apps", Version: "v1", Kind: "StatefulSet"}
var foo = schema.GroupVersionKind{Group: "example.com", Version: "v1", Kind: "Foo"}
func TestLabelsRun(t *testing.T) {
m := resource.ResourceCollection{
{
GVK: schema.GroupVersionKind{Version: "v1", Kind: "ConfigMap"},
Name: "cm1",
}: &resource.Resource{
Data: &unstructured.Unstructured{
m := resmap.ResMap{
resource.NewResId(cmap, "cm1"): resource.NewBehaviorlessResource(
&unstructured.Unstructured{
Object: map[string]interface{}{
"apiVersion": "v1",
"kind": "ConfigMap",
@@ -39,13 +44,9 @@ func TestLabelsRun(t *testing.T) {
"name": "cm1",
},
},
},
},
{
GVK: schema.GroupVersionKind{Group: "apps", Version: "v1", Kind: "Deployment"},
Name: "deploy1",
}: &resource.Resource{
Data: &unstructured.Unstructured{
}),
resource.NewResId(deploy, "deploy1"): resource.NewBehaviorlessResource(
&unstructured.Unstructured{
Object: map[string]interface{}{
"group": "apps",
"apiVersion": "v1",
@@ -71,13 +72,9 @@ func TestLabelsRun(t *testing.T) {
},
},
},
},
},
{
GVK: schema.GroupVersionKind{Version: "v1", Kind: "Service"},
Name: "svc1",
}: &resource.Resource{
Data: &unstructured.Unstructured{
}),
resource.NewResId(service, "svc1"): resource.NewBehaviorlessResource(
&unstructured.Unstructured{
Object: map[string]interface{}{
"apiVersion": "v1",
"kind": "Service",
@@ -93,15 +90,11 @@ func TestLabelsRun(t *testing.T) {
},
},
},
},
},
}),
}
expected := resource.ResourceCollection{
{
GVK: schema.GroupVersionKind{Version: "v1", Kind: "ConfigMap"},
Name: "cm1",
}: &resource.Resource{
Data: &unstructured.Unstructured{
expected := resmap.ResMap{
resource.NewResId(cmap, "cm1"): resource.NewBehaviorlessResource(
&unstructured.Unstructured{
Object: map[string]interface{}{
"apiVersion": "v1",
"kind": "ConfigMap",
@@ -113,13 +106,9 @@ func TestLabelsRun(t *testing.T) {
},
},
},
},
},
{
GVK: schema.GroupVersionKind{Group: "apps", Version: "v1", Kind: "Deployment"},
Name: "deploy1",
}: &resource.Resource{
Data: &unstructured.Unstructured{
}),
resource.NewResId(deploy, "deploy1"): resource.NewBehaviorlessResource(
&unstructured.Unstructured{
Object: map[string]interface{}{
"group": "apps",
"apiVersion": "v1",
@@ -157,13 +146,9 @@ func TestLabelsRun(t *testing.T) {
},
},
},
},
},
{
GVK: schema.GroupVersionKind{Version: "v1", Kind: "Service"},
Name: "svc1",
}: &resource.Resource{
Data: &unstructured.Unstructured{
}),
resource.NewResId(service, "svc1"): resource.NewBehaviorlessResource(
&unstructured.Unstructured{
Object: map[string]interface{}{
"apiVersion": "v1",
"kind": "Service",
@@ -187,8 +172,7 @@ func TestLabelsRun(t *testing.T) {
},
},
},
},
},
}),
}
lt, err := NewDefaultingLabelsMapTransformer(map[string]string{"label-key1": "label-value1", "label-key2": "label-value2"})
@@ -200,7 +184,7 @@ func TestLabelsRun(t *testing.T) {
t.Fatalf("unexpected error: %v", err)
}
if !reflect.DeepEqual(m, expected) {
err = compareMap(m, expected)
err = expected.ErrorIfNotEqual(m)
t.Fatalf("actual doesn't match expected: %v", err)
}
}
@@ -284,12 +268,9 @@ func makeAnnotatededService() *unstructured.Unstructured {
}
func TestAnnotationsRun(t *testing.T) {
m := resource.ResourceCollection{
{
GVK: schema.GroupVersionKind{Version: "v1", Kind: "ConfigMap"},
Name: "cm1",
}: &resource.Resource{
Data: &unstructured.Unstructured{
m := resmap.ResMap{
resource.NewResId(cmap, "cm1"): resource.NewBehaviorlessResource(
&unstructured.Unstructured{
Object: map[string]interface{}{
"apiVersion": "v1",
"kind": "ConfigMap",
@@ -297,13 +278,9 @@ func TestAnnotationsRun(t *testing.T) {
"name": "cm1",
},
},
},
},
{
GVK: schema.GroupVersionKind{Group: "apps", Version: "v1", Kind: "Deployment"},
Name: "deploy1",
}: &resource.Resource{
Data: &unstructured.Unstructured{
}),
resource.NewResId(deploy, "deploy1"): resource.NewBehaviorlessResource(
&unstructured.Unstructured{
Object: map[string]interface{}{
"group": "apps",
"apiVersion": "v1",
@@ -329,13 +306,9 @@ func TestAnnotationsRun(t *testing.T) {
},
},
},
},
},
{
GVK: schema.GroupVersionKind{Version: "v1", Kind: "Service"},
Name: "svc1",
}: &resource.Resource{
Data: &unstructured.Unstructured{
}),
resource.NewResId(service, "svc1"): resource.NewBehaviorlessResource(
&unstructured.Unstructured{
Object: map[string]interface{}{
"apiVersion": "v1",
"kind": "Service",
@@ -351,15 +324,11 @@ func TestAnnotationsRun(t *testing.T) {
},
},
},
},
},
}),
}
expected := resource.ResourceCollection{
{
GVK: schema.GroupVersionKind{Version: "v1", Kind: "ConfigMap"},
Name: "cm1",
}: &resource.Resource{
Data: &unstructured.Unstructured{
expected := resmap.ResMap{
resource.NewResId(cmap, "cm1"): resource.NewBehaviorlessResource(
&unstructured.Unstructured{
Object: map[string]interface{}{
"apiVersion": "v1",
"kind": "ConfigMap",
@@ -371,13 +340,9 @@ func TestAnnotationsRun(t *testing.T) {
},
},
},
},
},
{
GVK: schema.GroupVersionKind{Group: "apps", Version: "v1", Kind: "Deployment"},
Name: "deploy1",
}: &resource.Resource{
Data: &unstructured.Unstructured{
}),
resource.NewResId(deploy, "deploy1"): resource.NewBehaviorlessResource(
&unstructured.Unstructured{
Object: map[string]interface{}{
"group": "apps",
"apiVersion": "v1",
@@ -411,13 +376,9 @@ func TestAnnotationsRun(t *testing.T) {
},
},
},
},
},
{
GVK: schema.GroupVersionKind{Version: "v1", Kind: "Service"},
Name: "svc1",
}: &resource.Resource{
Data: &unstructured.Unstructured{
}),
resource.NewResId(service, "svc1"): resource.NewBehaviorlessResource(
&unstructured.Unstructured{
Object: map[string]interface{}{
"apiVersion": "v1",
"kind": "Service",
@@ -437,8 +398,7 @@ func TestAnnotationsRun(t *testing.T) {
},
},
},
},
},
}),
}
at, err := NewDefaultingAnnotationsMapTransformer(map[string]string{"anno-key1": "anno-value1", "anno-key2": "anno-value2"})
if err != nil {
@@ -449,7 +409,7 @@ func TestAnnotationsRun(t *testing.T) {
t.Fatalf("unexpected error: %v", err)
}
if !reflect.DeepEqual(m, expected) {
err = compareMap(m, expected)
err = expected.ErrorIfNotEqual(m)
t.Fatalf("actual doesn't match expected: %v", err)
}
}

View File

@@ -16,7 +16,7 @@ limitations under the License.
package transformers
import "github.com/kubernetes-sigs/kustomize/pkg/resource"
import "github.com/kubernetes-sigs/kustomize/pkg/resmap"
// multiTransformer contains a list of transformers.
type multiTransformer struct {
@@ -34,7 +34,7 @@ func NewMultiTransformer(t []Transformer) Transformer {
}
// Transform prepends the name prefix.
func (o *multiTransformer) Transform(m resource.ResourceCollection) error {
func (o *multiTransformer) Transform(m resmap.ResMap) error {
for _, t := range o.transformers {
err := t.Transform(m)
if err != nil {

View File

@@ -21,7 +21,7 @@ import (
"fmt"
"github.com/kubernetes-sigs/kustomize/pkg/hash"
"github.com/kubernetes-sigs/kustomize/pkg/resource"
"github.com/kubernetes-sigs/kustomize/pkg/resmap"
"github.com/kubernetes-sigs/kustomize/pkg/types"
"k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
@@ -40,14 +40,14 @@ func NewNameHashTransformer() Transformer {
}
// Transform appends hash to configmaps and secrets.
func (o *nameHashTransformer) Transform(m resource.ResourceCollection) error {
for gvkn, obj := range m {
func (o *nameHashTransformer) Transform(m resmap.ResMap) error {
for id, obj := range m {
switch {
case types.SelectByGVK(gvkn.GVK, &schema.GroupVersionKind{Version: "v1", Kind: "ConfigMap"}):
appendHashForConfigMap(obj.Data)
case types.SelectByGVK(id.Gvk(), &schema.GroupVersionKind{Version: "v1", Kind: "ConfigMap"}):
appendHashForConfigMap(obj.Unstruct())
case types.SelectByGVK(gvkn.GVK, &schema.GroupVersionKind{Version: "v1", Kind: "Secret"}):
appendHashForSecret(obj.Data)
case types.SelectByGVK(id.Gvk(), &schema.GroupVersionKind{Version: "v1", Kind: "Secret"}):
appendHashForSecret(obj.Unstruct())
}
}
return nil

View File

@@ -20,18 +20,15 @@ import (
"reflect"
"testing"
"github.com/kubernetes-sigs/kustomize/pkg/resmap"
"github.com/kubernetes-sigs/kustomize/pkg/resource"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime/schema"
)
func TestNameHashTransformer(t *testing.T) {
objs := resource.ResourceCollection{
{
GVK: schema.GroupVersionKind{Version: "v1", Kind: "ConfigMap"},
Name: "cm1",
}: &resource.Resource{
Data: &unstructured.Unstructured{
objs := resmap.ResMap{
resource.NewResId(cmap, "cm1"): resource.NewBehaviorlessResource(
&unstructured.Unstructured{
Object: map[string]interface{}{
"apiVersion": "v1",
"kind": "ConfigMap",
@@ -39,13 +36,9 @@ func TestNameHashTransformer(t *testing.T) {
"name": "cm1",
},
},
},
},
{
GVK: schema.GroupVersionKind{Group: "apps", Version: "v1", Kind: "Deployment"},
Name: "deploy1",
}: &resource.Resource{
Data: &unstructured.Unstructured{
}),
resource.NewResId(deploy, "deploy1"): resource.NewBehaviorlessResource(
&unstructured.Unstructured{
Object: map[string]interface{}{
"group": "apps",
"apiVersion": "v1",
@@ -71,13 +64,9 @@ func TestNameHashTransformer(t *testing.T) {
},
},
},
},
},
{
GVK: schema.GroupVersionKind{Version: "v1", Kind: "Service"},
Name: "svc1",
}: &resource.Resource{
Data: &unstructured.Unstructured{
}),
resource.NewResId(service, "svc1"): resource.NewBehaviorlessResource(
&unstructured.Unstructured{
Object: map[string]interface{}{
"apiVersion": "v1",
"kind": "Service",
@@ -93,13 +82,9 @@ func TestNameHashTransformer(t *testing.T) {
},
},
},
},
},
{
GVK: schema.GroupVersionKind{Version: "v1", Kind: "Secret"},
Name: "secret1",
}: &resource.Resource{
Data: &unstructured.Unstructured{
}),
resource.NewResId(secret, "secret1"): resource.NewBehaviorlessResource(
&unstructured.Unstructured{
Object: map[string]interface{}{
"apiVersion": "v1",
"kind": "Secret",
@@ -107,16 +92,12 @@ func TestNameHashTransformer(t *testing.T) {
"name": "secret1",
},
},
},
},
}),
}
expected := resource.ResourceCollection{
{
GVK: schema.GroupVersionKind{Version: "v1", Kind: "ConfigMap"},
Name: "cm1",
}: &resource.Resource{
Data: &unstructured.Unstructured{
expected := resmap.ResMap{
resource.NewResId(cmap, "cm1"): resource.NewBehaviorlessResource(
&unstructured.Unstructured{
Object: map[string]interface{}{
"apiVersion": "v1",
"kind": "ConfigMap",
@@ -124,13 +105,9 @@ func TestNameHashTransformer(t *testing.T) {
"name": "cm1-m462kdfb68",
},
},
},
},
{
GVK: schema.GroupVersionKind{Group: "apps", Version: "v1", Kind: "Deployment"},
Name: "deploy1",
}: &resource.Resource{
Data: &unstructured.Unstructured{
}),
resource.NewResId(deploy, "deploy1"): resource.NewBehaviorlessResource(
&unstructured.Unstructured{
Object: map[string]interface{}{
"group": "apps",
"apiVersion": "v1",
@@ -156,13 +133,9 @@ func TestNameHashTransformer(t *testing.T) {
},
},
},
},
},
{
GVK: schema.GroupVersionKind{Version: "v1", Kind: "Service"},
Name: "svc1",
}: &resource.Resource{
Data: &unstructured.Unstructured{
}),
resource.NewResId(service, "svc1"): resource.NewBehaviorlessResource(
&unstructured.Unstructured{
Object: map[string]interface{}{
"apiVersion": "v1",
"kind": "Service",
@@ -178,13 +151,9 @@ func TestNameHashTransformer(t *testing.T) {
},
},
},
},
},
{
GVK: schema.GroupVersionKind{Version: "v1", Kind: "Secret"},
Name: "secret1",
}: &resource.Resource{
Data: &unstructured.Unstructured{
}),
resource.NewResId(secret, "secret1"): resource.NewBehaviorlessResource(
&unstructured.Unstructured{
Object: map[string]interface{}{
"apiVersion": "v1",
"kind": "Secret",
@@ -192,15 +161,14 @@ func TestNameHashTransformer(t *testing.T) {
"name": "secret1-7kc45hd5f7",
},
},
},
},
}),
}
tran := NewNameHashTransformer()
tran.Transform(objs)
if !reflect.DeepEqual(objs, expected) {
err := compareMap(objs, expected)
err := expected.ErrorIfNotEqual(objs)
t.Fatalf("actual doesn't match expected: %v", err)
}
}

View File

@@ -20,7 +20,7 @@ import (
"errors"
"fmt"
"github.com/kubernetes-sigs/kustomize/pkg/resource"
"github.com/kubernetes-sigs/kustomize/pkg/resmap"
"github.com/kubernetes-sigs/kustomize/pkg/types"
"k8s.io/apimachinery/pkg/runtime/schema"
)
@@ -51,13 +51,13 @@ func NewNameReferenceTransformer(pc []referencePathConfig) (Transformer, error)
// associated with the key. e.g. if <k, v> is one of the key-value pair in the map,
// then the old name is k.Name and the new name is v.GetName()
func (o *nameReferenceTransformer) Transform(
m resource.ResourceCollection) error {
for GVKn := range m {
obj := m[GVKn].Data
m resmap.ResMap) error {
for id := range m {
obj := m[id].Unstruct()
objMap := obj.UnstructuredContent()
for _, referencePathConfig := range o.pathConfigs {
for _, path := range referencePathConfig.pathConfigs {
if !types.SelectByGVK(GVKn.GVK, path.GroupVersionKind) {
if !types.SelectByGVK(id.Gvk(), path.GroupVersionKind) {
continue
}
err := mutateField(objMap, path.Path, path.CreateIfNotPresent,
@@ -71,25 +71,9 @@ func (o *nameReferenceTransformer) Transform(
return nil
}
// noMatchingGVKNError indicates failing to find a gvkn.GroupVersionKindName.
type noMatchingGVKNError struct {
message string
}
// newNoMatchingGVKNError constructs an instance of noMatchingGVKNError with
// a given error message.
func newNoMatchingGVKNError(errMsg string) noMatchingGVKNError {
return noMatchingGVKNError{errMsg}
}
// Error returns the error in string format.
func (err noMatchingGVKNError) Error() string {
return err.message
}
func (o *nameReferenceTransformer) updateNameReference(
GVK schema.GroupVersionKind,
m resource.ResourceCollection,
m resmap.ResMap,
) func(in interface{}) (interface{}, error) {
return func(in interface{}) (interface{}, error) {
s, ok := in.(string)
@@ -97,12 +81,12 @@ func (o *nameReferenceTransformer) updateNameReference(
return nil, fmt.Errorf("%#v is expectd to be %T", in, s)
}
for GVKn, obj := range m {
if !types.SelectByGVK(GVKn.GVK, &GVK) {
for id, obj := range m {
if !types.SelectByGVK(id.Gvk(), &GVK) {
continue
}
if GVKn.Name == s {
return obj.Data.GetName(), nil
if id.Name() == s {
return obj.Unstruct().GetName(), nil
}
}
return in, nil

View File

@@ -20,18 +20,15 @@ import (
"reflect"
"testing"
"github.com/kubernetes-sigs/kustomize/pkg/resmap"
"github.com/kubernetes-sigs/kustomize/pkg/resource"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime/schema"
)
func TestNameReferenceRun(t *testing.T) {
m := resource.ResourceCollection{
{
GVK: schema.GroupVersionKind{Version: "v1", Kind: "ConfigMap"},
Name: "cm1",
}: &resource.Resource{
Data: &unstructured.Unstructured{
m := resmap.ResMap{
resource.NewResId(cmap, "cm1"): resource.NewBehaviorlessResource(
&unstructured.Unstructured{
Object: map[string]interface{}{
"apiVersion": "v1",
"kind": "ConfigMap",
@@ -39,13 +36,9 @@ func TestNameReferenceRun(t *testing.T) {
"name": "someprefix-cm1-somehash",
},
},
},
},
{
GVK: schema.GroupVersionKind{Version: "v1", Kind: "Secret"},
Name: "secret1",
}: &resource.Resource{
Data: &unstructured.Unstructured{
}),
resource.NewResId(secret, "secret1"): resource.NewBehaviorlessResource(
&unstructured.Unstructured{
Object: map[string]interface{}{
"apiVersion": "v1",
"kind": "Secret",
@@ -53,13 +46,9 @@ func TestNameReferenceRun(t *testing.T) {
"name": "someprefix-secret1-somehash",
},
},
},
},
{
GVK: schema.GroupVersionKind{Group: "apps", Version: "v1", Kind: "Deployment"},
Name: "deploy1",
}: &resource.Resource{
Data: &unstructured.Unstructured{
}),
resource.NewResId(deploy, "deploy1"): resource.NewBehaviorlessResource(
&unstructured.Unstructured{
Object: map[string]interface{}{
"group": "apps",
"apiVersion": "v1",
@@ -122,16 +111,12 @@ func TestNameReferenceRun(t *testing.T) {
},
},
},
},
},
}),
}
expected := resource.ResourceCollection{
{
GVK: schema.GroupVersionKind{Version: "v1", Kind: "ConfigMap"},
Name: "cm1",
}: &resource.Resource{
Data: &unstructured.Unstructured{
expected := resmap.ResMap{
resource.NewResId(cmap, "cm1"): resource.NewBehaviorlessResource(
&unstructured.Unstructured{
Object: map[string]interface{}{
"apiVersion": "v1",
"kind": "ConfigMap",
@@ -139,13 +124,9 @@ func TestNameReferenceRun(t *testing.T) {
"name": "someprefix-cm1-somehash",
},
},
},
},
{
GVK: schema.GroupVersionKind{Version: "v1", Kind: "Secret"},
Name: "secret1",
}: &resource.Resource{
Data: &unstructured.Unstructured{
}),
resource.NewResId(secret, "secret1"): resource.NewBehaviorlessResource(
&unstructured.Unstructured{
Object: map[string]interface{}{
"apiVersion": "v1",
"kind": "Secret",
@@ -153,13 +134,9 @@ func TestNameReferenceRun(t *testing.T) {
"name": "someprefix-secret1-somehash",
},
},
},
},
{
GVK: schema.GroupVersionKind{Group: "apps", Version: "v1", Kind: "Deployment"},
Name: "deploy1",
}: &resource.Resource{
Data: &unstructured.Unstructured{
}),
resource.NewResId(deploy, "deploy1"): resource.NewBehaviorlessResource(
&unstructured.Unstructured{
Object: map[string]interface{}{
"group": "apps",
"apiVersion": "v1",
@@ -222,8 +199,7 @@ func TestNameReferenceRun(t *testing.T) {
},
},
},
},
},
}),
}
nrt, err := NewDefaultingNameReferenceTransformer()
@@ -232,7 +208,7 @@ func TestNameReferenceRun(t *testing.T) {
t.Fatalf("unexpected error: %v", err)
}
if !reflect.DeepEqual(m, expected) {
err = compareMap(m, expected)
err = expected.ErrorIfNotEqual(m)
t.Fatalf("actual doesn't match expected: %v", err)
}
}

View File

@@ -16,7 +16,7 @@ limitations under the License.
package transformers
import "github.com/kubernetes-sigs/kustomize/pkg/resource"
import "github.com/kubernetes-sigs/kustomize/pkg/resmap"
// noOpTransformer contains a no-op transformer.
type noOpTransformer struct{}
@@ -29,6 +29,6 @@ func NewNoOpTransformer() Transformer {
}
// Transform does nothing.
func (o *noOpTransformer) Transform(_ resource.ResourceCollection) error {
func (o *noOpTransformer) Transform(_ resmap.ResMap) error {
return nil
}

View File

@@ -22,6 +22,7 @@ import (
jsonpatch "github.com/evanphx/json-patch"
"github.com/kubernetes-sigs/kustomize/pkg/resmap"
"github.com/kubernetes-sigs/kustomize/pkg/resource"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime"
@@ -45,8 +46,8 @@ func NewOverlayTransformer(overlay []*resource.Resource) (Transformer, error) {
}
// Transform apply the overlay on top of the base resources.
func (o *overlayTransformer) Transform(baseResourceMap resource.ResourceCollection) error {
// Merge and then index the patches by GVKN.
func (o *overlayTransformer) Transform(baseResourceMap resmap.ResMap) error {
// Merge and then index the patches by Id.
overlays, err := o.mergePatches()
if err != nil {
return err
@@ -55,22 +56,22 @@ func (o *overlayTransformer) Transform(baseResourceMap resource.ResourceCollecti
// Strategic merge the resources exist in both base and overlay.
for _, overlay := range overlays {
// Merge overlay with base resource.
gvkn := overlay.GVKN()
base, found := baseResourceMap[gvkn]
id := overlay.Id()
base, found := baseResourceMap[id]
if !found {
return fmt.Errorf("failed to find an object with %#v to apply the patch", gvkn.GVK)
return fmt.Errorf("failed to find an object with %#v to apply the patch", id.Gvk())
}
merged := map[string]interface{}{}
versionedObj, err := scheme.Scheme.New(gvkn.GVK)
baseName := base.Data.GetName()
versionedObj, err := scheme.Scheme.New(id.Gvk())
baseName := base.Unstruct().GetName()
switch {
case runtime.IsNotRegisteredError(err):
// Use JSON merge patch to handle types w/o schema
baseBytes, err := json.Marshal(base.Data)
baseBytes, err := json.Marshal(base.Unstruct())
if err != nil {
return err
}
patchBytes, err := json.Marshal(overlay.Data)
patchBytes, err := json.Marshal(overlay.Unstruct())
if err != nil {
return err
}
@@ -94,33 +95,33 @@ func (o *overlayTransformer) Transform(baseResourceMap resource.ResourceCollecti
return err
}
merged, err = strategicpatch.StrategicMergeMapPatchUsingLookupPatchMeta(
base.Data.Object,
overlay.Data.Object,
base.Unstruct().Object,
overlay.Unstruct().Object,
lookupPatchMeta)
if err != nil {
return err
}
}
base.Data.SetName(baseName)
baseResourceMap[gvkn].Data.Object = merged
base.Unstruct().SetName(baseName)
baseResourceMap[id].Unstruct().Object = merged
}
return nil
}
// mergePatches merge and index patches by GVKN.
// mergePatches merge and index patches by Id.
// It errors out if there is conflict between patches.
func (o *overlayTransformer) mergePatches() (resource.ResourceCollection, error) {
rc := resource.ResourceCollection{}
func (o *overlayTransformer) mergePatches() (resmap.ResMap, error) {
rc := resmap.ResMap{}
patches := resourcesToObjects(o.overlay)
for ix, patch := range o.overlay {
gvkn := patch.GVKN()
existing, found := rc[gvkn]
id := patch.Id()
existing, found := rc[id]
if !found {
rc[gvkn] = patch
rc[id] = patch
continue
}
versionedObj, err := scheme.Scheme.New(gvkn.GVK)
versionedObj, err := scheme.Scheme.New(id.Gvk())
if err != nil && !runtime.IsNotRegisteredError(err) {
return nil, err
}
@@ -134,7 +135,7 @@ func (o *overlayTransformer) mergePatches() (resource.ResourceCollection, error)
}
}
conflict, err := cd.hasConflict(existing.Data, patch.Data)
conflict, err := cd.hasConflict(existing.Unstruct(), patch.Unstruct())
if err != nil {
return nil, err
}
@@ -143,13 +144,13 @@ func (o *overlayTransformer) mergePatches() (resource.ResourceCollection, error)
if err != nil {
return nil, err
}
return nil, fmt.Errorf("there is conflict between %#v and %#v", conflictingPatch.Object, patch.Data.Object)
return nil, fmt.Errorf("there is conflict between %#v and %#v", conflictingPatch.Object, patch.Unstruct().Object)
} else {
merged, err := cd.mergePatches(existing.Data, patch.Data)
merged, err := cd.mergePatches(existing.Unstruct(), patch.Unstruct())
if err != nil {
return nil, err
}
existing.Data = merged
existing.SetUnstruct(merged)
}
}
return rc, nil
@@ -158,7 +159,7 @@ func (o *overlayTransformer) mergePatches() (resource.ResourceCollection, error)
func resourcesToObjects(rs []*resource.Resource) []*unstructured.Unstructured {
objectList := make([]*unstructured.Unstructured, len(rs))
for i := range rs {
objectList[i] = rs[i].Data
objectList[i] = rs[i].Unstruct()
}
return objectList
}

View File

@@ -21,18 +21,15 @@ import (
"strings"
"testing"
"github.com/kubernetes-sigs/kustomize/pkg/resmap"
"github.com/kubernetes-sigs/kustomize/pkg/resource"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime/schema"
)
func TestOverlayRun(t *testing.T) {
base := resource.ResourceCollection{
{
GVK: schema.GroupVersionKind{Group: "apps", Version: "v1", Kind: "Deployment"},
Name: "deploy1",
}: &resource.Resource{
Data: &unstructured.Unstructured{
base := resmap.ResMap{
resource.NewResId(deploy, "deploy1"): resource.NewBehaviorlessResource(
&unstructured.Unstructured{
Object: map[string]interface{}{
"apiVersion": "apps/v1",
"kind": "Deployment",
@@ -57,35 +54,32 @@ func TestOverlayRun(t *testing.T) {
},
},
},
},
},
}),
}
overlay := []*resource.Resource{
{
Data: &unstructured.Unstructured{
Object: map[string]interface{}{
"apiVersion": "apps/v1",
"kind": "Deployment",
"metadata": map[string]interface{}{
"name": "deploy1",
},
"spec": map[string]interface{}{
"template": map[string]interface{}{
"metadata": map[string]interface{}{
"labels": map[string]interface{}{
"another-label": "foo",
},
resource.NewBehaviorlessResource(&unstructured.Unstructured{
Object: map[string]interface{}{
"apiVersion": "apps/v1",
"kind": "Deployment",
"metadata": map[string]interface{}{
"name": "deploy1",
},
"spec": map[string]interface{}{
"template": map[string]interface{}{
"metadata": map[string]interface{}{
"labels": map[string]interface{}{
"another-label": "foo",
},
"spec": map[string]interface{}{
"containers": []interface{}{
map[string]interface{}{
"name": "nginx",
"image": "nginx:latest",
"env": []interface{}{
map[string]interface{}{
"name": "SOMEENV",
"value": "BAR",
},
},
"spec": map[string]interface{}{
"containers": []interface{}{
map[string]interface{}{
"name": "nginx",
"image": "nginx:latest",
"env": []interface{}{
map[string]interface{}{
"name": "SOMEENV",
"value": "BAR",
},
},
},
@@ -95,13 +89,11 @@ func TestOverlayRun(t *testing.T) {
},
},
},
),
}
expected := resource.ResourceCollection{
{
GVK: schema.GroupVersionKind{Group: "apps", Version: "v1", Kind: "Deployment"},
Name: "deploy1",
}: &resource.Resource{
Data: &unstructured.Unstructured{
expected := resmap.ResMap{
resource.NewResId(deploy, "deploy1"): resource.NewBehaviorlessResource(
&unstructured.Unstructured{
Object: map[string]interface{}{
"apiVersion": "apps/v1",
"kind": "Deployment",
@@ -133,8 +125,7 @@ func TestOverlayRun(t *testing.T) {
},
},
},
},
},
}),
}
lt, err := NewOverlayTransformer(overlay)
if err != nil {
@@ -145,18 +136,15 @@ func TestOverlayRun(t *testing.T) {
t.Fatalf("unexpected error: %v", err)
}
if !reflect.DeepEqual(base, expected) {
err = compareMap(base, expected)
err = expected.ErrorIfNotEqual(base)
t.Fatalf("actual doesn't match expected: %v", err)
}
}
func TestMultiplePatches(t *testing.T) {
base := resource.ResourceCollection{
{
GVK: schema.GroupVersionKind{Group: "apps", Version: "v1", Kind: "Deployment"},
Name: "deploy1",
}: &resource.Resource{
Data: &unstructured.Unstructured{
base := resmap.ResMap{
resource.NewResId(deploy, "deploy1"): resource.NewBehaviorlessResource(
&unstructured.Unstructured{
Object: map[string]interface{}{
"apiVersion": "apps/v1",
"kind": "Deployment",
@@ -176,30 +164,27 @@ func TestMultiplePatches(t *testing.T) {
},
},
},
},
},
}),
}
overlay := []*resource.Resource{
{
Data: &unstructured.Unstructured{
Object: map[string]interface{}{
"apiVersion": "apps/v1",
"kind": "Deployment",
"metadata": map[string]interface{}{
"name": "deploy1",
},
"spec": map[string]interface{}{
"template": map[string]interface{}{
"spec": map[string]interface{}{
"containers": []interface{}{
map[string]interface{}{
"name": "nginx",
"image": "nginx:latest",
"env": []interface{}{
map[string]interface{}{
"name": "SOMEENV",
"value": "BAR",
},
resource.NewBehaviorlessResource(&unstructured.Unstructured{
Object: map[string]interface{}{
"apiVersion": "apps/v1",
"kind": "Deployment",
"metadata": map[string]interface{}{
"name": "deploy1",
},
"spec": map[string]interface{}{
"template": map[string]interface{}{
"spec": map[string]interface{}{
"containers": []interface{}{
map[string]interface{}{
"name": "nginx",
"image": "nginx:latest",
"env": []interface{}{
map[string]interface{}{
"name": "SOMEENV",
"value": "BAR",
},
},
},
@@ -209,31 +194,30 @@ func TestMultiplePatches(t *testing.T) {
},
},
},
{
Data: &unstructured.Unstructured{
Object: map[string]interface{}{
"apiVersion": "apps/v1",
"kind": "Deployment",
"metadata": map[string]interface{}{
"name": "deploy1",
},
"spec": map[string]interface{}{
"template": map[string]interface{}{
"spec": map[string]interface{}{
"containers": []interface{}{
map[string]interface{}{
"name": "nginx",
"env": []interface{}{
map[string]interface{}{
"name": "ANOTHERENV",
"value": "HELLO",
},
),
resource.NewBehaviorlessResource(&unstructured.Unstructured{
Object: map[string]interface{}{
"apiVersion": "apps/v1",
"kind": "Deployment",
"metadata": map[string]interface{}{
"name": "deploy1",
},
"spec": map[string]interface{}{
"template": map[string]interface{}{
"spec": map[string]interface{}{
"containers": []interface{}{
map[string]interface{}{
"name": "nginx",
"env": []interface{}{
map[string]interface{}{
"name": "ANOTHERENV",
"value": "HELLO",
},
},
map[string]interface{}{
"name": "busybox",
"image": "busybox",
},
},
map[string]interface{}{
"name": "busybox",
"image": "busybox",
},
},
},
@@ -241,13 +225,11 @@ func TestMultiplePatches(t *testing.T) {
},
},
},
),
}
expected := resource.ResourceCollection{
{
GVK: schema.GroupVersionKind{Group: "apps", Version: "v1", Kind: "Deployment"},
Name: "deploy1",
}: &resource.Resource{
Data: &unstructured.Unstructured{
expected := resmap.ResMap{
resource.NewResId(deploy, "deploy1"): resource.NewBehaviorlessResource(
&unstructured.Unstructured{
Object: map[string]interface{}{
"apiVersion": "apps/v1",
"kind": "Deployment",
@@ -281,8 +263,7 @@ func TestMultiplePatches(t *testing.T) {
},
},
},
},
},
}),
}
lt, err := NewOverlayTransformer(overlay)
if err != nil {
@@ -293,18 +274,15 @@ func TestMultiplePatches(t *testing.T) {
t.Fatalf("unexpected error: %v", err)
}
if !reflect.DeepEqual(base, expected) {
err = compareMap(base, expected)
err = expected.ErrorIfNotEqual(base)
t.Fatalf("actual doesn't match expected: %v", err)
}
}
func TestMultiplePatchesWithConflict(t *testing.T) {
base := resource.ResourceCollection{
{
GVK: schema.GroupVersionKind{Group: "apps", Version: "v1", Kind: "Deployment"},
Name: "deploy1",
}: &resource.Resource{
Data: &unstructured.Unstructured{
base := resmap.ResMap{
resource.NewResId(deploy, "deploy1"): resource.NewBehaviorlessResource(
&unstructured.Unstructured{
Object: map[string]interface{}{
"apiVersion": "apps/v1",
"kind": "Deployment",
@@ -324,30 +302,27 @@ func TestMultiplePatchesWithConflict(t *testing.T) {
},
},
},
},
},
}),
}
overlay := []*resource.Resource{
{
Data: &unstructured.Unstructured{
Object: map[string]interface{}{
"apiVersion": "apps/v1",
"kind": "Deployment",
"metadata": map[string]interface{}{
"name": "deploy1",
},
"spec": map[string]interface{}{
"template": map[string]interface{}{
"spec": map[string]interface{}{
"containers": []interface{}{
map[string]interface{}{
"name": "nginx",
"image": "nginx:latest",
"env": []interface{}{
map[string]interface{}{
"name": "SOMEENV",
"value": "BAR",
},
resource.NewBehaviorlessResource(&unstructured.Unstructured{
Object: map[string]interface{}{
"apiVersion": "apps/v1",
"kind": "Deployment",
"metadata": map[string]interface{}{
"name": "deploy1",
},
"spec": map[string]interface{}{
"template": map[string]interface{}{
"spec": map[string]interface{}{
"containers": []interface{}{
map[string]interface{}{
"name": "nginx",
"image": "nginx:latest",
"env": []interface{}{
map[string]interface{}{
"name": "SOMEENV",
"value": "BAR",
},
},
},
@@ -357,22 +332,21 @@ func TestMultiplePatchesWithConflict(t *testing.T) {
},
},
},
{
Data: &unstructured.Unstructured{
Object: map[string]interface{}{
"apiVersion": "apps/v1",
"kind": "Deployment",
"metadata": map[string]interface{}{
"name": "deploy1",
},
"spec": map[string]interface{}{
"template": map[string]interface{}{
"spec": map[string]interface{}{
"containers": []interface{}{
map[string]interface{}{
"name": "nginx",
"image": "nginx:1.7.9",
},
),
resource.NewBehaviorlessResource(&unstructured.Unstructured{
Object: map[string]interface{}{
"apiVersion": "apps/v1",
"kind": "Deployment",
"metadata": map[string]interface{}{
"name": "deploy1",
},
"spec": map[string]interface{}{
"template": map[string]interface{}{
"spec": map[string]interface{}{
"containers": []interface{}{
map[string]interface{}{
"name": "nginx",
"image": "nginx:1.7.9",
},
},
},
@@ -380,6 +354,7 @@ func TestMultiplePatchesWithConflict(t *testing.T) {
},
},
},
),
}
lt, err := NewOverlayTransformer(overlay)
@@ -396,12 +371,9 @@ func TestMultiplePatchesWithConflict(t *testing.T) {
}
func TestNoSchemaOverlayRun(t *testing.T) {
base := resource.ResourceCollection{
{
GVK: schema.GroupVersionKind{Group: "example.com", Version: "v1", Kind: "Foo"},
Name: "my-foo",
}: &resource.Resource{
Data: &unstructured.Unstructured{
base := resmap.ResMap{
resource.NewResId(foo, "my-foo"): resource.NewBehaviorlessResource(
&unstructured.Unstructured{
Object: map[string]interface{}{
"apiVersion": "example.com/v1",
"kind": "Foo",
@@ -415,34 +387,29 @@ func TestNoSchemaOverlayRun(t *testing.T) {
},
},
},
},
},
}),
}
overlay := []*resource.Resource{
{
Data: &unstructured.Unstructured{
Object: map[string]interface{}{
"apiVersion": "example.com/v1",
"kind": "Foo",
"metadata": map[string]interface{}{
"name": "my-foo",
},
"spec": map[string]interface{}{
"bar": map[string]interface{}{
"B": nil,
"C": "Z",
},
resource.NewBehaviorlessResource(&unstructured.Unstructured{
Object: map[string]interface{}{
"apiVersion": "example.com/v1",
"kind": "Foo",
"metadata": map[string]interface{}{
"name": "my-foo",
},
"spec": map[string]interface{}{
"bar": map[string]interface{}{
"B": nil,
"C": "Z",
},
},
},
},
),
}
expected := resource.ResourceCollection{
{
GVK: schema.GroupVersionKind{Group: "example.com", Version: "v1", Kind: "Foo"},
Name: "my-foo",
}: &resource.Resource{
Data: &unstructured.Unstructured{
expected := resmap.ResMap{
resource.NewResId(foo, "my-foo"): resource.NewBehaviorlessResource(
&unstructured.Unstructured{
Object: map[string]interface{}{
"apiVersion": "example.com/v1",
"kind": "Foo",
@@ -456,8 +423,7 @@ func TestNoSchemaOverlayRun(t *testing.T) {
},
},
},
},
},
}),
}
lt, err := NewOverlayTransformer(overlay)
@@ -468,18 +434,15 @@ func TestNoSchemaOverlayRun(t *testing.T) {
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
if err = compareMap(base, expected); err != nil {
if err = expected.ErrorIfNotEqual(base); err != nil {
t.Fatalf("actual doesn't match expected: %v", err)
}
}
func TestNoSchemaMultiplePatches(t *testing.T) {
base := resource.ResourceCollection{
{
GVK: schema.GroupVersionKind{Group: "example.com", Version: "v1", Kind: "Foo"},
Name: "my-foo",
}: &resource.Resource{
Data: &unstructured.Unstructured{
base := resmap.ResMap{
resource.NewResId(foo, "my-foo"): resource.NewBehaviorlessResource(
&unstructured.Unstructured{
Object: map[string]interface{}{
"apiVersion": "example.com/v1",
"kind": "Foo",
@@ -493,54 +456,48 @@ func TestNoSchemaMultiplePatches(t *testing.T) {
},
},
},
},
},
}),
}
overlay := []*resource.Resource{
{
Data: &unstructured.Unstructured{
Object: map[string]interface{}{
"apiVersion": "example.com/v1",
"kind": "Foo",
"metadata": map[string]interface{}{
"name": "my-foo",
},
"spec": map[string]interface{}{
"bar": map[string]interface{}{
"B": nil,
"C": "Z",
},
resource.NewBehaviorlessResource(&unstructured.Unstructured{
Object: map[string]interface{}{
"apiVersion": "example.com/v1",
"kind": "Foo",
"metadata": map[string]interface{}{
"name": "my-foo",
},
"spec": map[string]interface{}{
"bar": map[string]interface{}{
"B": nil,
"C": "Z",
},
},
},
},
{
Data: &unstructured.Unstructured{
Object: map[string]interface{}{
"apiVersion": "example.com/v1",
"kind": "Foo",
"metadata": map[string]interface{}{
"name": "my-foo",
),
resource.NewBehaviorlessResource(&unstructured.Unstructured{
Object: map[string]interface{}{
"apiVersion": "example.com/v1",
"kind": "Foo",
"metadata": map[string]interface{}{
"name": "my-foo",
},
"spec": map[string]interface{}{
"bar": map[string]interface{}{
"C": "Z",
"D": "W",
},
"spec": map[string]interface{}{
"bar": map[string]interface{}{
"C": "Z",
"D": "W",
},
"baz": map[string]interface{}{
"hello": "world",
},
"baz": map[string]interface{}{
"hello": "world",
},
},
},
},
),
}
expected := resource.ResourceCollection{
{
GVK: schema.GroupVersionKind{Group: "example.com", Version: "v1", Kind: "Foo"},
Name: "my-foo",
}: &resource.Resource{
Data: &unstructured.Unstructured{
expected := resmap.ResMap{
resource.NewResId(foo, "my-foo"): resource.NewBehaviorlessResource(
&unstructured.Unstructured{
Object: map[string]interface{}{
"apiVersion": "example.com/v1",
"kind": "Foo",
@@ -558,8 +515,7 @@ func TestNoSchemaMultiplePatches(t *testing.T) {
},
},
},
},
},
}),
}
lt, err := NewOverlayTransformer(overlay)
@@ -570,18 +526,15 @@ func TestNoSchemaMultiplePatches(t *testing.T) {
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
if err = compareMap(base, expected); err != nil {
if err = expected.ErrorIfNotEqual(base); err != nil {
t.Fatalf("actual doesn't match expected: %v", err)
}
}
func TestNoSchemaMultiplePatchesWithConflict(t *testing.T) {
base := resource.ResourceCollection{
{
GVK: schema.GroupVersionKind{Group: "example.com", Version: "v1", Kind: "Foo"},
Name: "my-foo",
}: &resource.Resource{
Data: &unstructured.Unstructured{
base := resmap.ResMap{
resource.NewResId(foo, "my-foo"): resource.NewBehaviorlessResource(
&unstructured.Unstructured{
Object: map[string]interface{}{
"apiVersion": "example.com/v1",
"kind": "Foo",
@@ -595,43 +548,38 @@ func TestNoSchemaMultiplePatchesWithConflict(t *testing.T) {
},
},
},
},
},
}),
}
overlay := []*resource.Resource{
{
Data: &unstructured.Unstructured{
Object: map[string]interface{}{
"apiVersion": "example.com/v1",
"kind": "Foo",
"metadata": map[string]interface{}{
"name": "my-foo",
},
"spec": map[string]interface{}{
"bar": map[string]interface{}{
"B": nil,
"C": "Z",
},
resource.NewBehaviorlessResource(&unstructured.Unstructured{
Object: map[string]interface{}{
"apiVersion": "example.com/v1",
"kind": "Foo",
"metadata": map[string]interface{}{
"name": "my-foo",
},
"spec": map[string]interface{}{
"bar": map[string]interface{}{
"B": nil,
"C": "Z",
},
},
},
},
{
Data: &unstructured.Unstructured{
Object: map[string]interface{}{
"apiVersion": "example.com/v1",
"kind": "Foo",
"metadata": map[string]interface{}{
"name": "my-foo",
},
"spec": map[string]interface{}{
"bar": map[string]interface{}{
"C": "NOT_Z",
},
}),
resource.NewBehaviorlessResource(&unstructured.Unstructured{
Object: map[string]interface{}{
"apiVersion": "example.com/v1",
"kind": "Foo",
"metadata": map[string]interface{}{
"name": "my-foo",
},
"spec": map[string]interface{}{
"bar": map[string]interface{}{
"C": "NOT_Z",
},
},
},
},
}),
}
lt, err := NewOverlayTransformer(overlay)

View File

@@ -20,14 +20,14 @@ import (
"k8s.io/apimachinery/pkg/runtime/schema"
)
// PathConfig contains the configuration of a field, including the GVK it ties to,
// PathConfig contains the configuration of a field, including the gvk it ties to,
// path to the field, etc.
type PathConfig struct {
// If true, it will create the path if it is not found.
CreateIfNotPresent bool
// The GVK that this path tied to.
// If unset, it applied to any GVK
// If some fields are set, it applies to all matching GVK.
// The gvk that this path tied to.
// If unset, it applied to any gvk
// If some fields are set, it applies to all matching gvk.
GroupVersionKind *schema.GroupVersionKind
// Path to the field that will be munged.
Path []string
@@ -48,8 +48,8 @@ type PathConfig struct {
// }
type referencePathConfig struct {
// referencedGVK is the GroupVersionKind that is referenced by
// the PathConfig's GVK in the path of PathConfig.Path.
// the PathConfig's gvk in the path of PathConfig.Path.
referencedGVK schema.GroupVersionKind
// PathConfig is the GVK that is referencing the referencedGVK object's name.
// PathConfig is the gvk that is referencing the referencedGVK object's name.
pathConfigs []PathConfig
}

View File

@@ -20,7 +20,7 @@ import (
"errors"
"fmt"
"github.com/kubernetes-sigs/kustomize/pkg/resource"
"github.com/kubernetes-sigs/kustomize/pkg/resmap"
"github.com/kubernetes-sigs/kustomize/pkg/types"
)
@@ -57,12 +57,12 @@ func NewNamePrefixTransformer(pc []PathConfig, np string) (Transformer, error) {
}
// Transform prepends the name prefix.
func (o *namePrefixTransformer) Transform(m resource.ResourceCollection) error {
for gvkn := range m {
obj := m[gvkn].Data
func (o *namePrefixTransformer) Transform(m resmap.ResMap) error {
for id := range m {
obj := m[id].Unstruct()
objMap := obj.UnstructuredContent()
for _, path := range o.pathConfigs {
if !types.SelectByGVK(gvkn.GVK, path.GroupVersionKind) {
if !types.SelectByGVK(id.Gvk(), path.GroupVersionKind) {
continue
}
err := mutateField(objMap, path.Path, path.CreateIfNotPresent, o.addPrefix)

View File

@@ -20,18 +20,15 @@ import (
"reflect"
"testing"
"github.com/kubernetes-sigs/kustomize/pkg/resmap"
"github.com/kubernetes-sigs/kustomize/pkg/resource"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime/schema"
)
func TestPrefixNameRun(t *testing.T) {
m := resource.ResourceCollection{
{
GVK: schema.GroupVersionKind{Version: "v1", Kind: "ConfigMap"},
Name: "cm1",
}: &resource.Resource{
Data: &unstructured.Unstructured{
m := resmap.ResMap{
resource.NewResId(cmap, "cm1"): resource.NewBehaviorlessResource(
&unstructured.Unstructured{
Object: map[string]interface{}{
"apiVersion": "v1",
"kind": "ConfigMap",
@@ -39,13 +36,9 @@ func TestPrefixNameRun(t *testing.T) {
"name": "cm1",
},
},
},
},
{
GVK: schema.GroupVersionKind{Version: "v1", Kind: "ConfigMap"},
Name: "cm2",
}: &resource.Resource{
Data: &unstructured.Unstructured{
}),
resource.NewResId(cmap, "cm2"): resource.NewBehaviorlessResource(
&unstructured.Unstructured{
Object: map[string]interface{}{
"apiVersion": "v1",
"kind": "ConfigMap",
@@ -53,15 +46,11 @@ func TestPrefixNameRun(t *testing.T) {
"name": "cm2",
},
},
},
},
}),
}
expected := resource.ResourceCollection{
{
GVK: schema.GroupVersionKind{Version: "v1", Kind: "ConfigMap"},
Name: "cm1",
}: &resource.Resource{
Data: &unstructured.Unstructured{
expected := resmap.ResMap{
resource.NewResId(cmap, "cm1"): resource.NewBehaviorlessResource(
&unstructured.Unstructured{
Object: map[string]interface{}{
"apiVersion": "v1",
"kind": "ConfigMap",
@@ -69,13 +58,9 @@ func TestPrefixNameRun(t *testing.T) {
"name": "someprefix-cm1",
},
},
},
},
{
GVK: schema.GroupVersionKind{Version: "v1", Kind: "ConfigMap"},
Name: "cm2",
}: &resource.Resource{
Data: &unstructured.Unstructured{
}),
resource.NewResId(cmap, "cm2"): resource.NewBehaviorlessResource(
&unstructured.Unstructured{
Object: map[string]interface{}{
"apiVersion": "v1",
"kind": "ConfigMap",
@@ -83,8 +68,7 @@ func TestPrefixNameRun(t *testing.T) {
"name": "someprefix-cm2",
},
},
},
},
}),
}
npt, err := NewDefaultingNamePrefixTransformer("someprefix-")
@@ -96,7 +80,7 @@ func TestPrefixNameRun(t *testing.T) {
t.Fatalf("unexpected error: %v", err)
}
if !reflect.DeepEqual(m, expected) {
err = compareMap(m, expected)
err = expected.ErrorIfNotEqual(m)
t.Fatalf("actual doesn't match expected: %v", err)
}
}

View File

@@ -16,10 +16,10 @@ limitations under the License.
package transformers
import "github.com/kubernetes-sigs/kustomize/pkg/resource"
import "github.com/kubernetes-sigs/kustomize/pkg/resmap"
// Transformer can transform objects.
type Transformer interface {
// Transform modifies objects in a map, e.g. add prefixes or additional labels.
Transform(m resource.ResourceCollection) error
Transform(m resmap.ResMap) error
}

View File

@@ -1,49 +0,0 @@
/*
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.
*/
package transformers
import (
"fmt"
"reflect"
"github.com/kubernetes-sigs/kustomize/pkg/resource"
"github.com/kubernetes-sigs/kustomize/pkg/types"
)
func compareMap(m1, m2 resource.ResourceCollection) error {
if len(m1) != len(m2) {
keySet1 := []types.GroupVersionKindName{}
keySet2 := []types.GroupVersionKindName{}
for GVKn := range m1 {
keySet1 = append(keySet1, GVKn)
}
for GVKn := range m1 {
keySet2 = append(keySet2, GVKn)
}
return fmt.Errorf("maps has different number of entries: %#v doesn't equals %#v", keySet1, keySet2)
}
for GVKn, obj1 := range m1 {
obj2, found := m2[GVKn]
if !found {
return fmt.Errorf("%#v doesn't exist in %#v", GVKn, m2)
}
if !reflect.DeepEqual(obj1.Data, obj2.Data) {
return fmt.Errorf("%#v doesn't match %#v", obj1.Data, obj2.Data)
}
}
return nil
}