mirror of
https://github.com/kubernetes-sigs/kustomize.git
synced 2026-05-17 18:25:26 +00:00
1069 lines
30 KiB
Go
1069 lines
30 KiB
Go
// Copyright 2019 The Kubernetes Authors.
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
|
|
package accumulator
|
|
|
|
import (
|
|
"strings"
|
|
"testing"
|
|
|
|
"sigs.k8s.io/kustomize/api/internal/plugins/builtinconfig"
|
|
"sigs.k8s.io/kustomize/api/provider"
|
|
"sigs.k8s.io/kustomize/api/resid"
|
|
"sigs.k8s.io/kustomize/api/resmap"
|
|
resmaptest_test "sigs.k8s.io/kustomize/api/testutils/resmaptest"
|
|
)
|
|
|
|
const notEqualErrFmt = "expected (self) doesn't match actual (other): %v"
|
|
|
|
func TestNameReferenceHappyRun(t *testing.T) {
|
|
m := resmaptest_test.NewRmBuilderDefault(t).AddWithName(
|
|
"cm1",
|
|
map[string]interface{}{
|
|
"apiVersion": "v1",
|
|
"kind": "ConfigMap",
|
|
"metadata": map[string]interface{}{
|
|
"name": "someprefix-cm1-somehash",
|
|
},
|
|
}).AddWithName(
|
|
"cm2",
|
|
map[string]interface{}{
|
|
"apiVersion": "v1",
|
|
"kind": "ConfigMap",
|
|
"metadata": map[string]interface{}{
|
|
"name": "someprefix-cm2-somehash",
|
|
},
|
|
}).AddWithName(
|
|
"secret1",
|
|
map[string]interface{}{
|
|
"apiVersion": "v1",
|
|
"kind": "Secret",
|
|
"metadata": map[string]interface{}{
|
|
"name": "someprefix-secret1-somehash",
|
|
},
|
|
}).AddWithName(
|
|
"claim1",
|
|
map[string]interface{}{
|
|
"apiVersion": "v1",
|
|
"kind": "PersistentVolumeClaim",
|
|
"metadata": map[string]interface{}{
|
|
"name": "someprefix-claim1",
|
|
},
|
|
}).Add(
|
|
map[string]interface{}{
|
|
"group": "networking.k8s.io",
|
|
"apiVersion": "v1beta1",
|
|
"kind": "Ingress",
|
|
"metadata": map[string]interface{}{
|
|
"name": "ingress1",
|
|
"annotations": map[string]interface{}{
|
|
"ingress.kubernetes.io/auth-secret": "secret1",
|
|
"nginx.ingress.kubernetes.io/auth-secret": "secret1",
|
|
"nginx.ingress.kubernetes.io/auth-tls-secret": "secret1",
|
|
},
|
|
},
|
|
"spec": map[string]interface{}{
|
|
"backend": map[string]interface{}{
|
|
"serviceName": "testsvc",
|
|
"servicePort": "80",
|
|
},
|
|
},
|
|
},
|
|
).Add(
|
|
map[string]interface{}{
|
|
"group": "apps",
|
|
"apiVersion": "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",
|
|
"env": []interface{}{
|
|
map[string]interface{}{
|
|
"name": "CM_FOO",
|
|
"valueFrom": map[string]interface{}{
|
|
"configMapKeyRef": map[string]interface{}{
|
|
"name": "cm1",
|
|
"key": "somekey",
|
|
},
|
|
},
|
|
},
|
|
map[string]interface{}{
|
|
"name": "SECRET_FOO",
|
|
"valueFrom": map[string]interface{}{
|
|
"secretKeyRef": map[string]interface{}{
|
|
"name": "secret1",
|
|
"key": "somekey",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
"envFrom": []interface{}{
|
|
map[string]interface{}{
|
|
"configMapRef": map[string]interface{}{
|
|
"name": "cm1",
|
|
"key": "somekey",
|
|
},
|
|
},
|
|
map[string]interface{}{
|
|
"secretRef": map[string]interface{}{
|
|
"name": "secret1",
|
|
"key": "somekey",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
"imagePullSecrets": []interface{}{
|
|
map[string]interface{}{
|
|
"name": "secret1",
|
|
},
|
|
},
|
|
"volumes": map[string]interface{}{
|
|
"configMap": map[string]interface{}{
|
|
"name": "cm1",
|
|
},
|
|
"projected": map[string]interface{}{
|
|
"sources": map[string]interface{}{
|
|
"configMap": map[string]interface{}{
|
|
"name": "cm2",
|
|
},
|
|
"secret": map[string]interface{}{
|
|
"name": "secret1",
|
|
},
|
|
},
|
|
},
|
|
"secret": map[string]interface{}{
|
|
"secretName": "secret1",
|
|
},
|
|
"persistentVolumeClaim": map[string]interface{}{
|
|
"claimName": "claim1",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
}).Add(
|
|
map[string]interface{}{
|
|
"group": "apps",
|
|
"apiVersion": "v1",
|
|
"kind": "StatefulSet",
|
|
"metadata": map[string]interface{}{
|
|
"name": "statefulset1",
|
|
},
|
|
"spec": map[string]interface{}{
|
|
"template": map[string]interface{}{
|
|
"spec": map[string]interface{}{
|
|
"containers": []interface{}{
|
|
map[string]interface{}{
|
|
"name": "nginx",
|
|
"image": "nginx:1.7.9",
|
|
},
|
|
},
|
|
"volumes": map[string]interface{}{
|
|
"projected": map[string]interface{}{
|
|
"sources": map[string]interface{}{
|
|
"configMap": map[string]interface{}{
|
|
"name": "cm2",
|
|
},
|
|
"secret": map[string]interface{}{
|
|
"name": "secret1",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
}).AddWithName("sa",
|
|
map[string]interface{}{
|
|
"apiVersion": "v1",
|
|
"kind": "ServiceAccount",
|
|
"metadata": map[string]interface{}{
|
|
"name": "someprefix-sa",
|
|
"namespace": "test",
|
|
},
|
|
}).Add(
|
|
map[string]interface{}{
|
|
"apiVersion": "rbac.authorization.k8s.io/v1",
|
|
"kind": "ClusterRoleBinding",
|
|
"metadata": map[string]interface{}{
|
|
"name": "crb",
|
|
},
|
|
"subjects": []interface{}{
|
|
map[string]interface{}{
|
|
"kind": "ServiceAccount",
|
|
"name": "sa",
|
|
"namespace": "test",
|
|
},
|
|
},
|
|
}).Add(
|
|
map[string]interface{}{
|
|
"apiVersion": "rbac.authorization.k8s.io/v1",
|
|
"kind": "ClusterRole",
|
|
"metadata": map[string]interface{}{
|
|
"name": "cr",
|
|
},
|
|
"rules": []interface{}{
|
|
map[string]interface{}{
|
|
"resources": []interface{}{
|
|
"secrets",
|
|
},
|
|
"resourceNames": []interface{}{
|
|
"secret1",
|
|
"secret1",
|
|
"secret2",
|
|
"cm1",
|
|
},
|
|
},
|
|
},
|
|
}).Add(
|
|
map[string]interface{}{
|
|
"apiVersion": "batch/v1beta1",
|
|
"kind": "CronJob",
|
|
"metadata": map[string]interface{}{
|
|
"name": "cronjob1",
|
|
},
|
|
"spec": map[string]interface{}{
|
|
"schedule": "0 14 * * *",
|
|
"jobTemplate": map[string]interface{}{
|
|
"spec": map[string]interface{}{
|
|
"template": map[string]interface{}{
|
|
"spec": map[string]interface{}{
|
|
"containers": []interface{}{
|
|
map[string]interface{}{
|
|
"name": "main",
|
|
"image": "myimage",
|
|
},
|
|
},
|
|
"volumes": map[string]interface{}{
|
|
"projected": map[string]interface{}{
|
|
"sources": map[string]interface{}{
|
|
"configMap": map[string]interface{}{
|
|
"name": "cm2",
|
|
},
|
|
"secret": map[string]interface{}{
|
|
"name": "secret1",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
}).ResMap()
|
|
|
|
expected := resmaptest_test.NewSeededRmBuilderDefault(
|
|
t, m.ShallowCopy()).ReplaceResource(
|
|
map[string]interface{}{
|
|
"group": "apps",
|
|
"apiVersion": "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",
|
|
"env": []interface{}{
|
|
map[string]interface{}{
|
|
"name": "CM_FOO",
|
|
"valueFrom": map[string]interface{}{
|
|
"configMapKeyRef": map[string]interface{}{
|
|
"name": "someprefix-cm1-somehash",
|
|
"key": "somekey",
|
|
},
|
|
},
|
|
},
|
|
map[string]interface{}{
|
|
"name": "SECRET_FOO",
|
|
"valueFrom": map[string]interface{}{
|
|
"secretKeyRef": map[string]interface{}{
|
|
"name": "someprefix-secret1-somehash",
|
|
"key": "somekey",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
"envFrom": []interface{}{
|
|
map[string]interface{}{
|
|
"configMapRef": map[string]interface{}{
|
|
"name": "someprefix-cm1-somehash",
|
|
"key": "somekey",
|
|
},
|
|
},
|
|
map[string]interface{}{
|
|
"secretRef": map[string]interface{}{
|
|
"name": "someprefix-secret1-somehash",
|
|
"key": "somekey",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
"imagePullSecrets": []interface{}{
|
|
map[string]interface{}{
|
|
"name": "someprefix-secret1-somehash",
|
|
},
|
|
},
|
|
"volumes": map[string]interface{}{
|
|
"configMap": map[string]interface{}{
|
|
"name": "someprefix-cm1-somehash",
|
|
},
|
|
"projected": map[string]interface{}{
|
|
"sources": map[string]interface{}{
|
|
"configMap": map[string]interface{}{
|
|
"name": "someprefix-cm2-somehash",
|
|
},
|
|
"secret": map[string]interface{}{
|
|
"name": "someprefix-secret1-somehash",
|
|
},
|
|
},
|
|
},
|
|
"secret": map[string]interface{}{
|
|
"secretName": "someprefix-secret1-somehash",
|
|
},
|
|
"persistentVolumeClaim": map[string]interface{}{
|
|
"claimName": "someprefix-claim1",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
}).ReplaceResource(
|
|
map[string]interface{}{
|
|
"group": "apps",
|
|
"apiVersion": "v1",
|
|
"kind": "StatefulSet",
|
|
"metadata": map[string]interface{}{
|
|
"name": "statefulset1",
|
|
},
|
|
"spec": map[string]interface{}{
|
|
"template": map[string]interface{}{
|
|
"spec": map[string]interface{}{
|
|
"containers": []interface{}{
|
|
map[string]interface{}{
|
|
"name": "nginx",
|
|
"image": "nginx:1.7.9",
|
|
},
|
|
},
|
|
"volumes": map[string]interface{}{
|
|
"projected": map[string]interface{}{
|
|
"sources": map[string]interface{}{
|
|
"configMap": map[string]interface{}{
|
|
"name": "someprefix-cm2-somehash",
|
|
},
|
|
"secret": map[string]interface{}{
|
|
"name": "someprefix-secret1-somehash",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
}).ReplaceResource(
|
|
map[string]interface{}{
|
|
"group": "networking.k8s.io",
|
|
"apiVersion": "v1beta1",
|
|
"kind": "Ingress",
|
|
"metadata": map[string]interface{}{
|
|
"name": "ingress1",
|
|
"annotations": map[string]interface{}{
|
|
"ingress.kubernetes.io/auth-secret": "someprefix-secret1-somehash",
|
|
"nginx.ingress.kubernetes.io/auth-secret": "someprefix-secret1-somehash",
|
|
"nginx.ingress.kubernetes.io/auth-tls-secret": "someprefix-secret1-somehash",
|
|
},
|
|
},
|
|
"spec": map[string]interface{}{
|
|
"backend": map[string]interface{}{
|
|
"serviceName": "testsvc",
|
|
"servicePort": "80",
|
|
},
|
|
},
|
|
}).ReplaceResource(
|
|
map[string]interface{}{
|
|
"apiVersion": "rbac.authorization.k8s.io/v1",
|
|
"kind": "ClusterRoleBinding",
|
|
"metadata": map[string]interface{}{
|
|
"name": "crb",
|
|
},
|
|
"subjects": []interface{}{
|
|
map[string]interface{}{
|
|
"kind": "ServiceAccount",
|
|
"name": "someprefix-sa",
|
|
"namespace": "test",
|
|
},
|
|
},
|
|
}).ReplaceResource(
|
|
map[string]interface{}{
|
|
"apiVersion": "rbac.authorization.k8s.io/v1",
|
|
"kind": "ClusterRole",
|
|
"metadata": map[string]interface{}{
|
|
"name": "cr",
|
|
},
|
|
"rules": []interface{}{
|
|
map[string]interface{}{
|
|
"resources": []interface{}{
|
|
"secrets",
|
|
},
|
|
"resourceNames": []interface{}{
|
|
"someprefix-secret1-somehash",
|
|
"someprefix-secret1-somehash",
|
|
"secret2",
|
|
"someprefix-cm1-somehash",
|
|
},
|
|
},
|
|
},
|
|
}).ReplaceResource(
|
|
map[string]interface{}{
|
|
"apiVersion": "batch/v1beta1",
|
|
"kind": "CronJob",
|
|
"metadata": map[string]interface{}{
|
|
"name": "cronjob1",
|
|
},
|
|
"spec": map[string]interface{}{
|
|
"schedule": "0 14 * * *",
|
|
"jobTemplate": map[string]interface{}{
|
|
"spec": map[string]interface{}{
|
|
"template": map[string]interface{}{
|
|
"spec": map[string]interface{}{
|
|
"containers": []interface{}{
|
|
map[string]interface{}{
|
|
"name": "main",
|
|
"image": "myimage",
|
|
},
|
|
},
|
|
"volumes": map[string]interface{}{
|
|
"projected": map[string]interface{}{
|
|
"sources": map[string]interface{}{
|
|
"configMap": map[string]interface{}{
|
|
"name": "someprefix-cm2-somehash",
|
|
},
|
|
"secret": map[string]interface{}{
|
|
"name": "someprefix-secret1-somehash",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
}).ResMap()
|
|
|
|
nrt := newNameReferenceTransformer(builtinconfig.MakeDefaultConfig().NameReference)
|
|
err := nrt.Transform(m)
|
|
if err != nil {
|
|
t.Fatalf("unexpected error: %v", err)
|
|
}
|
|
|
|
if err = expected.ErrorIfNotEqualLists(m); err != nil {
|
|
t.Fatalf(notEqualErrFmt, err)
|
|
}
|
|
}
|
|
|
|
func TestNameReferenceUnhappyRun(t *testing.T) {
|
|
tests := []struct {
|
|
resMap resmap.ResMap
|
|
expectedErr string
|
|
}{
|
|
{
|
|
resMap: resmaptest_test.NewRmBuilderDefault(t).Add(
|
|
map[string]interface{}{
|
|
"apiVersion": "rbac.authorization.k8s.io/v1",
|
|
"kind": "ClusterRole",
|
|
"metadata": map[string]interface{}{
|
|
"name": "cr",
|
|
},
|
|
"rules": []interface{}{
|
|
map[string]interface{}{
|
|
"resources": []interface{}{
|
|
"secrets",
|
|
},
|
|
"resourceNames": []interface{}{
|
|
[]interface{}{},
|
|
},
|
|
},
|
|
},
|
|
}).ResMap(),
|
|
expectedErr: "is expected to be"},
|
|
{
|
|
resMap: resmaptest_test.NewRmBuilderDefault(t).Add(
|
|
map[string]interface{}{
|
|
"apiVersion": "rbac.authorization.k8s.io/v1",
|
|
"kind": "ClusterRole",
|
|
"metadata": map[string]interface{}{
|
|
"name": "cr",
|
|
},
|
|
"rules": []interface{}{
|
|
map[string]interface{}{
|
|
"resources": []interface{}{
|
|
"secrets",
|
|
},
|
|
"resourceNames": map[string]interface{}{
|
|
"foo": "bar",
|
|
},
|
|
},
|
|
},
|
|
}).ResMap(),
|
|
expectedErr: `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]: path config error; no 'name' field in node`},
|
|
}
|
|
|
|
nrt := newNameReferenceTransformer(builtinconfig.MakeDefaultConfig().NameReference)
|
|
for _, test := range tests {
|
|
err := nrt.Transform(test.resMap)
|
|
if err == nil {
|
|
t.Fatalf("expected error to happen")
|
|
}
|
|
|
|
if !strings.Contains(err.Error(), test.expectedErr) {
|
|
t.Fatalf("Incorrect error.\nExpected:\n %s\nGot:\n%v",
|
|
test.expectedErr, err)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestNameReferencePersistentVolumeHappyRun(t *testing.T) {
|
|
rf := provider.NewDefaultDepProvider().GetResourceFactory()
|
|
|
|
v1 := rf.FromMapWithName(
|
|
"volume1",
|
|
map[string]interface{}{
|
|
"apiVersion": "v1",
|
|
"kind": "PersistentVolume",
|
|
"metadata": map[string]interface{}{
|
|
"name": "someprefix-volume1",
|
|
},
|
|
})
|
|
c1 := rf.FromMapWithName(
|
|
"claim1",
|
|
map[string]interface{}{
|
|
"apiVersion": "v1",
|
|
"kind": "PersistentVolumeClaim",
|
|
"metadata": map[string]interface{}{
|
|
"name": "someprefix-claim1",
|
|
"namespace": "some-namespace",
|
|
},
|
|
"spec": map[string]interface{}{
|
|
"volumeName": "volume1",
|
|
},
|
|
})
|
|
|
|
v2 := v1.DeepCopy()
|
|
c2 := rf.FromMapWithName(
|
|
"claim1",
|
|
map[string]interface{}{
|
|
"apiVersion": "v1",
|
|
"kind": "PersistentVolumeClaim",
|
|
"metadata": map[string]interface{}{
|
|
"name": "someprefix-claim1",
|
|
"namespace": "some-namespace",
|
|
},
|
|
"spec": map[string]interface{}{
|
|
"volumeName": "someprefix-volume1",
|
|
},
|
|
})
|
|
|
|
m1 := resmaptest_test.NewRmBuilder(t, rf).AddR(v1).AddR(c1).ResMap()
|
|
|
|
nrt := newNameReferenceTransformer(builtinconfig.MakeDefaultConfig().NameReference)
|
|
if err := nrt.Transform(m1); err != nil {
|
|
t.Fatalf("unexpected error: %v", err)
|
|
}
|
|
|
|
m2 := resmaptest_test.NewRmBuilder(t, rf).AddR(v2).AddR(c2).ResMap()
|
|
v2.AppendRefBy(c2.CurId())
|
|
|
|
if err := m1.ErrorIfNotEqualLists(m2); err != nil {
|
|
t.Fatalf(notEqualErrFmt, err)
|
|
}
|
|
}
|
|
|
|
// utility map to create a deployment object
|
|
// with (metadatanamespace, metadataname) as key
|
|
// and pointing to "refname" secret and configmap
|
|
func deploymentMap(metadatanamespace string, metadataname string,
|
|
configmapref string, secretref string) map[string]interface{} {
|
|
deployment := map[string]interface{}{
|
|
"group": "apps",
|
|
"apiVersion": "v1",
|
|
"kind": "Deployment",
|
|
"metadata": map[string]interface{}{
|
|
"name": metadataname,
|
|
},
|
|
"spec": map[string]interface{}{
|
|
"template": map[string]interface{}{
|
|
"spec": map[string]interface{}{
|
|
"containers": []interface{}{
|
|
map[string]interface{}{
|
|
"name": "nginx",
|
|
"image": "nginx:1.7.9",
|
|
"env": []interface{}{
|
|
map[string]interface{}{
|
|
"name": "CM_FOO",
|
|
"valueFrom": map[string]interface{}{
|
|
"configMapKeyRef": map[string]interface{}{
|
|
"name": configmapref,
|
|
"key": "somekey",
|
|
},
|
|
},
|
|
},
|
|
map[string]interface{}{
|
|
"name": "SECRET_FOO",
|
|
"valueFrom": map[string]interface{}{
|
|
"secretKeyRef": map[string]interface{}{
|
|
"name": secretref,
|
|
"key": "somekey",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
}
|
|
|
|
if metadatanamespace != "" {
|
|
metadata := deployment["metadata"].(map[string]interface{})
|
|
metadata["namespace"] = metadatanamespace
|
|
}
|
|
return deployment
|
|
}
|
|
|
|
const (
|
|
defaultNs = "default"
|
|
ns1 = "ns1"
|
|
ns2 = "ns2"
|
|
ns3 = "ns3"
|
|
ns4 = "ns4"
|
|
|
|
orgname = "uniquename"
|
|
prefixedname = "prefix-uniquename"
|
|
suffixedname = "uniquename-suffix"
|
|
modifiedname = "modifiedname"
|
|
)
|
|
|
|
// TestNameReferenceNamespace creates serviceAccount and clusterRoleBinding
|
|
// object with the same original names (uniquename) in different namespaces
|
|
// and with different current Id.
|
|
func TestNameReferenceNamespace(t *testing.T) {
|
|
m := resmaptest_test.NewRmBuilderDefault(t).
|
|
// Add ConfigMap with the same org name in noNs, "ns1" and "ns2" namespaces
|
|
AddWithName(orgname, map[string]interface{}{
|
|
"apiVersion": "v1",
|
|
"kind": "ConfigMap",
|
|
"metadata": map[string]interface{}{
|
|
"name": modifiedname,
|
|
}}).
|
|
AddWithNsAndName(ns1, orgname, map[string]interface{}{
|
|
"apiVersion": "v1",
|
|
"kind": "ConfigMap",
|
|
"metadata": map[string]interface{}{
|
|
"name": prefixedname,
|
|
"namespace": ns1,
|
|
}}).
|
|
AddWithNsAndName(ns2, orgname, map[string]interface{}{
|
|
"apiVersion": "v1",
|
|
"kind": "ConfigMap",
|
|
"metadata": map[string]interface{}{
|
|
"name": suffixedname,
|
|
"namespace": ns2,
|
|
}}).
|
|
// Add Secret with the same org name in noNs, "ns1" and "ns2" namespaces
|
|
AddWithNsAndName(defaultNs, orgname, map[string]interface{}{
|
|
"apiVersion": "v1",
|
|
"kind": "Secret",
|
|
"metadata": map[string]interface{}{
|
|
"name": modifiedname,
|
|
"namespace": defaultNs,
|
|
}}).
|
|
AddWithNsAndName(ns1, orgname, map[string]interface{}{
|
|
"apiVersion": "v1",
|
|
"kind": "Secret",
|
|
"metadata": map[string]interface{}{
|
|
"name": prefixedname,
|
|
"namespace": ns1,
|
|
}}).
|
|
AddWithNsAndName(ns2, orgname, map[string]interface{}{
|
|
"apiVersion": "v1",
|
|
"kind": "Secret",
|
|
"metadata": map[string]interface{}{
|
|
"name": suffixedname,
|
|
"namespace": ns2,
|
|
}}).
|
|
// Add Deployment with the same org name in noNs, "ns1" and "ns2" namespaces
|
|
AddWithNsAndName(defaultNs, orgname, deploymentMap(defaultNs, modifiedname, modifiedname, modifiedname)).
|
|
AddWithNsAndName(ns1, orgname, deploymentMap(ns1, prefixedname, orgname, orgname)).
|
|
AddWithNsAndName(ns2, orgname, deploymentMap(ns2, suffixedname, orgname, orgname)).ResMap()
|
|
|
|
expected := resmaptest_test.NewSeededRmBuilderDefault(t, m.ShallowCopy()).
|
|
ReplaceResource(deploymentMap(defaultNs, modifiedname, modifiedname, modifiedname)).
|
|
ReplaceResource(deploymentMap(ns1, prefixedname, prefixedname, prefixedname)).
|
|
ReplaceResource(deploymentMap(ns2, suffixedname, suffixedname, suffixedname)).ResMap()
|
|
|
|
nrt := newNameReferenceTransformer(builtinconfig.MakeDefaultConfig().NameReference)
|
|
err := nrt.Transform(m)
|
|
if err != nil {
|
|
t.Fatalf("unexpected error: %v", err)
|
|
}
|
|
|
|
m.RemoveBuildAnnotations()
|
|
if err = expected.ErrorIfNotEqualLists(m); err != nil {
|
|
t.Fatalf(notEqualErrFmt, err)
|
|
}
|
|
}
|
|
|
|
// TestNameReferenceNamespace creates serviceAccount and clusterRoleBinding
|
|
// object with the same original names (uniquename) in different namespaces
|
|
// and with different current Id.
|
|
func TestNameReferenceClusterWide(t *testing.T) {
|
|
m := resmaptest_test.NewRmBuilderDefault(t).
|
|
// Add ServiceAccount with the same org name in noNs, "ns1" and "ns2" namespaces
|
|
AddWithName(orgname, map[string]interface{}{
|
|
"apiVersion": "v1",
|
|
"kind": "ServiceAccount",
|
|
"metadata": map[string]interface{}{
|
|
"name": modifiedname,
|
|
}}).
|
|
AddWithNsAndName(ns1, orgname, map[string]interface{}{
|
|
"apiVersion": "v1",
|
|
"kind": "ServiceAccount",
|
|
"metadata": map[string]interface{}{
|
|
"name": prefixedname,
|
|
"namespace": ns1,
|
|
}}).
|
|
AddWithNsAndName(ns2, orgname, map[string]interface{}{
|
|
"apiVersion": "v1",
|
|
"kind": "ServiceAccount",
|
|
"metadata": map[string]interface{}{
|
|
"name": suffixedname,
|
|
"namespace": ns2,
|
|
}}).
|
|
// Add a PersistentVolume to have a clusterwide resource
|
|
AddWithName(orgname, map[string]interface{}{
|
|
"apiVersion": "v1",
|
|
"kind": "PersistentVolume",
|
|
"metadata": map[string]interface{}{
|
|
"name": modifiedname,
|
|
}}).
|
|
AddWithName(orgname, map[string]interface{}{
|
|
"apiVersion": "rbac.authorization.k8s.io/v1",
|
|
"kind": "ClusterRole",
|
|
"metadata": map[string]interface{}{
|
|
"name": modifiedname,
|
|
},
|
|
"rules": []interface{}{
|
|
map[string]interface{}{
|
|
"resources": []interface{}{
|
|
"persistentvolumes",
|
|
},
|
|
"resourceNames": []interface{}{
|
|
orgname,
|
|
},
|
|
},
|
|
}}).
|
|
AddWithName(orgname, map[string]interface{}{
|
|
"apiVersion": "rbac.authorization.k8s.io/v1",
|
|
"kind": "ClusterRoleBinding",
|
|
"metadata": map[string]interface{}{
|
|
"name": modifiedname,
|
|
},
|
|
"roleRef": map[string]interface{}{
|
|
"apiGroup": "rbac.authorization.k8s.io",
|
|
"kind": "ClusterRole",
|
|
"name": orgname,
|
|
},
|
|
"subjects": []interface{}{
|
|
map[string]interface{}{
|
|
"kind": "ServiceAccount",
|
|
"name": orgname,
|
|
"namespace": defaultNs,
|
|
},
|
|
map[string]interface{}{
|
|
"kind": "ServiceAccount",
|
|
"name": orgname,
|
|
"namespace": ns1,
|
|
},
|
|
map[string]interface{}{
|
|
"kind": "ServiceAccount",
|
|
"name": orgname,
|
|
"namespace": ns2,
|
|
},
|
|
map[string]interface{}{
|
|
"kind": "ServiceAccount",
|
|
"name": orgname,
|
|
"namespace": "random",
|
|
},
|
|
}}).ResMap()
|
|
|
|
expected := resmaptest_test.NewSeededRmBuilderDefault(t, m.ShallowCopy()).
|
|
ReplaceResource(
|
|
map[string]interface{}{
|
|
"apiVersion": "rbac.authorization.k8s.io/v1",
|
|
"kind": "ClusterRole",
|
|
"metadata": map[string]interface{}{
|
|
"name": modifiedname,
|
|
},
|
|
// Behavior of the transformer is still imperfect
|
|
// It should use the (resources,apigroup,resourceNames) as
|
|
// combination to select the candidates.
|
|
"rules": []interface{}{
|
|
map[string]interface{}{
|
|
"resources": []interface{}{
|
|
"persistentvolumes",
|
|
},
|
|
"resourceNames": []interface{}{
|
|
modifiedname,
|
|
},
|
|
},
|
|
}}).
|
|
ReplaceResource(
|
|
map[string]interface{}{
|
|
"apiVersion": "rbac.authorization.k8s.io/v1",
|
|
"kind": "ClusterRoleBinding",
|
|
"metadata": map[string]interface{}{
|
|
"name": modifiedname,
|
|
},
|
|
"roleRef": map[string]interface{}{
|
|
"apiGroup": "rbac.authorization.k8s.io",
|
|
"kind": "ClusterRole",
|
|
"name": modifiedname,
|
|
},
|
|
// The following tests required a change in
|
|
// getNameFunc implementation in order to leverage
|
|
// the namespace field.
|
|
"subjects": []interface{}{
|
|
map[string]interface{}{
|
|
"kind": "ServiceAccount",
|
|
"name": modifiedname,
|
|
"namespace": defaultNs,
|
|
},
|
|
map[string]interface{}{
|
|
"kind": "ServiceAccount",
|
|
"name": prefixedname,
|
|
"namespace": ns1,
|
|
},
|
|
map[string]interface{}{
|
|
"kind": "ServiceAccount",
|
|
"name": suffixedname,
|
|
"namespace": ns2,
|
|
},
|
|
map[string]interface{}{
|
|
"kind": "ServiceAccount",
|
|
"name": orgname,
|
|
"namespace": "random",
|
|
},
|
|
},
|
|
}).ResMap()
|
|
|
|
clusterRoleId := resid.NewResId(
|
|
resid.Gvk{Group: "rbac.authorization.k8s.io", Version: "v1", Kind: "ClusterRole"}, modifiedname)
|
|
clusterRoleBindingId := resid.NewResId(
|
|
resid.Gvk{Group: "rbac.authorization.k8s.io", Version: "v1", Kind: "ClusterRoleBinding"}, modifiedname)
|
|
clusterRole, _ := expected.GetByCurrentId(clusterRoleId)
|
|
clusterRole.AppendRefBy(clusterRoleBindingId)
|
|
|
|
nrt := newNameReferenceTransformer(builtinconfig.MakeDefaultConfig().NameReference)
|
|
err := nrt.Transform(m)
|
|
if err != nil {
|
|
t.Fatalf("unexpected error: %v", err)
|
|
}
|
|
|
|
m.RemoveBuildAnnotations()
|
|
if err = expected.ErrorIfNotEqualLists(m); err != nil {
|
|
t.Fatalf(notEqualErrFmt, err)
|
|
}
|
|
}
|
|
|
|
// TestNameReferenceNamespaceTransformation creates serviceAccount and clusterRoleBinding
|
|
// object with the same original names (uniquename) in different namespaces
|
|
// and with different current Id.
|
|
func TestNameReferenceNamespaceTransformation(t *testing.T) {
|
|
m := resmaptest_test.NewRmBuilderDefault(t).
|
|
AddWithNsAndName(ns4, orgname, map[string]interface{}{
|
|
"apiVersion": "v1",
|
|
"kind": "Secret",
|
|
"metadata": map[string]interface{}{
|
|
"name": orgname,
|
|
"namespace": ns4,
|
|
}}).
|
|
// Add ServiceAccount with the same org name in "ns1" namespaces
|
|
AddWithNsAndName(ns1, orgname, map[string]interface{}{
|
|
"apiVersion": "v1",
|
|
"kind": "ServiceAccount",
|
|
"metadata": map[string]interface{}{
|
|
"name": prefixedname,
|
|
"namespace": ns1,
|
|
}}).
|
|
// Simulate NamespaceTransformer effect (ns3 transformed in ns2)
|
|
AddWithNsAndName(ns3, orgname, map[string]interface{}{
|
|
"apiVersion": "v1",
|
|
"kind": "ServiceAccount",
|
|
"metadata": map[string]interface{}{
|
|
"name": suffixedname,
|
|
"namespace": ns2,
|
|
}}).
|
|
AddWithName(orgname, map[string]interface{}{
|
|
"apiVersion": "rbac.authorization.k8s.io/v1",
|
|
"kind": "ClusterRole",
|
|
"metadata": map[string]interface{}{
|
|
"name": modifiedname,
|
|
}}).
|
|
AddWithName(orgname, map[string]interface{}{
|
|
"apiVersion": "rbac.authorization.k8s.io/v1",
|
|
"kind": "ClusterRoleBinding",
|
|
"metadata": map[string]interface{}{
|
|
"name": modifiedname,
|
|
},
|
|
"roleRef": map[string]interface{}{
|
|
"apiGroup": "rbac.authorization.k8s.io",
|
|
"kind": "ClusterRole",
|
|
"name": orgname,
|
|
},
|
|
"subjects": []interface{}{
|
|
map[string]interface{}{
|
|
"kind": "ServiceAccount",
|
|
"name": orgname,
|
|
"namespace": ns1,
|
|
},
|
|
map[string]interface{}{
|
|
"kind": "ServiceAccount",
|
|
"name": orgname,
|
|
"namespace": ns3,
|
|
},
|
|
map[string]interface{}{
|
|
"kind": "ServiceAccount",
|
|
"name": orgname,
|
|
"namespace": "random",
|
|
},
|
|
map[string]interface{}{
|
|
"kind": "ServiceAccount",
|
|
"name": orgname,
|
|
"namespace": ns4,
|
|
},
|
|
}}).ResMap()
|
|
|
|
expected := resmaptest_test.NewSeededRmBuilderDefault(t, m.ShallowCopy()).
|
|
ReplaceResource(
|
|
map[string]interface{}{
|
|
"apiVersion": "rbac.authorization.k8s.io/v1",
|
|
"kind": "ClusterRoleBinding",
|
|
"metadata": map[string]interface{}{
|
|
"name": modifiedname,
|
|
},
|
|
"roleRef": map[string]interface{}{
|
|
"apiGroup": "rbac.authorization.k8s.io",
|
|
"kind": "ClusterRole",
|
|
"name": modifiedname,
|
|
},
|
|
// The following tests required a change in
|
|
// getNameFunc implementation in order to leverage
|
|
// the namespace field.
|
|
"subjects": []interface{}{
|
|
map[string]interface{}{
|
|
"kind": "ServiceAccount",
|
|
"name": prefixedname,
|
|
"namespace": ns1,
|
|
},
|
|
map[string]interface{}{
|
|
"kind": "ServiceAccount",
|
|
"name": suffixedname,
|
|
"namespace": ns2,
|
|
},
|
|
map[string]interface{}{
|
|
"kind": "ServiceAccount",
|
|
"name": orgname,
|
|
"namespace": "random",
|
|
},
|
|
map[string]interface{}{
|
|
"kind": "ServiceAccount",
|
|
"name": orgname,
|
|
"namespace": ns4,
|
|
},
|
|
},
|
|
}).ResMap()
|
|
|
|
clusterRoleId := resid.NewResId(
|
|
resid.Gvk{Group: "rbac.authorization.k8s.io", Version: "v1", Kind: "ClusterRole"}, modifiedname)
|
|
clusterRoleBindingId := resid.NewResId(
|
|
resid.Gvk{Group: "rbac.authorization.k8s.io", Version: "v1", Kind: "ClusterRoleBinding"}, modifiedname)
|
|
clusterRole, _ := expected.GetByCurrentId(clusterRoleId)
|
|
clusterRole.AppendRefBy(clusterRoleBindingId)
|
|
|
|
nrt := newNameReferenceTransformer(builtinconfig.MakeDefaultConfig().NameReference)
|
|
err := nrt.Transform(m)
|
|
if err != nil {
|
|
t.Fatalf("unexpected error: %v", err)
|
|
}
|
|
|
|
m.RemoveBuildAnnotations()
|
|
if err = expected.ErrorIfNotEqualLists(m); err != nil {
|
|
t.Fatalf(notEqualErrFmt, err)
|
|
}
|
|
}
|
|
|
|
// TestNameReferenceNamespace creates configmap, secret, deployment
|
|
// It validates the change done is IsSameFuzzyNamespace which
|
|
// uses the IsNsEquals method instead of the simple == operator.
|
|
func TestNameReferenceCandidateSelection(t *testing.T) {
|
|
m := resmaptest_test.NewRmBuilderDefault(t).
|
|
AddWithName("cm1", map[string]interface{}{
|
|
"apiVersion": "v1",
|
|
"kind": "ConfigMap",
|
|
"metadata": map[string]interface{}{
|
|
"name": "p1-cm1-hash",
|
|
}}).
|
|
AddWithNsAndName("default", "secret1", map[string]interface{}{
|
|
"apiVersion": "v1",
|
|
"kind": "Secret",
|
|
"metadata": map[string]interface{}{
|
|
"name": "p1-secret1-hash",
|
|
"namespace": "default",
|
|
}}).
|
|
AddWithName("deploy1", deploymentMap("", "p1-deploy1", "cm1", "secret1")).
|
|
ResMap()
|
|
|
|
expected := resmaptest_test.NewSeededRmBuilderDefault(t, m.ShallowCopy()).
|
|
ReplaceResource(deploymentMap("", "p1-deploy1", "p1-cm1-hash", "p1-secret1-hash")).
|
|
ResMap()
|
|
|
|
nrt := newNameReferenceTransformer(builtinconfig.MakeDefaultConfig().NameReference)
|
|
err := nrt.Transform(m)
|
|
if err != nil {
|
|
t.Fatalf("unexpected error: %v", err)
|
|
}
|
|
|
|
m.RemoveBuildAnnotations()
|
|
if err = expected.ErrorIfNotEqualLists(m); err != nil {
|
|
t.Fatalf(notEqualErrFmt, err)
|
|
}
|
|
}
|