1
2
3
4 package accumulator
5
6 import (
7 "strings"
8 "testing"
9
10 "github.com/stretchr/testify/require"
11 "sigs.k8s.io/kustomize/api/internal/plugins/builtinconfig"
12 "sigs.k8s.io/kustomize/api/provider"
13 "sigs.k8s.io/kustomize/api/resmap"
14 resmaptest_test "sigs.k8s.io/kustomize/api/testutils/resmaptest"
15 "sigs.k8s.io/kustomize/kyaml/resid"
16 )
17
18 const notEqualErrFmt = "expected (self) doesn't match actual (other): %v"
19
20 func TestNameReferenceHappyRun(t *testing.T) {
21 m := resmaptest_test.NewRmBuilderDefault(t).AddWithName(
22 "cm1",
23 map[string]interface{}{
24 "apiVersion": "v1",
25 "kind": "ConfigMap",
26 "metadata": map[string]interface{}{
27 "name": "someprefix-cm1-somehash",
28 },
29 }).AddWithName(
30 "cm2",
31 map[string]interface{}{
32 "apiVersion": "v1",
33 "kind": "ConfigMap",
34 "metadata": map[string]interface{}{
35 "name": "someprefix-cm2-somehash",
36 },
37 }).AddWithName(
38 "secret1",
39 map[string]interface{}{
40 "apiVersion": "v1",
41 "kind": "Secret",
42 "metadata": map[string]interface{}{
43 "name": "someprefix-secret1-somehash",
44 },
45 }).AddWithName(
46 "claim1",
47 map[string]interface{}{
48 "apiVersion": "v1",
49 "kind": "PersistentVolumeClaim",
50 "metadata": map[string]interface{}{
51 "name": "someprefix-claim1",
52 },
53 }).Add(
54 map[string]interface{}{
55 "group": "networking.k8s.io",
56 "apiVersion": "v1beta1",
57 "kind": "Ingress",
58 "metadata": map[string]interface{}{
59 "name": "ingress1",
60 "annotations": map[string]interface{}{
61 "ingress.kubernetes.io/auth-secret": "secret1",
62 "nginx.ingress.kubernetes.io/auth-secret": "secret1",
63 "nginx.ingress.kubernetes.io/auth-tls-secret": "secret1",
64 },
65 },
66 "spec": map[string]interface{}{
67 "backend": map[string]interface{}{
68 "serviceName": "testsvc",
69 "servicePort": "80",
70 },
71 },
72 },
73 ).Add(
74 map[string]interface{}{
75 "group": "apps",
76 "apiVersion": "v1",
77 "kind": "Deployment",
78 "metadata": map[string]interface{}{
79 "name": "deploy1",
80 },
81 "spec": map[string]interface{}{
82 "template": map[string]interface{}{
83 "spec": map[string]interface{}{
84 "containers": []interface{}{
85 map[string]interface{}{
86 "name": "nginx",
87 "image": "nginx:1.7.9",
88 "env": []interface{}{
89 map[string]interface{}{
90 "name": "CM_FOO",
91 "valueFrom": map[string]interface{}{
92 "configMapKeyRef": map[string]interface{}{
93 "name": "cm1",
94 "key": "somekey",
95 },
96 },
97 },
98 map[string]interface{}{
99 "name": "SECRET_FOO",
100 "valueFrom": map[string]interface{}{
101 "secretKeyRef": map[string]interface{}{
102 "name": "secret1",
103 "key": "somekey",
104 },
105 },
106 },
107 },
108 "envFrom": []interface{}{
109 map[string]interface{}{
110 "configMapRef": map[string]interface{}{
111 "name": "cm1",
112 "key": "somekey",
113 },
114 },
115 map[string]interface{}{
116 "secretRef": map[string]interface{}{
117 "name": "secret1",
118 "key": "somekey",
119 },
120 },
121 },
122 },
123 },
124 "imagePullSecrets": []interface{}{
125 map[string]interface{}{
126 "name": "secret1",
127 },
128 },
129 "volumes": map[string]interface{}{
130 "configMap": map[string]interface{}{
131 "name": "cm1",
132 },
133 "projected": map[string]interface{}{
134 "sources": map[string]interface{}{
135 "configMap": map[string]interface{}{
136 "name": "cm2",
137 },
138 "secret": map[string]interface{}{
139 "name": "secret1",
140 },
141 },
142 },
143 "secret": map[string]interface{}{
144 "secretName": "secret1",
145 },
146 "persistentVolumeClaim": map[string]interface{}{
147 "claimName": "claim1",
148 },
149 },
150 },
151 },
152 },
153 }).Add(
154 map[string]interface{}{
155 "group": "apps",
156 "apiVersion": "v1",
157 "kind": "StatefulSet",
158 "metadata": map[string]interface{}{
159 "name": "statefulset1",
160 },
161 "spec": map[string]interface{}{
162 "template": map[string]interface{}{
163 "spec": map[string]interface{}{
164 "containers": []interface{}{
165 map[string]interface{}{
166 "name": "nginx",
167 "image": "nginx:1.7.9",
168 },
169 },
170 "volumes": map[string]interface{}{
171 "projected": map[string]interface{}{
172 "sources": map[string]interface{}{
173 "configMap": map[string]interface{}{
174 "name": "cm2",
175 },
176 "secret": map[string]interface{}{
177 "name": "secret1",
178 },
179 },
180 },
181 },
182 },
183 },
184 },
185 }).AddWithName("sa",
186 map[string]interface{}{
187 "apiVersion": "v1",
188 "kind": "ServiceAccount",
189 "metadata": map[string]interface{}{
190 "name": "someprefix-sa",
191 "namespace": "test",
192 },
193 }).Add(
194 map[string]interface{}{
195 "apiVersion": "rbac.authorization.k8s.io/v1",
196 "kind": "ClusterRoleBinding",
197 "metadata": map[string]interface{}{
198 "name": "crb",
199 },
200 "subjects": []interface{}{
201 map[string]interface{}{
202 "kind": "ServiceAccount",
203 "name": "sa",
204 "namespace": "test",
205 },
206 },
207 }).Add(
208 map[string]interface{}{
209 "apiVersion": "rbac.authorization.k8s.io/v1",
210 "kind": "ClusterRole",
211 "metadata": map[string]interface{}{
212 "name": "cr",
213 },
214 "rules": []interface{}{
215 map[string]interface{}{
216 "resources": []interface{}{
217 "secrets",
218 },
219 "resourceNames": []interface{}{
220 "secret1",
221 "secret1",
222 "secret2",
223 "cm1",
224 },
225 },
226 },
227 }).Add(
228 map[string]interface{}{
229 "apiVersion": "batch/v1beta1",
230 "kind": "CronJob",
231 "metadata": map[string]interface{}{
232 "name": "cronjob1",
233 },
234 "spec": map[string]interface{}{
235 "schedule": "0 14 * * *",
236 "jobTemplate": map[string]interface{}{
237 "spec": map[string]interface{}{
238 "template": map[string]interface{}{
239 "spec": map[string]interface{}{
240 "containers": []interface{}{
241 map[string]interface{}{
242 "name": "main",
243 "image": "myimage",
244 },
245 },
246 "volumes": map[string]interface{}{
247 "projected": map[string]interface{}{
248 "sources": map[string]interface{}{
249 "configMap": map[string]interface{}{
250 "name": "cm2",
251 },
252 "secret": map[string]interface{}{
253 "name": "secret1",
254 },
255 },
256 },
257 },
258 },
259 },
260 },
261 },
262 },
263 }).ResMap()
264
265 expected := resmaptest_test.NewSeededRmBuilderDefault(
266 t, m.ShallowCopy()).ReplaceResource(
267 map[string]interface{}{
268 "group": "apps",
269 "apiVersion": "v1",
270 "kind": "Deployment",
271 "metadata": map[string]interface{}{
272 "name": "deploy1",
273 },
274 "spec": map[string]interface{}{
275 "template": map[string]interface{}{
276 "spec": map[string]interface{}{
277 "containers": []interface{}{
278 map[string]interface{}{
279 "name": "nginx",
280 "image": "nginx:1.7.9",
281 "env": []interface{}{
282 map[string]interface{}{
283 "name": "CM_FOO",
284 "valueFrom": map[string]interface{}{
285 "configMapKeyRef": map[string]interface{}{
286 "name": "someprefix-cm1-somehash",
287 "key": "somekey",
288 },
289 },
290 },
291 map[string]interface{}{
292 "name": "SECRET_FOO",
293 "valueFrom": map[string]interface{}{
294 "secretKeyRef": map[string]interface{}{
295 "name": "someprefix-secret1-somehash",
296 "key": "somekey",
297 },
298 },
299 },
300 },
301 "envFrom": []interface{}{
302 map[string]interface{}{
303 "configMapRef": map[string]interface{}{
304 "name": "someprefix-cm1-somehash",
305 "key": "somekey",
306 },
307 },
308 map[string]interface{}{
309 "secretRef": map[string]interface{}{
310 "name": "someprefix-secret1-somehash",
311 "key": "somekey",
312 },
313 },
314 },
315 },
316 },
317 "imagePullSecrets": []interface{}{
318 map[string]interface{}{
319 "name": "someprefix-secret1-somehash",
320 },
321 },
322 "volumes": map[string]interface{}{
323 "configMap": map[string]interface{}{
324 "name": "someprefix-cm1-somehash",
325 },
326 "projected": map[string]interface{}{
327 "sources": map[string]interface{}{
328 "configMap": map[string]interface{}{
329 "name": "someprefix-cm2-somehash",
330 },
331 "secret": map[string]interface{}{
332 "name": "someprefix-secret1-somehash",
333 },
334 },
335 },
336 "secret": map[string]interface{}{
337 "secretName": "someprefix-secret1-somehash",
338 },
339 "persistentVolumeClaim": map[string]interface{}{
340 "claimName": "someprefix-claim1",
341 },
342 },
343 },
344 },
345 },
346 }).ReplaceResource(
347 map[string]interface{}{
348 "group": "apps",
349 "apiVersion": "v1",
350 "kind": "StatefulSet",
351 "metadata": map[string]interface{}{
352 "name": "statefulset1",
353 },
354 "spec": map[string]interface{}{
355 "template": map[string]interface{}{
356 "spec": map[string]interface{}{
357 "containers": []interface{}{
358 map[string]interface{}{
359 "name": "nginx",
360 "image": "nginx:1.7.9",
361 },
362 },
363 "volumes": map[string]interface{}{
364 "projected": map[string]interface{}{
365 "sources": map[string]interface{}{
366 "configMap": map[string]interface{}{
367 "name": "someprefix-cm2-somehash",
368 },
369 "secret": map[string]interface{}{
370 "name": "someprefix-secret1-somehash",
371 },
372 },
373 },
374 },
375 },
376 },
377 },
378 }).ReplaceResource(
379 map[string]interface{}{
380 "group": "networking.k8s.io",
381 "apiVersion": "v1beta1",
382 "kind": "Ingress",
383 "metadata": map[string]interface{}{
384 "name": "ingress1",
385 "annotations": map[string]interface{}{
386 "ingress.kubernetes.io/auth-secret": "someprefix-secret1-somehash",
387 "nginx.ingress.kubernetes.io/auth-secret": "someprefix-secret1-somehash",
388 "nginx.ingress.kubernetes.io/auth-tls-secret": "someprefix-secret1-somehash",
389 },
390 },
391 "spec": map[string]interface{}{
392 "backend": map[string]interface{}{
393 "serviceName": "testsvc",
394 "servicePort": "80",
395 },
396 },
397 }).ReplaceResource(
398 map[string]interface{}{
399 "apiVersion": "rbac.authorization.k8s.io/v1",
400 "kind": "ClusterRoleBinding",
401 "metadata": map[string]interface{}{
402 "name": "crb",
403 },
404 "subjects": []interface{}{
405 map[string]interface{}{
406 "kind": "ServiceAccount",
407 "name": "someprefix-sa",
408 "namespace": "test",
409 },
410 },
411 }).ReplaceResource(
412 map[string]interface{}{
413 "apiVersion": "rbac.authorization.k8s.io/v1",
414 "kind": "ClusterRole",
415 "metadata": map[string]interface{}{
416 "name": "cr",
417 },
418 "rules": []interface{}{
419 map[string]interface{}{
420 "resources": []interface{}{
421 "secrets",
422 },
423 "resourceNames": []interface{}{
424 "someprefix-secret1-somehash",
425 "someprefix-secret1-somehash",
426 "secret2",
427 "someprefix-cm1-somehash",
428 },
429 },
430 },
431 }).ReplaceResource(
432 map[string]interface{}{
433 "apiVersion": "batch/v1beta1",
434 "kind": "CronJob",
435 "metadata": map[string]interface{}{
436 "name": "cronjob1",
437 },
438 "spec": map[string]interface{}{
439 "schedule": "0 14 * * *",
440 "jobTemplate": map[string]interface{}{
441 "spec": map[string]interface{}{
442 "template": map[string]interface{}{
443 "spec": map[string]interface{}{
444 "containers": []interface{}{
445 map[string]interface{}{
446 "name": "main",
447 "image": "myimage",
448 },
449 },
450 "volumes": map[string]interface{}{
451 "projected": map[string]interface{}{
452 "sources": map[string]interface{}{
453 "configMap": map[string]interface{}{
454 "name": "someprefix-cm2-somehash",
455 },
456 "secret": map[string]interface{}{
457 "name": "someprefix-secret1-somehash",
458 },
459 },
460 },
461 },
462 },
463 },
464 },
465 },
466 },
467 }).ResMap()
468
469 nrt := newNameReferenceTransformer(builtinconfig.MakeDefaultConfig().NameReference)
470 err := nrt.Transform(m)
471 if err != nil {
472 t.Fatalf("unexpected error: %v", err)
473 }
474
475 if err = expected.ErrorIfNotEqualLists(m); err != nil {
476 t.Fatalf(notEqualErrFmt, err)
477 }
478 }
479
480 func TestNameReferenceUnhappyRun(t *testing.T) {
481 tests := []struct {
482 resMap resmap.ResMap
483 expectedErr string
484 }{
485 {
486 resMap: resmaptest_test.NewRmBuilderDefault(t).Add(
487 map[string]interface{}{
488 "apiVersion": "rbac.authorization.k8s.io/v1",
489 "kind": "ClusterRole",
490 "metadata": map[string]interface{}{
491 "name": "cr",
492 },
493 "rules": []interface{}{
494 map[string]interface{}{
495 "resources": []interface{}{
496 "secrets",
497 },
498 "resourceNames": []interface{}{
499 []interface{}{},
500 },
501 },
502 },
503 }).ResMap(),
504 expectedErr: "is expected to be"},
505 {
506 resMap: resmaptest_test.NewRmBuilderDefault(t).Add(
507 map[string]interface{}{
508 "apiVersion": "rbac.authorization.k8s.io/v1",
509 "kind": "ClusterRole",
510 "metadata": map[string]interface{}{
511 "name": "cr",
512 },
513 "rules": []interface{}{
514 map[string]interface{}{
515 "resources": []interface{}{
516 "secrets",
517 },
518 "resourceNames": map[string]interface{}{
519 "foo": "bar",
520 },
521 },
522 },
523 }).ResMap(),
524 expectedErr: `updating name reference in 'rules/resourceNames' field of 'ClusterRole.v1.rbac.authorization.k8s.io/cr.[noNs]': ` +
525 `considering field 'rules/resourceNames' of object ClusterRole.v1.rbac.authorization.k8s.io/cr.[noNs]: visit traversal on ` +
526 `path: [resourceNames]: path config error; no 'name' field in node`,
527 },
528 {
529
530
531
532 resMap: resmaptest_test.NewRmBuilderDefault(t).AddWithNsAndName(
533 "", orgname,
534 map[string]interface{}{
535 "apiVersion": "v1",
536 "kind": "ServiceAccount",
537 "metadata": map[string]interface{}{
538 "name": orgname,
539 "namespace": ns1,
540 },
541 },
542 ).AddWithNsAndName(
543 "", orgname,
544 map[string]interface{}{
545 "apiVersion": "v1",
546 "kind": "ServiceAccount",
547 "metadata": map[string]interface{}{
548 "name": orgname,
549 "namespace": ns2,
550 },
551 },
552 ).Add(
553 map[string]interface{}{
554 "apiVersion": "rbac.authorization.k8s.io/v1",
555 "kind": "ClusterRoleBinding",
556 "metadata": map[string]interface{}{
557 "name": orgname,
558 },
559 "roleRef": map[string]interface{}{
560 "apiGroup": "rbac.authorization.k8s.io",
561 "kind": "ClusterRole",
562 "name": orgname,
563 },
564 "subjects": []interface{}{
565 map[string]interface{}{
566 "kind": "ServiceAccount",
567 "name": orgname,
568 },
569 },
570 },
571 ).ResMap(),
572 expectedErr: "found multiple possible referrals: ServiceAccount.v1.[noGrp]/uniquename.ns1, ServiceAccount.v1.[noGrp]/uniquename.ns2",
573 },
574 }
575
576 nrt := newNameReferenceTransformer(builtinconfig.MakeDefaultConfig().NameReference)
577 for _, test := range tests {
578 err := nrt.Transform(test.resMap)
579 if err == nil {
580 t.Fatalf("expected error to happen")
581 }
582
583 if !strings.Contains(err.Error(), test.expectedErr) {
584 t.Fatalf("Incorrect error.\nExpected:\n %s\nGot:\n%v",
585 test.expectedErr, err)
586 }
587 }
588 }
589
590 func TestNameReferencePersistentVolumeHappyRun(t *testing.T) {
591 rf := provider.NewDefaultDepProvider().GetResourceFactory()
592
593 v1 := rf.FromMapWithName(
594 "volume1",
595 map[string]interface{}{
596 "apiVersion": "v1",
597 "kind": "PersistentVolume",
598 "metadata": map[string]interface{}{
599 "name": "someprefix-volume1",
600 },
601 })
602 c1 := rf.FromMapWithName(
603 "claim1",
604 map[string]interface{}{
605 "apiVersion": "v1",
606 "kind": "PersistentVolumeClaim",
607 "metadata": map[string]interface{}{
608 "name": "someprefix-claim1",
609 "namespace": "some-namespace",
610 },
611 "spec": map[string]interface{}{
612 "volumeName": "volume1",
613 },
614 })
615
616 v2 := v1.DeepCopy()
617 c2 := rf.FromMapWithName(
618 "claim1",
619 map[string]interface{}{
620 "apiVersion": "v1",
621 "kind": "PersistentVolumeClaim",
622 "metadata": map[string]interface{}{
623 "name": "someprefix-claim1",
624 "namespace": "some-namespace",
625 },
626 "spec": map[string]interface{}{
627 "volumeName": "someprefix-volume1",
628 },
629 })
630
631 m1 := resmaptest_test.NewRmBuilder(t, rf).AddR(v1).AddR(c1).ResMap()
632
633 nrt := newNameReferenceTransformer(builtinconfig.MakeDefaultConfig().NameReference)
634 if err := nrt.Transform(m1); err != nil {
635 t.Fatalf("unexpected error: %v", err)
636 }
637
638 m2 := resmaptest_test.NewRmBuilder(t, rf).AddR(v2).AddR(c2).ResMap()
639 v2.AppendRefBy(c2.CurId())
640
641 if err := m1.ErrorIfNotEqualLists(m2); err != nil {
642 t.Fatalf(notEqualErrFmt, err)
643 }
644 }
645
646
647
648
649 func deploymentMap(metadatanamespace string, metadataname string,
650 configmapref string, secretref string) map[string]interface{} {
651 deployment := map[string]interface{}{
652 "group": "apps",
653 "apiVersion": "v1",
654 "kind": "Deployment",
655 "metadata": map[string]interface{}{
656 "name": metadataname,
657 },
658 "spec": map[string]interface{}{
659 "template": map[string]interface{}{
660 "spec": map[string]interface{}{
661 "containers": []interface{}{
662 map[string]interface{}{
663 "name": "nginx",
664 "image": "nginx:1.7.9",
665 "env": []interface{}{
666 map[string]interface{}{
667 "name": "CM_FOO",
668 "valueFrom": map[string]interface{}{
669 "configMapKeyRef": map[string]interface{}{
670 "name": configmapref,
671 "key": "somekey",
672 },
673 },
674 },
675 map[string]interface{}{
676 "name": "SECRET_FOO",
677 "valueFrom": map[string]interface{}{
678 "secretKeyRef": map[string]interface{}{
679 "name": secretref,
680 "key": "somekey",
681 },
682 },
683 },
684 },
685 },
686 },
687 },
688 },
689 },
690 }
691
692 if metadatanamespace != "" {
693 metadata := deployment["metadata"].(map[string]interface{})
694 metadata["namespace"] = metadatanamespace
695 }
696 return deployment
697 }
698
699 const (
700 defaultNs = "default"
701 ns1 = "ns1"
702 ns2 = "ns2"
703 ns3 = "ns3"
704 ns4 = "ns4"
705
706 orgname = "uniquename"
707 prefixedname = "prefix-uniquename"
708 suffixedname = "uniquename-suffix"
709 modifiedname = "modifiedname"
710 )
711
712
713
714
715 func TestNameReferenceNamespace(t *testing.T) {
716 m := resmaptest_test.NewRmBuilderDefault(t).
717
718 AddWithName(orgname, map[string]interface{}{
719 "apiVersion": "v1",
720 "kind": "ConfigMap",
721 "metadata": map[string]interface{}{
722 "name": modifiedname,
723 }}).
724 AddWithNsAndName(ns1, orgname, map[string]interface{}{
725 "apiVersion": "v1",
726 "kind": "ConfigMap",
727 "metadata": map[string]interface{}{
728 "name": prefixedname,
729 "namespace": ns1,
730 }}).
731 AddWithNsAndName(ns2, orgname, map[string]interface{}{
732 "apiVersion": "v1",
733 "kind": "ConfigMap",
734 "metadata": map[string]interface{}{
735 "name": suffixedname,
736 "namespace": ns2,
737 }}).
738
739 AddWithNsAndName(defaultNs, orgname, map[string]interface{}{
740 "apiVersion": "v1",
741 "kind": "Secret",
742 "metadata": map[string]interface{}{
743 "name": modifiedname,
744 "namespace": defaultNs,
745 }}).
746 AddWithNsAndName(ns1, orgname, map[string]interface{}{
747 "apiVersion": "v1",
748 "kind": "Secret",
749 "metadata": map[string]interface{}{
750 "name": prefixedname,
751 "namespace": ns1,
752 }}).
753 AddWithNsAndName(ns2, orgname, map[string]interface{}{
754 "apiVersion": "v1",
755 "kind": "Secret",
756 "metadata": map[string]interface{}{
757 "name": suffixedname,
758 "namespace": ns2,
759 }}).
760
761 AddWithNsAndName(defaultNs, orgname, deploymentMap(defaultNs, modifiedname, modifiedname, modifiedname)).
762 AddWithNsAndName(ns1, orgname, deploymentMap(ns1, prefixedname, orgname, orgname)).
763 AddWithNsAndName(ns2, orgname, deploymentMap(ns2, suffixedname, orgname, orgname)).ResMap()
764
765 expected := resmaptest_test.NewSeededRmBuilderDefault(t, m.ShallowCopy()).
766 ReplaceResource(deploymentMap(defaultNs, modifiedname, modifiedname, modifiedname)).
767 ReplaceResource(deploymentMap(ns1, prefixedname, prefixedname, prefixedname)).
768 ReplaceResource(deploymentMap(ns2, suffixedname, suffixedname, suffixedname)).ResMap()
769
770 nrt := newNameReferenceTransformer(builtinconfig.MakeDefaultConfig().NameReference)
771 err := nrt.Transform(m)
772 if err != nil {
773 t.Fatalf("unexpected error: %v", err)
774 }
775
776 m.RemoveBuildAnnotations()
777 if err = expected.ErrorIfNotEqualLists(m); err != nil {
778 t.Fatalf(notEqualErrFmt, err)
779 }
780 }
781
782
783
784
785 func TestNameReferenceClusterWide(t *testing.T) {
786 m := resmaptest_test.NewRmBuilderDefault(t).
787
788 AddWithName(orgname, map[string]interface{}{
789 "apiVersion": "v1",
790 "kind": "ServiceAccount",
791 "metadata": map[string]interface{}{
792 "name": modifiedname,
793 }}).
794 AddWithNsAndName(ns1, orgname, map[string]interface{}{
795 "apiVersion": "v1",
796 "kind": "ServiceAccount",
797 "metadata": map[string]interface{}{
798 "name": prefixedname,
799 "namespace": ns1,
800 }}).
801 AddWithNsAndName(ns2, orgname, map[string]interface{}{
802 "apiVersion": "v1",
803 "kind": "ServiceAccount",
804 "metadata": map[string]interface{}{
805 "name": suffixedname,
806 "namespace": ns2,
807 }}).
808
809 AddWithName(orgname, map[string]interface{}{
810 "apiVersion": "v1",
811 "kind": "PersistentVolume",
812 "metadata": map[string]interface{}{
813 "name": modifiedname,
814 }}).
815 AddWithName(orgname, map[string]interface{}{
816 "apiVersion": "rbac.authorization.k8s.io/v1",
817 "kind": "ClusterRole",
818 "metadata": map[string]interface{}{
819 "name": modifiedname,
820 },
821 "rules": []interface{}{
822 map[string]interface{}{
823 "resources": []interface{}{
824 "persistentvolumes",
825 },
826 "resourceNames": []interface{}{
827 orgname,
828 },
829 },
830 }}).
831 AddWithName(orgname, map[string]interface{}{
832 "apiVersion": "rbac.authorization.k8s.io/v1",
833 "kind": "ClusterRoleBinding",
834 "metadata": map[string]interface{}{
835 "name": modifiedname,
836 },
837 "roleRef": map[string]interface{}{
838 "apiGroup": "rbac.authorization.k8s.io",
839 "kind": "ClusterRole",
840 "name": orgname,
841 },
842 "subjects": []interface{}{
843 map[string]interface{}{
844 "kind": "ServiceAccount",
845 "name": orgname,
846 "namespace": defaultNs,
847 },
848 map[string]interface{}{
849 "kind": "ServiceAccount",
850 "name": orgname,
851 "namespace": ns1,
852 },
853 map[string]interface{}{
854 "kind": "ServiceAccount",
855 "name": orgname,
856 "namespace": ns2,
857 },
858 map[string]interface{}{
859 "kind": "ServiceAccount",
860 "name": orgname,
861 "namespace": "random",
862 },
863 }}).ResMap()
864
865 expected := resmaptest_test.NewSeededRmBuilderDefault(t, m.ShallowCopy()).
866 ReplaceResource(
867 map[string]interface{}{
868 "apiVersion": "rbac.authorization.k8s.io/v1",
869 "kind": "ClusterRole",
870 "metadata": map[string]interface{}{
871 "name": modifiedname,
872 },
873
874
875
876 "rules": []interface{}{
877 map[string]interface{}{
878 "resources": []interface{}{
879 "persistentvolumes",
880 },
881 "resourceNames": []interface{}{
882 modifiedname,
883 },
884 },
885 }}).
886 ReplaceResource(
887 map[string]interface{}{
888 "apiVersion": "rbac.authorization.k8s.io/v1",
889 "kind": "ClusterRoleBinding",
890 "metadata": map[string]interface{}{
891 "name": modifiedname,
892 },
893 "roleRef": map[string]interface{}{
894 "apiGroup": "rbac.authorization.k8s.io",
895 "kind": "ClusterRole",
896 "name": modifiedname,
897 },
898
899
900
901 "subjects": []interface{}{
902 map[string]interface{}{
903 "kind": "ServiceAccount",
904 "name": modifiedname,
905 "namespace": defaultNs,
906 },
907 map[string]interface{}{
908 "kind": "ServiceAccount",
909 "name": prefixedname,
910 "namespace": ns1,
911 },
912 map[string]interface{}{
913 "kind": "ServiceAccount",
914 "name": suffixedname,
915 "namespace": ns2,
916 },
917 map[string]interface{}{
918 "kind": "ServiceAccount",
919 "name": orgname,
920 "namespace": "random",
921 },
922 },
923 }).ResMap()
924
925 clusterRoleId := resid.NewResId(
926 resid.NewGvk("rbac.authorization.k8s.io", "v1", "ClusterRole"), modifiedname)
927 clusterRoleBindingId := resid.NewResId(
928 resid.NewGvk("rbac.authorization.k8s.io", "v1", "ClusterRoleBinding"), modifiedname)
929 clusterRole, _ := expected.GetByCurrentId(clusterRoleId)
930 clusterRole.AppendRefBy(clusterRoleBindingId)
931
932 nrt := newNameReferenceTransformer(builtinconfig.MakeDefaultConfig().NameReference)
933 err := nrt.Transform(m)
934 if err != nil {
935 t.Fatalf("unexpected error: %v", err)
936 }
937
938 expected.RemoveBuildAnnotations()
939 m.RemoveBuildAnnotations()
940
941 if err = expected.ErrorIfNotEqualLists(m); err != nil {
942 t.Fatalf(notEqualErrFmt, err)
943 }
944 }
945
946
947
948
949 func TestNameReferenceNamespaceTransformation(t *testing.T) {
950 m := resmaptest_test.NewRmBuilderDefault(t).
951 AddWithNsAndName(ns4, orgname, map[string]interface{}{
952 "apiVersion": "v1",
953 "kind": "Secret",
954 "metadata": map[string]interface{}{
955 "name": orgname,
956 "namespace": ns4,
957 }}).
958
959 AddWithNsAndName(ns1, orgname, map[string]interface{}{
960 "apiVersion": "v1",
961 "kind": "ServiceAccount",
962 "metadata": map[string]interface{}{
963 "name": prefixedname,
964 "namespace": ns1,
965 }}).
966
967 AddWithNsAndName(ns3, orgname, map[string]interface{}{
968 "apiVersion": "v1",
969 "kind": "ServiceAccount",
970 "metadata": map[string]interface{}{
971 "name": suffixedname,
972 "namespace": ns2,
973 }}).
974 AddWithName(orgname, map[string]interface{}{
975 "apiVersion": "rbac.authorization.k8s.io/v1",
976 "kind": "ClusterRole",
977 "metadata": map[string]interface{}{
978 "name": modifiedname,
979 }}).
980 AddWithName(orgname, map[string]interface{}{
981 "apiVersion": "rbac.authorization.k8s.io/v1",
982 "kind": "ClusterRoleBinding",
983 "metadata": map[string]interface{}{
984 "name": modifiedname,
985 },
986 "roleRef": map[string]interface{}{
987 "apiGroup": "rbac.authorization.k8s.io",
988 "kind": "ClusterRole",
989 "name": orgname,
990 },
991 "subjects": []interface{}{
992 map[string]interface{}{
993 "kind": "ServiceAccount",
994 "name": orgname,
995 "namespace": ns1,
996 },
997 map[string]interface{}{
998 "kind": "ServiceAccount",
999 "name": orgname,
1000 "namespace": ns3,
1001 },
1002 map[string]interface{}{
1003 "kind": "ServiceAccount",
1004 "name": orgname,
1005 "namespace": "random",
1006 },
1007 map[string]interface{}{
1008 "kind": "ServiceAccount",
1009 "name": orgname,
1010 "namespace": ns4,
1011 },
1012 }}).ResMap()
1013
1014 expected := resmaptest_test.NewSeededRmBuilderDefault(t, m.ShallowCopy()).
1015 ReplaceResource(
1016 map[string]interface{}{
1017 "apiVersion": "rbac.authorization.k8s.io/v1",
1018 "kind": "ClusterRoleBinding",
1019 "metadata": map[string]interface{}{
1020 "name": modifiedname,
1021 },
1022 "roleRef": map[string]interface{}{
1023 "apiGroup": "rbac.authorization.k8s.io",
1024 "kind": "ClusterRole",
1025 "name": modifiedname,
1026 },
1027
1028
1029
1030 "subjects": []interface{}{
1031 map[string]interface{}{
1032 "kind": "ServiceAccount",
1033 "name": prefixedname,
1034 "namespace": ns1,
1035 },
1036 map[string]interface{}{
1037 "kind": "ServiceAccount",
1038 "name": suffixedname,
1039 "namespace": ns2,
1040 },
1041 map[string]interface{}{
1042 "kind": "ServiceAccount",
1043 "name": orgname,
1044 "namespace": "random",
1045 },
1046 map[string]interface{}{
1047 "kind": "ServiceAccount",
1048 "name": orgname,
1049 "namespace": ns4,
1050 },
1051 },
1052 }).ResMap()
1053
1054 clusterRoleId := resid.NewResId(
1055 resid.NewGvk("rbac.authorization.k8s.io", "v1", "ClusterRole"),
1056 modifiedname)
1057 clusterRoleBindingId := resid.NewResId(
1058 resid.NewGvk("rbac.authorization.k8s.io", "v1", "ClusterRoleBinding"),
1059 modifiedname)
1060 clusterRole, _ := expected.GetByCurrentId(clusterRoleId)
1061 clusterRole.AppendRefBy(clusterRoleBindingId)
1062
1063 nrt := newNameReferenceTransformer(builtinconfig.MakeDefaultConfig().NameReference)
1064 err := nrt.Transform(m)
1065 if err != nil {
1066 t.Fatalf("unexpected error: %v", err)
1067 }
1068
1069 m.RemoveBuildAnnotations()
1070 if err = expected.ErrorIfNotEqualLists(m); err != nil {
1071 t.Fatalf(notEqualErrFmt, err)
1072 }
1073 }
1074
1075
1076
1077
1078 func TestNameReferenceCandidateSelection(t *testing.T) {
1079 m := resmaptest_test.NewRmBuilderDefault(t).
1080 AddWithName("cm1", map[string]interface{}{
1081 "apiVersion": "v1",
1082 "kind": "ConfigMap",
1083 "metadata": map[string]interface{}{
1084 "name": "p1-cm1-hash",
1085 }}).
1086 AddWithNsAndName("default", "secret1", map[string]interface{}{
1087 "apiVersion": "v1",
1088 "kind": "Secret",
1089 "metadata": map[string]interface{}{
1090 "name": "p1-secret1-hash",
1091 "namespace": "default",
1092 }}).
1093 AddWithName("deploy1", deploymentMap("", "p1-deploy1", "cm1", "secret1")).
1094 ResMap()
1095
1096 expected := resmaptest_test.NewSeededRmBuilderDefault(t, m.ShallowCopy()).
1097 ReplaceResource(deploymentMap("", "p1-deploy1", "p1-cm1-hash", "p1-secret1-hash")).
1098 ResMap()
1099
1100 nrt := newNameReferenceTransformer(builtinconfig.MakeDefaultConfig().NameReference)
1101 err := nrt.Transform(m)
1102 if err != nil {
1103 t.Fatalf("unexpected error: %v", err)
1104 }
1105
1106 m.RemoveBuildAnnotations()
1107 if err = expected.ErrorIfNotEqualLists(m); err != nil {
1108 t.Fatalf(notEqualErrFmt, err)
1109 }
1110 }
1111
1112 func TestNameReferenceCandidateDisambiguationByNamespace(t *testing.T) {
1113
1114
1115
1116
1117
1118 m := resmaptest_test.NewRmBuilderDefault(t).AddWithName(orgname,
1119 map[string]interface{}{
1120 "apiVersion": "v1",
1121 "kind": "ConfigMap",
1122 "metadata": map[string]interface{}{
1123 "name": suffixedname,
1124 "namespace": ns1,
1125 },
1126 },
1127 ).AddWithName(orgname,
1128 map[string]interface{}{
1129 "apiVersion": "v1",
1130 "kind": "ConfigMap",
1131 "metadata": map[string]interface{}{
1132 "name": suffixedname,
1133 "namespace": ns2,
1134 },
1135 },
1136 ).Add(
1137 map[string]interface{}{
1138 "apiVersion": "rbac.authorization.k8s.io/v1",
1139 "kind": "ClusterRole",
1140 "metadata": map[string]interface{}{
1141 "name": orgname,
1142 },
1143 "rules": []interface{}{
1144 map[string]interface{}{
1145 "resources": []interface{}{
1146 "configmaps",
1147 },
1148 "resourceNames": []interface{}{
1149 orgname,
1150 },
1151 },
1152 },
1153 },
1154 ).ResMap()
1155
1156 expected := resmaptest_test.NewSeededRmBuilderDefault(t, m.ShallowCopy()).
1157 ReplaceResource(map[string]interface{}{
1158 "apiVersion": "rbac.authorization.k8s.io/v1",
1159 "kind": "ClusterRole",
1160 "metadata": map[string]interface{}{
1161 "name": orgname,
1162 },
1163 "rules": []interface{}{
1164 map[string]interface{}{
1165 "resources": []interface{}{
1166 "configmaps",
1167 },
1168 "resourceNames": []interface{}{
1169 suffixedname,
1170 },
1171 },
1172 },
1173 },
1174 ).ResMap()
1175
1176 nrt := newNameReferenceTransformer(builtinconfig.MakeDefaultConfig().NameReference)
1177 require.NoError(t, nrt.Transform(m))
1178
1179 m.RemoveBuildAnnotations()
1180 if err := expected.ErrorIfNotEqualLists(m); err != nil {
1181 t.Fatalf(notEqualErrFmt, err)
1182 }
1183 }
1184
View as plain text