1
2
3
4 package replacement
5
6 import (
7 "strings"
8 "testing"
9
10 "github.com/stretchr/testify/assert"
11 filtertest "sigs.k8s.io/kustomize/api/testutils/filtertest"
12 "sigs.k8s.io/kustomize/kyaml/yaml"
13 )
14
15 func TestFilter(t *testing.T) {
16 testCases := map[string]struct {
17 input string
18 replacements string
19 expected string
20 expectedErr string
21 }{
22 "simple": {
23 input: `apiVersion: v1
24 kind: Deployment
25 metadata:
26 name: deploy
27 spec:
28 template:
29 spec:
30 containers:
31 - image: nginx:1.7.9
32 name: nginx-tagged
33 - image: postgres:1.8.0
34 name: postgresdb
35 `,
36 replacements: `replacements:
37 - source:
38 kind: Deployment
39 name: deploy
40 fieldPath: spec.template.spec.containers.0.image
41 targets:
42 - select:
43 kind: Deployment
44 name: deploy
45 fieldPaths:
46 - spec.template.spec.containers.1.image
47 `,
48 expected: `apiVersion: v1
49 kind: Deployment
50 metadata:
51 name: deploy
52 spec:
53 template:
54 spec:
55 containers:
56 - image: nginx:1.7.9
57 name: nginx-tagged
58 - image: nginx:1.7.9
59 name: postgresdb
60 `,
61 },
62 "complex type": {
63 input: `apiVersion: v1
64 kind: Pod
65 metadata:
66 name: pod
67 spec:
68 containers:
69 - image: busybox
70 name: myapp-container
71 ---
72 apiVersion: apps/v1
73 kind: Deployment
74 metadata:
75 name: deploy2
76 spec:
77 template:
78 spec:
79 containers: {}
80 ---
81 apiVersion: apps/v1
82 kind: Deployment
83 metadata:
84 name: deploy3
85 spec:
86 template:
87 spec:
88 containers: {}
89 `,
90 replacements: `replacements:
91 - source:
92 kind: Pod
93 name: pod
94 fieldPath: spec.containers
95 targets:
96 - select:
97 kind: Deployment
98 fieldPaths:
99 - spec.template.spec.containers
100 `,
101 expected: `apiVersion: v1
102 kind: Pod
103 metadata:
104 name: pod
105 spec:
106 containers:
107 - image: busybox
108 name: myapp-container
109 ---
110 apiVersion: apps/v1
111 kind: Deployment
112 metadata:
113 name: deploy2
114 spec:
115 template:
116 spec:
117 containers:
118 - image: busybox
119 name: myapp-container
120 ---
121 apiVersion: apps/v1
122 kind: Deployment
123 metadata:
124 name: deploy3
125 spec:
126 template:
127 spec:
128 containers:
129 - image: busybox
130 name: myapp-container
131 `,
132 },
133 "from ConfigMap": {
134 input: `apiVersion: apps/v1
135 kind: Deployment
136 metadata:
137 name: deploy
138 labels:
139 foo: bar
140 spec:
141 template:
142 metadata:
143 labels:
144 foo: bar
145 spec:
146 containers:
147 - name: command-demo-container
148 image: debian
149 command: ["printenv"]
150 args:
151 - HOSTNAME
152 - PORT
153 - name: busybox
154 image: busybox:latest
155 args:
156 - echo
157 - HOSTNAME
158 - PORT
159 ---
160 apiVersion: v1
161 kind: ConfigMap
162 metadata:
163 name: cm
164 data:
165 HOSTNAME: example.com
166 PORT: 8080
167 `,
168 replacements: `replacements:
169 - source:
170 kind: ConfigMap
171 name: cm
172 fieldPath: data.HOSTNAME
173 targets:
174 - select:
175 kind: Deployment
176 fieldPaths:
177 - spec.template.spec.containers.0.args.0
178 - spec.template.spec.containers.1.args.1
179 - source:
180 kind: ConfigMap
181 name: cm
182 fieldPath: data.PORT
183 targets:
184 - select:
185 kind: Deployment
186 fieldPaths:
187 - spec.template.spec.containers.0.args.1
188 - spec.template.spec.containers.1.args.2
189 `,
190 expected: `apiVersion: apps/v1
191 kind: Deployment
192 metadata:
193 name: deploy
194 labels:
195 foo: bar
196 spec:
197 template:
198 metadata:
199 labels:
200 foo: bar
201 spec:
202 containers:
203 - name: command-demo-container
204 image: debian
205 command: ["printenv"]
206 args:
207 - example.com
208 - "8080"
209 - name: busybox
210 image: busybox:latest
211 args:
212 - echo
213 - example.com
214 - "8080"
215 ---
216 apiVersion: v1
217 kind: ConfigMap
218 metadata:
219 name: cm
220 data:
221 HOSTNAME: example.com
222 PORT: 8080
223 `,
224 },
225 "multiple matches for source select": {
226 input: `apiVersion: v1
227 kind: Deployment
228 metadata:
229 name: deploy1
230 spec:
231 template:
232 spec:
233 containers:
234 - image: nginx:1.7.9
235 name: nginx-tagged
236 - image: postgres:1.8.0
237 name: postgresdb
238 ---
239 apiVersion: v1
240 kind: Deployment
241 metadata:
242 name: deploy2
243 spec:
244 template:
245 spec:
246 containers:
247 - image: nginx:1.7.9
248 name: nginx-tagged
249 - image: postgres:1.8.0
250 name: postgresdb
251 ---
252 apiVersion: v1
253 kind: Deployment
254 metadata:
255 name: deploy3
256 spec:
257 template:
258 spec:
259 containers:
260 - image: nginx:1.7.9
261 name: nginx-tagged
262 - image: postgres:1.8.0
263 name: postgresdb
264 `,
265 replacements: `replacements:
266 - source:
267 kind: Deployment
268 targets:
269 - select:
270 kind: Deployment
271 `,
272 expectedErr: "multiple matches for selector Deployment.[noVer].[noGrp]/[noName].[noNs]",
273 },
274 "replacement has no source": {
275 input: `apiVersion: v1
276 kind: Deployment
277 metadata:
278 name: deploy
279 spec:
280 template:
281 spec:
282 containers:
283 - image: nginx:1.7.9
284 name: nginx-tagged
285 - image: postgres:1.8.0
286 name: postgresdb
287 `,
288 replacements: `replacements:
289 - targets:
290 - select:
291 kind: Deployment
292 `,
293 expectedErr: "replacements must specify a source and at least one target",
294 },
295 "field paths with key-value pairs": {
296 input: `apiVersion: v1
297 kind: Deployment
298 metadata:
299 name: deploy1
300 spec:
301 template:
302 spec:
303 containers:
304 - image: nginx:1.7.9
305 name: nginx-tagged
306 - image: postgres:1.8.0
307 name: postgresdb
308 ---
309 apiVersion: v1
310 kind: Deployment
311 metadata:
312 name: deploy2
313 spec:
314 template:
315 spec:
316 containers:
317 - image: nginx:1.7.9
318 name: nginx-tagged
319 - image: postgres:1.8.0
320 name: postgresdb
321 `,
322 replacements: `replacements:
323 - source:
324 kind: Deployment
325 name: deploy2
326 fieldPath: spec.template.spec.containers.[name=nginx-tagged].image
327 targets:
328 - select:
329 kind: Deployment
330 name: deploy1
331 fieldPaths:
332 - spec.template.spec.containers.[name=postgresdb].image
333 `,
334 expected: `apiVersion: v1
335 kind: Deployment
336 metadata:
337 name: deploy1
338 spec:
339 template:
340 spec:
341 containers:
342 - image: nginx:1.7.9
343 name: nginx-tagged
344 - image: nginx:1.7.9
345 name: postgresdb
346 ---
347 apiVersion: v1
348 kind: Deployment
349 metadata:
350 name: deploy2
351 spec:
352 template:
353 spec:
354 containers:
355 - image: nginx:1.7.9
356 name: nginx-tagged
357 - image: postgres:1.8.0
358 name: postgresdb
359 `,
360 },
361 "select by group and version": {
362 input: `apiVersion: my-group-1/v1
363 kind: Custom
364 metadata:
365 name: my-name
366 spec:
367 template:
368 spec:
369 containers:
370 - image: nginx:1.7.9
371 name: nginx-tagged
372 - image: postgres:1.8.0
373 name: postgresdb
374 ---
375 apiVersion: my-group-2/v2
376 kind: Custom
377 metadata:
378 name: my-name
379 spec:
380 template:
381 spec:
382 containers:
383 - image: nginx:1.7.9
384 name: nginx-tagged
385 - image: postgres:1.8.0
386 name: postgresdb
387 ---
388 apiVersion: my-group-3/v3
389 kind: Custom
390 metadata:
391 name: my-name
392 spec:
393 template:
394 spec:
395 containers:
396 - image: nginx:1.7.9
397 name: nginx-tagged
398 - image: postgres:1.8.0
399 name: postgresdb
400 `,
401 replacements: `replacements:
402 - source:
403 group: my-group-2
404 fieldPath: spec.template.spec.containers.0.image
405 targets:
406 - select:
407 version: v3
408 fieldPaths:
409 - spec.template.spec.containers.1.image
410 `,
411 expected: `apiVersion: my-group-1/v1
412 kind: Custom
413 metadata:
414 name: my-name
415 spec:
416 template:
417 spec:
418 containers:
419 - image: nginx:1.7.9
420 name: nginx-tagged
421 - image: postgres:1.8.0
422 name: postgresdb
423 ---
424 apiVersion: my-group-2/v2
425 kind: Custom
426 metadata:
427 name: my-name
428 spec:
429 template:
430 spec:
431 containers:
432 - image: nginx:1.7.9
433 name: nginx-tagged
434 - image: postgres:1.8.0
435 name: postgresdb
436 ---
437 apiVersion: my-group-3/v3
438 kind: Custom
439 metadata:
440 name: my-name
441 spec:
442 template:
443 spec:
444 containers:
445 - image: nginx:1.7.9
446 name: nginx-tagged
447 - image: nginx:1.7.9
448 name: postgresdb
449 `,
450 },
451
452 "missing metadata": {
453 input: `spec:
454 template:
455 spec:
456 containers:
457 - image: nginx:1.7.9
458 name: nginx-tagged
459 - image: postgres:1.8.0
460 name: postgresdb
461 ---
462 apiVersion: my-group/v1
463 kind: Custom
464 metadata:
465 name: my-name-1
466 spec:
467 template:
468 spec:
469 containers:
470 - image: nginx:1.7.9
471 name: nginx-tagged
472 - image: postgres:1.8.0
473 name: postgresdb
474 ---
475 apiVersion: my-group/v1
476 kind: Custom
477 metadata:
478 name: my-name-2
479 spec:
480 template:
481 spec:
482 containers:
483 - image: nginx:1.7.9
484 name: nginx-tagged
485 - image: postgres:1.8.0
486 name: postgresdb
487 `,
488 replacements: `replacements:
489 - source:
490 name: my-name-1
491 fieldPath: spec.template.spec.containers.0.image
492 targets:
493 - select:
494 name: my-name-2
495 fieldPaths:
496 - spec.template.spec.containers.1.image
497 `,
498 expected: `spec:
499 template:
500 spec:
501 containers:
502 - image: nginx:1.7.9
503 name: nginx-tagged
504 - image: postgres:1.8.0
505 name: postgresdb
506 ---
507 apiVersion: my-group/v1
508 kind: Custom
509 metadata:
510 name: my-name-1
511 spec:
512 template:
513 spec:
514 containers:
515 - image: nginx:1.7.9
516 name: nginx-tagged
517 - image: postgres:1.8.0
518 name: postgresdb
519 ---
520 apiVersion: my-group/v1
521 kind: Custom
522 metadata:
523 name: my-name-2
524 spec:
525 template:
526 spec:
527 containers:
528 - image: nginx:1.7.9
529 name: nginx-tagged
530 - image: nginx:1.7.9
531 name: postgresdb
532 `,
533 },
534 "reject 1": {
535 input: `apiVersion: v1
536 kind: Deployment
537 metadata:
538 name: deploy1
539 spec:
540 template:
541 spec:
542 containers:
543 - image: nginx:1.7.9
544 name: nginx-tagged
545 - image: postgres:1.8.0
546 name: postgresdb
547 ---
548 apiVersion: v1
549 kind: Deployment
550 metadata:
551 name: deploy2
552 spec:
553 template:
554 spec:
555 containers:
556 - image: nginx:1.7.9
557 name: nginx-tagged
558 - image: postgres:1.8.0
559 name: postgresdb
560 ---
561 apiVersion: v1
562 kind: Deployment
563 metadata:
564 name: deploy3
565 spec:
566 template:
567 spec:
568 containers:
569 - image: nginx:1.7.9
570 name: nginx-tagged
571 - image: postgres:1.8.0
572 name: postgresdb
573 `,
574 replacements: `replacements:
575 - source:
576 kind: Deployment
577 name: deploy2
578 fieldPath: spec.template.spec.containers.0.image
579 targets:
580 - select:
581 kind: Deployment
582 reject:
583 - name: deploy2
584 - name: deploy3
585 fieldPaths:
586 - spec.template.spec.containers.1.image
587 `,
588 expected: `apiVersion: v1
589 kind: Deployment
590 metadata:
591 name: deploy1
592 spec:
593 template:
594 spec:
595 containers:
596 - image: nginx:1.7.9
597 name: nginx-tagged
598 - image: nginx:1.7.9
599 name: postgresdb
600 ---
601 apiVersion: v1
602 kind: Deployment
603 metadata:
604 name: deploy2
605 spec:
606 template:
607 spec:
608 containers:
609 - image: nginx:1.7.9
610 name: nginx-tagged
611 - image: postgres:1.8.0
612 name: postgresdb
613 ---
614 apiVersion: v1
615 kind: Deployment
616 metadata:
617 name: deploy3
618 spec:
619 template:
620 spec:
621 containers:
622 - image: nginx:1.7.9
623 name: nginx-tagged
624 - image: postgres:1.8.0
625 name: postgresdb
626 `,
627 },
628 "reject 2": {
629 input: `apiVersion: v1
630 kind: Deployment
631 metadata:
632 name: my-name
633 spec:
634 template:
635 spec:
636 containers:
637 - image: nginx:1.7.9
638 name: nginx-tagged
639 - image: postgres:1.8.0
640 name: postgresdb
641 ---
642 apiVersion: v1
643 kind: StatefulSet
644 metadata:
645 name: my-name
646 spec:
647 template:
648 spec:
649 containers:
650 - image: nginx:1.7.9
651 name: nginx-tagged
652 - image: postgres:1.8.0
653 name: postgresdb
654 `,
655 replacements: `replacements:
656 - source:
657 kind: Deployment
658 fieldPath: spec.template.spec.containers.0.image
659 targets:
660 - select:
661 version: v1
662 reject:
663 - kind: Deployment
664 name: my-name
665 fieldPaths:
666 - spec.template.spec.containers.1.image
667 `,
668 expected: `apiVersion: v1
669 kind: Deployment
670 metadata:
671 name: my-name
672 spec:
673 template:
674 spec:
675 containers:
676 - image: nginx:1.7.9
677 name: nginx-tagged
678 - image: postgres:1.8.0
679 name: postgresdb
680 ---
681 apiVersion: v1
682 kind: StatefulSet
683 metadata:
684 name: my-name
685 spec:
686 template:
687 spec:
688 containers:
689 - image: nginx:1.7.9
690 name: nginx-tagged
691 - image: nginx:1.7.9
692 name: postgresdb
693 `,
694 },
695
696
697 "reject 3": {
698 input: `apiVersion: v1
699 kind: Deployment
700 metadata:
701 name: my-name
702 spec:
703 template:
704 spec:
705 containers:
706 - image: nginx:1.7.9
707 name: nginx-tagged
708 - image: postgres:1.8.0
709 name: postgresdb
710 ---
711 apiVersion: v1
712 kind: StatefulSet
713 metadata:
714 name: my-name
715 spec:
716 template:
717 spec:
718 containers:
719 - image: nginx:1.7.9
720 name: nginx-tagged
721 - image: postgres:1.8.0
722 name: postgresdb
723 `,
724 replacements: `replacements:
725 - source:
726 kind: Deployment
727 fieldPath: spec.template.spec.containers.0.image
728 targets:
729 - select:
730 version: v1
731 reject:
732 - kind: Deployment
733 - name: my-name
734 fieldPaths:
735 - spec.template.spec.containers.1.image
736 `,
737 expected: `apiVersion: v1
738 kind: Deployment
739 metadata:
740 name: my-name
741 spec:
742 template:
743 spec:
744 containers:
745 - image: nginx:1.7.9
746 name: nginx-tagged
747 - image: postgres:1.8.0
748 name: postgresdb
749 ---
750 apiVersion: v1
751 kind: StatefulSet
752 metadata:
753 name: my-name
754 spec:
755 template:
756 spec:
757 containers:
758 - image: nginx:1.7.9
759 name: nginx-tagged
760 - image: postgres:1.8.0
761 name: postgresdb
762 `,
763 },
764 "partial string replacement - replace": {
765 input: `apiVersion: v1
766 kind: Deployment
767 metadata:
768 name: deploy1
769 spec:
770 template:
771 spec:
772 containers:
773 - image: nginx:1.7.9
774 name: nginx-tagged
775 - image: postgres:1.8.0
776 name: postgresdb
777 ---
778 apiVersion: v1
779 kind: Deployment
780 metadata:
781 name: deploy2
782 spec:
783 template:
784 spec:
785 containers:
786 - image: nginx:1.7.9
787 name: nginx-tagged
788 - image: postgres:1.8.0
789 name: postgresdb
790 `,
791 replacements: `replacements:
792 - source:
793 kind: Deployment
794 name: deploy2
795 fieldPath: spec.template.spec.containers.0.image
796 options:
797 delimiter: ':'
798 targets:
799 - select:
800 kind: Deployment
801 name: deploy1
802 fieldPaths:
803 - spec.template.spec.containers.1.image
804 options:
805 delimiter: ':'
806 `,
807 expected: `apiVersion: v1
808 kind: Deployment
809 metadata:
810 name: deploy1
811 spec:
812 template:
813 spec:
814 containers:
815 - image: nginx:1.7.9
816 name: nginx-tagged
817 - image: nginx:1.8.0
818 name: postgresdb
819 ---
820 apiVersion: v1
821 kind: Deployment
822 metadata:
823 name: deploy2
824 spec:
825 template:
826 spec:
827 containers:
828 - image: nginx:1.7.9
829 name: nginx-tagged
830 - image: postgres:1.8.0
831 name: postgresdb
832 `,
833 },
834 "partial string replacement - prefix": {
835 input: `apiVersion: v1
836 kind: Pod
837 metadata:
838 name: pod1
839 spec:
840 volumes:
841 - projected:
842 sources:
843 - configMap:
844 name: myconfigmap
845 items:
846 - key: config
847 path: my/group
848 ---
849 apiVersion: v1
850 kind: Pod
851 metadata:
852 name: pod2
853 spec:
854 volumes:
855 - projected:
856 sources:
857 - configMap:
858 name: myconfigmap
859 items:
860 - key: config
861 path: group/config
862 `,
863 replacements: `replacements:
864 - source:
865 kind: Pod
866 name: pod1
867 fieldPath: spec.volumes.0.projected.sources.0.configMap.items.0.path
868 options:
869 delimiter: '/'
870 index: 0
871 targets:
872 - select:
873 kind: Pod
874 name: pod2
875 fieldPaths:
876 - spec.volumes.0.projected.sources.0.configMap.items.0.path
877 options:
878 delimiter: '/'
879 index: -1
880 `,
881 expected: `apiVersion: v1
882 kind: Pod
883 metadata:
884 name: pod1
885 spec:
886 volumes:
887 - projected:
888 sources:
889 - configMap:
890 name: myconfigmap
891 items:
892 - key: config
893 path: my/group
894 ---
895 apiVersion: v1
896 kind: Pod
897 metadata:
898 name: pod2
899 spec:
900 volumes:
901 - projected:
902 sources:
903 - configMap:
904 name: myconfigmap
905 items:
906 - key: config
907 path: my/group/config
908 `,
909 },
910 "partial string replacement - suffix": {
911 input: `apiVersion: v1
912 kind: Pod
913 metadata:
914 name: pod1
915 spec:
916 volumes:
917 - projected:
918 sources:
919 - configMap:
920 name: myconfigmap
921 items:
922 - key: config
923 path: my/group
924 ---
925 apiVersion: v1
926 kind: Pod
927 metadata:
928 name: pod2
929 spec:
930 volumes:
931 - projected:
932 sources:
933 - configMap:
934 name: myconfigmap
935 items:
936 - key: config
937 path: group/config
938 `,
939 replacements: `replacements:
940 - source:
941 kind: Pod
942 name: pod2
943 fieldPath: spec.volumes.0.projected.sources.0.configMap.items.0.path
944 options:
945 delimiter: '/'
946 index: 1
947 targets:
948 - select:
949 kind: Pod
950 name: pod1
951 fieldPaths:
952 - spec.volumes.0.projected.sources.0.configMap.items.0.path
953 options:
954 delimiter: '/'
955 index: 2
956 `,
957 expected: `apiVersion: v1
958 kind: Pod
959 metadata:
960 name: pod1
961 spec:
962 volumes:
963 - projected:
964 sources:
965 - configMap:
966 name: myconfigmap
967 items:
968 - key: config
969 path: my/group/config
970 ---
971 apiVersion: v1
972 kind: Pod
973 metadata:
974 name: pod2
975 spec:
976 volumes:
977 - projected:
978 sources:
979 - configMap:
980 name: myconfigmap
981 items:
982 - key: config
983 path: group/config
984 `,
985 },
986 "partial string replacement - last element": {
987 input: `apiVersion: v1
988 kind: Pod
989 metadata:
990 name: pod1
991 spec:
992 volumes:
993 - projected:
994 sources:
995 - configMap:
996 name: myconfigmap
997 items:
998 - key: config
999 path: my/group1
1000 ---
1001 apiVersion: v1
1002 kind: Pod
1003 metadata:
1004 name: pod2
1005 spec:
1006 volumes:
1007 - projected:
1008 sources:
1009 - configMap:
1010 name: myconfigmap
1011 items:
1012 - key: config
1013 path: group2
1014 `,
1015 replacements: `replacements:
1016 - source:
1017 kind: Pod
1018 name: pod2
1019 fieldPath: spec.volumes.0.projected.sources.0.configMap.items.0.path
1020 options:
1021 delimiter: '/'
1022 index: 0
1023 targets:
1024 - select:
1025 kind: Pod
1026 name: pod1
1027 fieldPaths:
1028 - spec.volumes.0.projected.sources.0.configMap.items.0.path
1029 options:
1030 delimiter: '/'
1031 index: 1
1032 `,
1033 expected: `apiVersion: v1
1034 kind: Pod
1035 metadata:
1036 name: pod1
1037 spec:
1038 volumes:
1039 - projected:
1040 sources:
1041 - configMap:
1042 name: myconfigmap
1043 items:
1044 - key: config
1045 path: my/group2
1046 ---
1047 apiVersion: v1
1048 kind: Pod
1049 metadata:
1050 name: pod2
1051 spec:
1052 volumes:
1053 - projected:
1054 sources:
1055 - configMap:
1056 name: myconfigmap
1057 items:
1058 - key: config
1059 path: group2
1060 `,
1061 },
1062 "partial string replacement - first element": {
1063 input: `apiVersion: v1
1064 kind: Pod
1065 metadata:
1066 name: pod1
1067 spec:
1068 volumes:
1069 - projected:
1070 sources:
1071 - configMap:
1072 name: myconfigmap
1073 items:
1074 - key: config
1075 path: group1/config
1076 ---
1077 apiVersion: v1
1078 kind: Pod
1079 metadata:
1080 name: pod2
1081 spec:
1082 volumes:
1083 - projected:
1084 sources:
1085 - configMap:
1086 name: myconfigmap
1087 items:
1088 - key: config
1089 path: group2
1090 `,
1091 replacements: `replacements:
1092 - source:
1093 kind: Pod
1094 name: pod2
1095 fieldPath: spec.volumes.0.projected.sources.0.configMap.items.0.path
1096 options:
1097 delimiter: '/'
1098 index: 0
1099 targets:
1100 - select:
1101 kind: Pod
1102 name: pod1
1103 fieldPaths:
1104 - spec.volumes.0.projected.sources.0.configMap.items.0.path
1105 options:
1106 delimiter: '/'
1107 index: 0
1108 `,
1109 expected: `apiVersion: v1
1110 kind: Pod
1111 metadata:
1112 name: pod1
1113 spec:
1114 volumes:
1115 - projected:
1116 sources:
1117 - configMap:
1118 name: myconfigmap
1119 items:
1120 - key: config
1121 path: group2/config
1122 ---
1123 apiVersion: v1
1124 kind: Pod
1125 metadata:
1126 name: pod2
1127 spec:
1128 volumes:
1129 - projected:
1130 sources:
1131 - configMap:
1132 name: myconfigmap
1133 items:
1134 - key: config
1135 path: group2
1136 `,
1137 },
1138 "options.index out of bounds": {
1139 input: `apiVersion: v1
1140 kind: Pod
1141 metadata:
1142 name: pod1
1143 spec:
1144 volumes:
1145 - projected:
1146 sources:
1147 - configMap:
1148 name: myconfigmap
1149 items:
1150 - key: config
1151 path: my/group1
1152 ---
1153 apiVersion: v1
1154 kind: Pod
1155 metadata:
1156 name: pod2
1157 spec:
1158 volumes:
1159 - projected:
1160 sources:
1161 - configMap:
1162 name: myconfigmap
1163 items:
1164 - key: config
1165 path: group2
1166 `,
1167 replacements: `replacements:
1168 - source:
1169 kind: Pod
1170 name: pod2
1171 fieldPath: spec.volumes.0.projected.sources.0.configMap.items.0.path
1172 options:
1173 delimiter: '/'
1174 index: -1
1175 targets:
1176 - select:
1177 kind: Pod
1178 name: pod1
1179 fieldPaths:
1180 - spec.volumes.0.projected.sources.0.configMap.items.0.path
1181 options:
1182 delimiter: '/'
1183 index: 1
1184 `,
1185 expectedErr: "options.index -1 is out of bounds for value group2",
1186 },
1187 "create": {
1188 input: `apiVersion: v1
1189 kind: Pod
1190 metadata:
1191 name: pod
1192 spec:
1193 containers:
1194 - image: busybox
1195 name: myapp-container
1196 ---
1197 apiVersion: apps/v1
1198 kind: Deployment
1199 metadata:
1200 name: deploy1
1201 `,
1202 replacements: `replacements:
1203 - source:
1204 kind: Pod
1205 name: pod
1206 fieldPath: spec.containers
1207 targets:
1208 - select:
1209 name: deploy1
1210 fieldPaths:
1211 - spec.template.spec.containers
1212 options:
1213 create: true
1214 `,
1215 expected: `apiVersion: v1
1216 kind: Pod
1217 metadata:
1218 name: pod
1219 spec:
1220 containers:
1221 - image: busybox
1222 name: myapp-container
1223 ---
1224 apiVersion: apps/v1
1225 kind: Deployment
1226 metadata:
1227 name: deploy1
1228 spec:
1229 template:
1230 spec:
1231 containers:
1232 - image: busybox
1233 name: myapp-container
1234 `,
1235 },
1236 "complex type with delimiter in source": {
1237 input: `apiVersion: v1
1238 kind: Pod
1239 metadata:
1240 name: pod
1241 spec:
1242 containers:
1243 - image: busybox
1244 name: myapp-container
1245 ---
1246 apiVersion: apps/v1
1247 kind: Deployment
1248 metadata:
1249 name: deploy2
1250 spec:
1251 template:
1252 spec:
1253 containers: {}
1254 ---
1255 apiVersion: apps/v1
1256 kind: Deployment
1257 metadata:
1258 name: deploy3
1259 spec:
1260 template:
1261 spec:
1262 containers: {}
1263 `,
1264 replacements: `replacements:
1265 - source:
1266 kind: Pod
1267 name: pod
1268 fieldPath: spec.containers
1269 options:
1270 delimiter: "/"
1271 targets:
1272 - select:
1273 kind: Deployment
1274 fieldPaths:
1275 - spec.template.spec.containers
1276 `,
1277 expectedErr: "delimiter option can only be used with scalar nodes",
1278 },
1279 "complex type with delimiter in target": {
1280 input: `apiVersion: v1
1281 kind: Pod
1282 metadata:
1283 name: pod
1284 spec:
1285 containers:
1286 - image: busybox
1287 name: myapp-container
1288 ---
1289 apiVersion: apps/v1
1290 kind: Deployment
1291 metadata:
1292 name: deploy2
1293 spec:
1294 template:
1295 spec:
1296 containers: {}
1297 ---
1298 apiVersion: apps/v1
1299 kind: Deployment
1300 metadata:
1301 name: deploy3
1302 spec:
1303 template:
1304 spec:
1305 containers: {}
1306 `,
1307 replacements: `replacements:
1308 - source:
1309 kind: Pod
1310 name: pod
1311 fieldPath: spec.containers
1312 targets:
1313 - select:
1314 kind: Deployment
1315 fieldPaths:
1316 - spec.template.spec.containers
1317 options:
1318 delimiter: "/"
1319 `,
1320 expectedErr: "delimiter option can only be used with scalar nodes",
1321 },
1322 "mapping value contains '.' character": {
1323 input: `apiVersion: v1
1324 kind: Custom
1325 metadata:
1326 name: custom
1327 annotations:
1328 a.b.c/d-e: source
1329 f.g.h/i-j: target
1330 `,
1331 replacements: `replacements:
1332 - source:
1333 name: custom
1334 fieldPath: metadata.annotations.[a.b.c/d-e]
1335 targets:
1336 - select:
1337 name: custom
1338 fieldPaths:
1339 - metadata.annotations.[f.g.h/i-j]
1340 `,
1341 expected: `apiVersion: v1
1342 kind: Custom
1343 metadata:
1344 name: custom
1345 annotations:
1346 a.b.c/d-e: source
1347 f.g.h/i-j: source
1348 `,
1349 },
1350 "list index contains '.' character": {
1351 input: `apiVersion: v1
1352 kind: ConfigMap
1353 metadata:
1354 name: source
1355 data:
1356 value: example
1357 ---
1358 apiVersion: kubernetes-client.io/v1
1359 kind: ExternalSecret
1360 metadata:
1361 name: some-secret
1362 spec:
1363 backendType: secretsManager
1364 data:
1365 - key: some-prefix-replaceme
1366 name: .first
1367 version: latest
1368 property: first
1369 - key: some-prefix-replaceme
1370 name: second
1371 version: latest
1372 property: second
1373 `,
1374 replacements: `replacements:
1375 - source:
1376 kind: ConfigMap
1377 version: v1
1378 name: source
1379 fieldPath: data.value
1380 targets:
1381 - select:
1382 group: kubernetes-client.io
1383 version: v1
1384 kind: ExternalSecret
1385 name: some-secret
1386 fieldPaths:
1387 - spec.data.[name=.first].key
1388 - spec.data.[name=second].key
1389 options:
1390 delimiter: "-"
1391 index: 2
1392 `,
1393 expected: `apiVersion: v1
1394 kind: ConfigMap
1395 metadata:
1396 name: source
1397 data:
1398 value: example
1399 ---
1400 apiVersion: kubernetes-client.io/v1
1401 kind: ExternalSecret
1402 metadata:
1403 name: some-secret
1404 spec:
1405 backendType: secretsManager
1406 data:
1407 - key: some-prefix-example
1408 name: .first
1409 version: latest
1410 property: first
1411 - key: some-prefix-example
1412 name: second
1413 version: latest
1414 property: second`,
1415 },
1416 "one replacements target has multiple value": {
1417 input: `apiVersion: apps/v1
1418 kind: Deployment
1419 metadata:
1420 labels:
1421 app: sample-deploy
1422 name: sample-deploy
1423 spec:
1424 replicas: 1
1425 selector:
1426 matchLabels:
1427 app: sample-deploy
1428 template:
1429 metadata:
1430 labels:
1431 app: sample-deploy
1432 spec:
1433 containers:
1434 - image: nginx
1435 name: main
1436 env:
1437 - name: deployment-name
1438 value: XXXXX
1439 - name: foo
1440 value: bar
1441 - image: nginx
1442 name: sidecar
1443 env:
1444 - name: deployment-name
1445 value: YYYYY
1446 `,
1447 replacements: `replacements:
1448 - source:
1449 kind: Deployment
1450 name: sample-deploy
1451 fieldPath: metadata.name
1452 targets:
1453 - select:
1454 kind: Deployment
1455 fieldPaths:
1456 - spec.template.spec.containers.[image=nginx].env.[name=deployment-name].value
1457 `,
1458 expected: `apiVersion: apps/v1
1459 kind: Deployment
1460 metadata:
1461 labels:
1462 app: sample-deploy
1463 name: sample-deploy
1464 spec:
1465 replicas: 1
1466 selector:
1467 matchLabels:
1468 app: sample-deploy
1469 template:
1470 metadata:
1471 labels:
1472 app: sample-deploy
1473 spec:
1474 containers:
1475 - image: nginx
1476 name: main
1477 env:
1478 - name: deployment-name
1479 value: sample-deploy
1480 - name: foo
1481 value: bar
1482 - image: nginx
1483 name: sidecar
1484 env:
1485 - name: deployment-name
1486 value: sample-deploy`,
1487 },
1488 "one replacements target should create multiple values": {
1489 input: `apiVersion: apps/v1
1490 kind: Deployment
1491 metadata:
1492 labels:
1493 app: sample-deploy
1494 name: sample-deploy
1495 spec:
1496 replicas: 1
1497 selector:
1498 matchLabels:
1499 app: sample-deploy
1500 template:
1501 metadata:
1502 labels:
1503 app: sample-deploy
1504 spec:
1505 containers:
1506 - image: other
1507 name: do-not-modify-me
1508 env:
1509 - name: foo
1510 value: bar
1511 - image: nginx
1512 name: main
1513 env:
1514 - name: foo
1515 value: bar
1516 - image: nginx
1517 name: sidecar
1518 `,
1519 replacements: `replacements:
1520 - source:
1521 kind: Deployment
1522 name: sample-deploy
1523 fieldPath: metadata.name
1524 targets:
1525 - select:
1526 kind: Deployment
1527 options:
1528 create: true
1529 fieldPaths:
1530 - spec.template.spec.containers.[image=nginx].env.[name=deployment-name].value
1531 `,
1532 expected: `apiVersion: apps/v1
1533 kind: Deployment
1534 metadata:
1535 labels:
1536 app: sample-deploy
1537 name: sample-deploy
1538 spec:
1539 replicas: 1
1540 selector:
1541 matchLabels:
1542 app: sample-deploy
1543 template:
1544 metadata:
1545 labels:
1546 app: sample-deploy
1547 spec:
1548 containers:
1549 - image: other
1550 name: do-not-modify-me
1551 env:
1552 - name: foo
1553 value: bar
1554 - image: nginx
1555 name: main
1556 env:
1557 - name: foo
1558 value: bar
1559 - name: deployment-name
1560 value: sample-deploy
1561 - image: nginx
1562 name: sidecar
1563 env:
1564 - name: deployment-name
1565 value: sample-deploy`,
1566 },
1567 "index contains '*' character": {
1568 input: `apiVersion: apps/v1
1569 kind: Deployment
1570 metadata:
1571 labels:
1572 app: sample-deploy
1573 name: sample-deploy
1574 spec:
1575 replicas: 1
1576 selector:
1577 matchLabels:
1578 app: sample-deploy
1579 template:
1580 metadata:
1581 labels:
1582 app: sample-deploy
1583 spec:
1584 containers:
1585 - image: nginx
1586 name: main
1587 env:
1588 - name: deployment-name
1589 value: XXXXX
1590 `,
1591 replacements: `replacements:
1592 - source:
1593 kind: Deployment
1594 name: sample-deploy
1595 fieldPath: metadata.name
1596 targets:
1597 - select:
1598 kind: Deployment
1599 fieldPaths:
1600 - spec.template.spec.containers.*.env.[name=deployment-name].value
1601 `,
1602 expected: `apiVersion: apps/v1
1603 kind: Deployment
1604 metadata:
1605 labels:
1606 app: sample-deploy
1607 name: sample-deploy
1608 spec:
1609 replicas: 1
1610 selector:
1611 matchLabels:
1612 app: sample-deploy
1613 template:
1614 metadata:
1615 labels:
1616 app: sample-deploy
1617 spec:
1618 containers:
1619 - image: nginx
1620 name: main
1621 env:
1622 - name: deployment-name
1623 value: sample-deploy`,
1624 },
1625 "list index contains '*' character": {
1626 input: `apiVersion: apps/v1
1627 kind: Deployment
1628 metadata:
1629 labels:
1630 app: sample-deploy
1631 name: sample-deploy
1632 spec:
1633 replicas: 1
1634 selector:
1635 matchLabels:
1636 app: sample-deploy
1637 template:
1638 metadata:
1639 labels:
1640 app: sample-deploy
1641 spec:
1642 containers:
1643 - image: nginx
1644 name: main
1645 env:
1646 - name: deployment-name
1647 value: XXXXX
1648 - name: foo
1649 value: bar
1650 - image: nginx
1651 name: sidecar
1652 env:
1653 - name: deployment-name
1654 value: YYYYY
1655 `,
1656 replacements: `replacements:
1657 - source:
1658 kind: Deployment
1659 name: sample-deploy
1660 fieldPath: metadata.name
1661 targets:
1662 - select:
1663 kind: Deployment
1664 fieldPaths:
1665 - spec.template.spec.containers.*.env.[name=deployment-name].value
1666 `,
1667 expected: `apiVersion: apps/v1
1668 kind: Deployment
1669 metadata:
1670 labels:
1671 app: sample-deploy
1672 name: sample-deploy
1673 spec:
1674 replicas: 1
1675 selector:
1676 matchLabels:
1677 app: sample-deploy
1678 template:
1679 metadata:
1680 labels:
1681 app: sample-deploy
1682 spec:
1683 containers:
1684 - image: nginx
1685 name: main
1686 env:
1687 - name: deployment-name
1688 value: sample-deploy
1689 - name: foo
1690 value: bar
1691 - image: nginx
1692 name: sidecar
1693 env:
1694 - name: deployment-name
1695 value: sample-deploy`,
1696 },
1697 "index contains '*' character and create options": {
1698 input: `apiVersion: apps/v1
1699 kind: Deployment
1700 metadata:
1701 labels:
1702 app: sample-deploy
1703 name: sample-deploy
1704 spec:
1705 replicas: 1
1706 selector:
1707 matchLabels:
1708 app: sample-deploy
1709 template:
1710 metadata:
1711 labels:
1712 app: sample-deploy
1713 spec:
1714 containers:
1715 - image: nginx
1716 name: main
1717 env:
1718 - name: other-env
1719 value: YYYYY
1720 `,
1721 replacements: `replacements:
1722 - source:
1723 kind: Deployment
1724 name: sample-deploy
1725 fieldPath: metadata.name
1726 targets:
1727 - select:
1728 kind: Deployment
1729 fieldPaths:
1730 - spec.template.spec.containers.*.env.[name=deployment-name].value
1731 options:
1732 create: true
1733 `,
1734 expected: `apiVersion: apps/v1
1735 kind: Deployment
1736 metadata:
1737 labels:
1738 app: sample-deploy
1739 name: sample-deploy
1740 spec:
1741 replicas: 1
1742 selector:
1743 matchLabels:
1744 app: sample-deploy
1745 template:
1746 metadata:
1747 labels:
1748 app: sample-deploy
1749 spec:
1750 containers:
1751 - image: nginx
1752 name: main
1753 env:
1754 - name: other-env
1755 value: YYYYY
1756 - name: deployment-name
1757 value: sample-deploy
1758 `,
1759 },
1760 "Issue 1493: wildcard to create or replace field in all containers in all workloads": {
1761 input: `apiVersion: v1
1762 kind: ConfigMap
1763 metadata:
1764 name: policy
1765 data:
1766 restart: OnFailure
1767 ---
1768 apiVersion: v1
1769 kind: Pod
1770 metadata:
1771 name: pod1
1772 spec:
1773 containers:
1774 - image: nginx
1775 name: main
1776 - image: nginx
1777 name: sidecar
1778 imagePullPolicy: Always
1779 ---
1780 apiVersion: v1
1781 kind: Pod
1782 metadata:
1783 name: pod2
1784 spec:
1785 containers:
1786 - image: nginx
1787 name: main
1788 imagePullPolicy: Always
1789 - image: nginx
1790 name: sidecar
1791 `,
1792 replacements: `replacements:
1793 - source:
1794 kind: ConfigMap
1795 name: policy
1796 fieldPath: data.restart
1797 targets:
1798 - select:
1799 kind: Pod
1800 fieldPaths:
1801 - spec.containers.*.imagePullPolicy
1802 options:
1803 create: true
1804 `,
1805 expected: `apiVersion: v1
1806 kind: ConfigMap
1807 metadata:
1808 name: policy
1809 data:
1810 restart: OnFailure
1811 ---
1812 apiVersion: v1
1813 kind: Pod
1814 metadata:
1815 name: pod1
1816 spec:
1817 containers:
1818 - image: nginx
1819 name: main
1820 imagePullPolicy: OnFailure
1821 - image: nginx
1822 name: sidecar
1823 imagePullPolicy: OnFailure
1824 ---
1825 apiVersion: v1
1826 kind: Pod
1827 metadata:
1828 name: pod2
1829 spec:
1830 containers:
1831 - image: nginx
1832 name: main
1833 imagePullPolicy: OnFailure
1834 - image: nginx
1835 name: sidecar
1836 imagePullPolicy: OnFailure
1837 `,
1838 },
1839 "multiple field paths in target": {
1840 input: `apiVersion: v1
1841 kind: ConfigMap
1842 metadata:
1843 name: source
1844 data:
1845 value: example
1846 ---
1847 apiVersion: kubernetes-client.io/v1
1848 kind: ExternalSecret
1849 metadata:
1850 name: some-secret
1851 spec:
1852 backendType: secretsManager
1853 data:
1854 - key: some-prefix-replaceme
1855 name: first
1856 version: latest
1857 property: first
1858 - key: some-prefix-replaceme
1859 name: second
1860 version: latest
1861 property: second
1862 - key: some-prefix-replaceme
1863 name: third
1864 version: latest
1865 property: third
1866 `,
1867 replacements: `replacements:
1868 - source:
1869 kind: ConfigMap
1870 version: v1
1871 name: source
1872 fieldPath: data.value
1873 targets:
1874 - select:
1875 group: kubernetes-client.io
1876 version: v1
1877 kind: ExternalSecret
1878 name: some-secret
1879 fieldPaths:
1880 - spec.data.0.key
1881 - spec.data.1.key
1882 - spec.data.2.key
1883 options:
1884 delimiter: "-"
1885 index: 2
1886 `,
1887 expected: `apiVersion: v1
1888 kind: ConfigMap
1889 metadata:
1890 name: source
1891 data:
1892 value: example
1893 ---
1894 apiVersion: kubernetes-client.io/v1
1895 kind: ExternalSecret
1896 metadata:
1897 name: some-secret
1898 spec:
1899 backendType: secretsManager
1900 data:
1901 - key: some-prefix-example
1902 name: first
1903 version: latest
1904 property: first
1905 - key: some-prefix-example
1906 name: second
1907 version: latest
1908 property: second
1909 - key: some-prefix-example
1910 name: third
1911 version: latest
1912 property: third
1913 `,
1914 },
1915 "using a previous ID": {
1916 input: `apiVersion: v1
1917 kind: Deployment
1918 metadata:
1919 name: pre-deploy
1920 annotations:
1921 internal.config.kubernetes.io/previousNames: deploy,deploy
1922 internal.config.kubernetes.io/previousKinds: CronJob,Deployment
1923 internal.config.kubernetes.io/previousNamespaces: default,default
1924 spec:
1925 template:
1926 spec:
1927 containers:
1928 - image: nginx:1.7.9
1929 name: nginx-tagged
1930 - image: postgres:1.8.0
1931 name: postgresdb
1932 `,
1933 replacements: `replacements:
1934 - source:
1935 kind: CronJob
1936 name: deploy
1937 fieldPath: spec.template.spec.containers.0.image
1938 targets:
1939 - select:
1940 kind: Deployment
1941 name: deploy
1942 fieldPaths:
1943 - spec.template.spec.containers.1.image
1944 `,
1945 expected: `apiVersion: v1
1946 kind: Deployment
1947 metadata:
1948 name: pre-deploy
1949 annotations:
1950 internal.config.kubernetes.io/previousNames: deploy,deploy
1951 internal.config.kubernetes.io/previousKinds: CronJob,Deployment
1952 internal.config.kubernetes.io/previousNamespaces: default,default
1953 spec:
1954 template:
1955 spec:
1956 containers:
1957 - image: nginx:1.7.9
1958 name: nginx-tagged
1959 - image: nginx:1.7.9
1960 name: postgresdb
1961 `,
1962 },
1963 "replacement source.fieldPath does not exist": {
1964 input: `apiVersion: v1
1965 kind: ConfigMap
1966 metadata:
1967 name: ports-from
1968 data:
1969 grpcPort: 8080
1970 ---
1971 apiVersion: v1
1972 kind: ConfigMap
1973 metadata:
1974 name: ports-to
1975 data:
1976 grpcPort: 8081
1977 `,
1978 replacements: `replacements:
1979 - source:
1980 kind: ConfigMap
1981 name: ports-from
1982 fieldPath: data.httpPort
1983 targets:
1984 - select:
1985 kind: ConfigMap
1986 name: ports-to
1987 fieldPaths:
1988 - data.grpcPort
1989 options:
1990 create: true
1991 `,
1992 expectedErr: "fieldPath `data.httpPort` is missing for replacement source ConfigMap.[noVer].[noGrp]/ports-from.[noNs]",
1993 },
1994 "annotationSelector": {
1995 input: `apiVersion: v1
1996 kind: Deployment
1997 metadata:
1998 name: deploy-1
1999 annotations:
2000 foo: bar-1
2001 spec:
2002 template:
2003 spec:
2004 containers:
2005 - image: nginx:1.7.9
2006 name: nginx-tagged
2007 - image: postgres:1.8.0
2008 name: postgresdb
2009 ---
2010 apiVersion: v1
2011 kind: Deployment
2012 metadata:
2013 name: deploy-2
2014 annotations:
2015 foo: bar-2
2016 spec:
2017 template:
2018 spec:
2019 containers:
2020 - image: nginx:1.7.9
2021 name: nginx-tagged
2022 - image: postgres:1.8.0
2023 name: postgresdb
2024
2025 `,
2026 replacements: `replacements:
2027 - source:
2028 kind: Deployment
2029 name: deploy-1
2030 fieldPath: spec.template.spec.containers.0.image
2031 targets:
2032 - select:
2033 annotationSelector: foo=bar-1
2034 fieldPaths:
2035 - spec.template.spec.containers.1.image
2036 `,
2037 expected: `apiVersion: v1
2038 kind: Deployment
2039 metadata:
2040 name: deploy-1
2041 annotations:
2042 foo: bar-1
2043 spec:
2044 template:
2045 spec:
2046 containers:
2047 - image: nginx:1.7.9
2048 name: nginx-tagged
2049 - image: nginx:1.7.9
2050 name: postgresdb
2051 ---
2052 apiVersion: v1
2053 kind: Deployment
2054 metadata:
2055 name: deploy-2
2056 annotations:
2057 foo: bar-2
2058 spec:
2059 template:
2060 spec:
2061 containers:
2062 - image: nginx:1.7.9
2063 name: nginx-tagged
2064 - image: postgres:1.8.0
2065 name: postgresdb
2066 `,
2067 },
2068 "labelSelector": {
2069 input: `apiVersion: v1
2070 kind: Deployment
2071 metadata:
2072 name: deploy-1
2073 labels:
2074 foo: bar-1
2075 spec:
2076 template:
2077 spec:
2078 containers:
2079 - image: nginx:1.7.9
2080 name: nginx-tagged
2081 - image: postgres:1.8.0
2082 name: postgresdb
2083 ---
2084 apiVersion: v1
2085 kind: Deployment
2086 metadata:
2087 name: deploy-2
2088 labels:
2089 foo: bar-2
2090 spec:
2091 template:
2092 spec:
2093 containers:
2094 - image: nginx:1.7.9
2095 name: nginx-tagged
2096 - image: postgres:1.8.0
2097 name: postgresdb
2098
2099 `,
2100 replacements: `replacements:
2101 - source:
2102 kind: Deployment
2103 name: deploy-1
2104 fieldPath: spec.template.spec.containers.0.image
2105 targets:
2106 - select:
2107 labelSelector: foo=bar-1
2108 fieldPaths:
2109 - spec.template.spec.containers.1.image
2110 `,
2111 expected: `apiVersion: v1
2112 kind: Deployment
2113 metadata:
2114 name: deploy-1
2115 labels:
2116 foo: bar-1
2117 spec:
2118 template:
2119 spec:
2120 containers:
2121 - image: nginx:1.7.9
2122 name: nginx-tagged
2123 - image: nginx:1.7.9
2124 name: postgresdb
2125 ---
2126 apiVersion: v1
2127 kind: Deployment
2128 metadata:
2129 name: deploy-2
2130 labels:
2131 foo: bar-2
2132 spec:
2133 template:
2134 spec:
2135 containers:
2136 - image: nginx:1.7.9
2137 name: nginx-tagged
2138 - image: postgres:1.8.0
2139 name: postgresdb
2140 `,
2141 },
2142 "reject via labelSelector": {
2143 input: `apiVersion: v1
2144 kind: Deployment
2145 metadata:
2146 name: deploy-1
2147 labels:
2148 foo: bar-1
2149 spec:
2150 template:
2151 spec:
2152 containers:
2153 - image: nginx:1.7.9
2154 name: nginx-tagged
2155 - image: postgres:1.8.0
2156 name: postgresdb
2157 ---
2158 apiVersion: v1
2159 kind: Deployment
2160 metadata:
2161 name: deploy-2
2162 labels:
2163 foo: bar-2
2164 spec:
2165 template:
2166 spec:
2167 containers:
2168 - image: nginx:1.7.9
2169 name: nginx-tagged
2170 - image: postgres:1.8.0
2171 name: postgresdb
2172
2173 `,
2174 replacements: `replacements:
2175 - source:
2176 kind: Deployment
2177 name: deploy-1
2178 fieldPath: spec.template.spec.containers.0.image
2179 targets:
2180 - select:
2181 kind: Deployment
2182 reject:
2183 - labelSelector: foo=bar-2
2184 fieldPaths:
2185 - spec.template.spec.containers.1.image
2186 `,
2187 expected: `apiVersion: v1
2188 kind: Deployment
2189 metadata:
2190 name: deploy-1
2191 labels:
2192 foo: bar-1
2193 spec:
2194 template:
2195 spec:
2196 containers:
2197 - image: nginx:1.7.9
2198 name: nginx-tagged
2199 - image: nginx:1.7.9
2200 name: postgresdb
2201 ---
2202 apiVersion: v1
2203 kind: Deployment
2204 metadata:
2205 name: deploy-2
2206 labels:
2207 foo: bar-2
2208 spec:
2209 template:
2210 spec:
2211 containers:
2212 - image: nginx:1.7.9
2213 name: nginx-tagged
2214 - image: postgres:1.8.0
2215 name: postgresdb
2216 `,
2217 },
2218 "string source -> integer target": {
2219 input: `apiVersion: v1
2220 kind: ConfigMap
2221 metadata:
2222 name: config
2223 data:
2224 PORT: "8080"
2225 ---
2226 apiVersion: apps/v1
2227 kind: Pod
2228 metadata:
2229 name: pod
2230 spec:
2231 containers:
2232 - image: busybox
2233 name: myapp-container
2234 ports:
2235 - containerPort: 80
2236 `,
2237 replacements: `replacements:
2238 - source:
2239 kind: ConfigMap
2240 name: config
2241 fieldPath: data.PORT
2242 targets:
2243 - select:
2244 kind: Pod
2245 fieldPaths:
2246 - spec.containers.0.ports.0.containerPort
2247 `,
2248 expected: `apiVersion: v1
2249 kind: ConfigMap
2250 metadata:
2251 name: config
2252 data:
2253 PORT: "8080"
2254 ---
2255 apiVersion: apps/v1
2256 kind: Pod
2257 metadata:
2258 name: pod
2259 spec:
2260 containers:
2261 - image: busybox
2262 name: myapp-container
2263 ports:
2264 - containerPort: 8080
2265 `,
2266 },
2267 "string source -> boolean target": {
2268 input: `apiVersion: v1
2269 kind: ConfigMap
2270 metadata:
2271 name: config
2272 data:
2273 MOUNT_TOKEN: "true"
2274 ---
2275 apiVersion: apps/v1
2276 kind: Pod
2277 metadata:
2278 name: pod
2279 spec:
2280 containers:
2281 - image: busybox
2282 name: myapp-container
2283 automountServiceAccountToken: false
2284 `,
2285 replacements: `replacements:
2286 - source:
2287 kind: ConfigMap
2288 name: config
2289 fieldPath: data.MOUNT_TOKEN
2290 targets:
2291 - select:
2292 kind: Pod
2293 fieldPaths:
2294 - spec.containers.0.automountServiceAccountToken
2295 `,
2296 expected: `apiVersion: v1
2297 kind: ConfigMap
2298 metadata:
2299 name: config
2300 data:
2301 MOUNT_TOKEN: "true"
2302 ---
2303 apiVersion: apps/v1
2304 kind: Pod
2305 metadata:
2306 name: pod
2307 spec:
2308 containers:
2309 - image: busybox
2310 name: myapp-container
2311 automountServiceAccountToken: true
2312 `,
2313 },
2314
2315
2316
2317 "numerical string source -> integer creation": {
2318 input: `apiVersion: v1
2319 kind: ConfigMap
2320 metadata:
2321 name: config
2322 data:
2323 PORT: "8080"
2324 ---
2325 apiVersion: apps/v1
2326 kind: Pod
2327 metadata:
2328 name: pod
2329 spec:
2330 containers:
2331 - image: busybox
2332 name: myapp-container
2333 ports:
2334 - protocol: TCP
2335 `,
2336 replacements: `replacements:
2337 - source:
2338 kind: ConfigMap
2339 name: config
2340 fieldPath: data.PORT
2341 targets:
2342 - select:
2343 kind: Pod
2344 fieldPaths:
2345 - spec.containers.0.ports.0.containerPort
2346 - spec.containers.0.ports.0.name
2347 options:
2348 create: true
2349 `,
2350 expected: `apiVersion: v1
2351 kind: ConfigMap
2352 metadata:
2353 name: config
2354 data:
2355 PORT: "8080"
2356 ---
2357 apiVersion: apps/v1
2358 kind: Pod
2359 metadata:
2360 name: pod
2361 spec:
2362 containers:
2363 - image: busybox
2364 name: myapp-container
2365 ports:
2366 - protocol: TCP
2367 containerPort: 8080
2368 name: 8080
2369 `,
2370 },
2371 "integer source -> string target": {
2372 input: `apiVersion: v1
2373 kind: ConfigMap
2374 metadata:
2375 name: config
2376 data:
2377 PORT: "8080"
2378 ---
2379 apiVersion: apps/v1
2380 kind: Pod
2381 metadata:
2382 name: pod
2383 spec:
2384 containers:
2385 - image: busybox
2386 name: myapp-container
2387 ports:
2388 - containerPort: 80
2389 `,
2390 replacements: `replacements:
2391 - source:
2392 kind: Pod
2393 name: pod
2394 fieldPath: spec.containers.0.ports.0.containerPort
2395 targets:
2396 - select:
2397 kind: ConfigMap
2398 fieldPaths:
2399 - data.PORT
2400 `,
2401 expected: `apiVersion: v1
2402 kind: ConfigMap
2403 metadata:
2404 name: config
2405 data:
2406 PORT: "80"
2407 ---
2408 apiVersion: apps/v1
2409 kind: Pod
2410 metadata:
2411 name: pod
2412 spec:
2413 containers:
2414 - image: busybox
2415 name: myapp-container
2416 ports:
2417 - containerPort: 80
2418 `,
2419 },
2420 "boolean source -> string target": {
2421 input: `apiVersion: v1
2422 kind: ConfigMap
2423 metadata:
2424 name: config
2425 data:
2426 MOUNT_TOKEN: "true"
2427 ---
2428 apiVersion: apps/v1
2429 kind: Pod
2430 metadata:
2431 name: pod
2432 spec:
2433 containers:
2434 - image: busybox
2435 name: myapp-container
2436 automountServiceAccountToken: false
2437 `,
2438 replacements: `replacements:
2439 - source:
2440 kind: Pod
2441 name: pod
2442 fieldPath: spec.containers.0.automountServiceAccountToken
2443 targets:
2444 - select:
2445 kind: ConfigMap
2446 fieldPaths:
2447 - data.MOUNT_TOKEN
2448 `,
2449 expected: `apiVersion: v1
2450 kind: ConfigMap
2451 metadata:
2452 name: config
2453 data:
2454 MOUNT_TOKEN: "false"
2455 ---
2456 apiVersion: apps/v1
2457 kind: Pod
2458 metadata:
2459 name: pod
2460 spec:
2461 containers:
2462 - image: busybox
2463 name: myapp-container
2464 automountServiceAccountToken: false
2465 `,
2466 },
2467
2468
2469
2470 "integer source -> integer creation": {
2471 input: `apiVersion: v1
2472 kind: ConfigMap
2473 metadata:
2474 name: config
2475 data:
2476 FOO: "Bar"
2477 ---
2478 apiVersion: apps/v1
2479 kind: Pod
2480 metadata:
2481 name: pod
2482 spec:
2483 containers:
2484 - image: busybox
2485 name: myapp-container
2486 ports:
2487 - containerPort: 80
2488 `,
2489 replacements: `replacements:
2490 - source:
2491 kind: Pod
2492 name: pod
2493 fieldPath: spec.containers.0.ports.0.containerPort
2494 targets:
2495 - select:
2496 kind: ConfigMap
2497 fieldPaths:
2498 - data.PORT
2499 options:
2500 create: true
2501 `,
2502 expected: `apiVersion: v1
2503 kind: ConfigMap
2504 metadata:
2505 name: config
2506 data:
2507 FOO: "Bar"
2508 PORT: 80
2509 ---
2510 apiVersion: apps/v1
2511 kind: Pod
2512 metadata:
2513 name: pod
2514 spec:
2515 containers:
2516 - image: busybox
2517 name: myapp-container
2518 ports:
2519 - containerPort: 80
2520 `,
2521 },
2522 "replace an existing mapping value": {
2523 input: `apiVersion: batch/v1
2524 kind: Job
2525 metadata:
2526 name: hello
2527 spec:
2528 template:
2529 spec:
2530 containers:
2531 - image: busybox
2532 name: myapp-container
2533 restartPolicy: old
2534 ---
2535 apiVersion: v1
2536 kind: Pod
2537 metadata:
2538 name: my-pod
2539 spec:
2540 containers:
2541 - image: busybox
2542 name: myapp-container
2543 restartPolicy: new
2544 `,
2545 replacements: `replacements:
2546 - source:
2547 kind: Pod
2548 name: my-pod
2549 fieldPath: spec
2550 targets:
2551 - select:
2552 name: hello
2553 kind: Job
2554 fieldPaths:
2555 - spec.template.spec
2556 options:
2557 create: true
2558 `,
2559 expected: `apiVersion: batch/v1
2560 kind: Job
2561 metadata:
2562 name: hello
2563 spec:
2564 template:
2565 spec:
2566 containers:
2567 - image: busybox
2568 name: myapp-container
2569 restartPolicy: new
2570 ---
2571 apiVersion: v1
2572 kind: Pod
2573 metadata:
2574 name: my-pod
2575 spec:
2576 containers:
2577 - image: busybox
2578 name: myapp-container
2579 restartPolicy: new
2580 `,
2581 },
2582 "issue4761 - path not in target with create: true": {
2583 input: `
2584 ---
2585 apiVersion: networking.istio.io/v1alpha3
2586 kind: EnvoyFilter
2587 metadata:
2588 name: request-id
2589 spec:
2590 configPatches:
2591 - applyTo: NETWORK_FILTER
2592 - applyTo: NETWORK_FILTER
2593 ---
2594 apiVersion: v1
2595 kind: ConfigMap
2596 metadata:
2597 name: istio-version
2598 annotations:
2599 config.kubernetes.io/local-config: true
2600 data:
2601 ISTIO_REGEX: '^1\.14.*'
2602 `,
2603 replacements: `
2604 replacements:
2605 - source:
2606 kind: ConfigMap
2607 name: istio-version
2608 fieldPath: data.ISTIO_REGEX
2609 targets:
2610 - select:
2611 kind: EnvoyFilter
2612 fieldPaths:
2613 - spec.configPatches.0.match.proxy.proxyVersion
2614 - spec.configPatches.1.match.proxy.proxyVersion
2615 - spec.configPatches.2.match.proxy.proxyVersion
2616 - spec.configPatches.3.match.proxy.proxyVersion
2617 options:
2618 create: true
2619 `,
2620 expected: `
2621 apiVersion: networking.istio.io/v1alpha3
2622 kind: EnvoyFilter
2623 metadata:
2624 name: request-id
2625 spec:
2626 configPatches:
2627 - applyTo: NETWORK_FILTER
2628 match:
2629 proxy:
2630 proxyVersion: ^1\.14.*
2631 - applyTo: NETWORK_FILTER
2632 match:
2633 proxy:
2634 proxyVersion: ^1\.14.*
2635 - match:
2636 proxy:
2637 proxyVersion: ^1\.14.*
2638 - match:
2639 proxy:
2640 proxyVersion: ^1\.14.*
2641 ---
2642 apiVersion: v1
2643 kind: ConfigMap
2644 metadata:
2645 name: istio-version
2646 annotations:
2647 config.kubernetes.io/local-config: true
2648 data:
2649 ISTIO_REGEX: '^1\.14.*'
2650 `,
2651 },
2652 "issue4761 - path not in target with create: false": {
2653 input: `
2654 ---
2655 apiVersion: networking.istio.io/v1alpha3
2656 kind: EnvoyFilter
2657 metadata:
2658 name: request-id
2659 spec:
2660 configPatches:
2661 - applyTo: NETWORK_FILTER
2662 - applyTo: NETWORK_FILTER
2663 ---
2664 apiVersion: v1
2665 kind: ConfigMap
2666 metadata:
2667 name: istio-version
2668 annotations:
2669 config.kubernetes.io/local-config: true
2670 data:
2671 ISTIO_REGEX: '^1\.14.*'
2672 `,
2673 replacements: `
2674 replacements:
2675 - source:
2676 kind: ConfigMap
2677 name: istio-version
2678 fieldPath: data.ISTIO_REGEX
2679 targets:
2680 - select:
2681 kind: EnvoyFilter
2682 fieldPaths:
2683 - spec.configPatches.0.match.proxy.proxyVersion
2684 - spec.configPatches.1.match.proxy.proxyVersion
2685 - spec.configPatches.2.match.proxy.proxyVersion
2686 - spec.configPatches.3.match.proxy.proxyVersion
2687 options:
2688 create: false
2689 `,
2690 expectedErr: "unable to find field \"spec.configPatches.0.match.proxy.proxyVersion\" in replacement target",
2691 },
2692 "issue4761 - wildcard solution": {
2693 input: `
2694 ---
2695 apiVersion: networking.istio.io/v1alpha3
2696 kind: EnvoyFilter
2697 metadata:
2698 name: request-id
2699 spec:
2700 configPatches:
2701 - applyTo: NETWORK_FILTER
2702 - applyTo: NETWORK_FILTER
2703 ---
2704 apiVersion: v1
2705 kind: ConfigMap
2706 metadata:
2707 name: istio-version
2708 annotations:
2709 config.kubernetes.io/local-config: true
2710 data:
2711 ISTIO_REGEX: '^1\.14.*'
2712 `,
2713 replacements: `
2714 replacements:
2715 - source:
2716 kind: ConfigMap
2717 name: istio-version
2718 fieldPath: data.ISTIO_REGEX
2719 targets:
2720 - select:
2721 kind: EnvoyFilter
2722 fieldPaths:
2723 - spec.configPatches.*.match.proxy.proxyVersion
2724 options:
2725 create: true
2726 `,
2727 expected: `
2728 apiVersion: networking.istio.io/v1alpha3
2729 kind: EnvoyFilter
2730 metadata:
2731 name: request-id
2732 spec:
2733 configPatches:
2734 - applyTo: NETWORK_FILTER
2735 match:
2736 proxy:
2737 proxyVersion: ^1\.14.*
2738 - applyTo: NETWORK_FILTER
2739 match:
2740 proxy:
2741 proxyVersion: ^1\.14.*
2742 ---
2743 apiVersion: v1
2744 kind: ConfigMap
2745 metadata:
2746 name: istio-version
2747 annotations:
2748 config.kubernetes.io/local-config: true
2749 data:
2750 ISTIO_REGEX: '^1\.14.*'
2751 `,
2752 },
2753 "append to sequence using index": {
2754 input: `apiVersion: networking.k8s.io/v1
2755 kind: Ingress
2756 metadata:
2757 name: myingress
2758 spec:
2759 rules:
2760 - host: myingress.example.com
2761 http:
2762 paths:
2763 - path: /
2764 pathType: Prefix
2765 backend:
2766 service:
2767 name: my-svc
2768 port:
2769 number: 80
2770 `,
2771 replacements: `replacements:
2772 - source:
2773 kind: Ingress
2774 name: myingress
2775 fieldPath: spec.rules.0.host
2776 targets:
2777 - select:
2778 kind: Ingress
2779 name: myingress
2780 fieldPaths:
2781 - spec.tls.0.hosts.0
2782 - spec.tls.0.secretName
2783 options:
2784 create: true
2785 `,
2786 expected: `apiVersion: networking.k8s.io/v1
2787 kind: Ingress
2788 metadata:
2789 name: myingress
2790 spec:
2791 rules:
2792 - host: myingress.example.com
2793 http:
2794 paths:
2795 - path: /
2796 pathType: Prefix
2797 backend:
2798 service:
2799 name: my-svc
2800 port:
2801 number: 80
2802 tls:
2803 - hosts:
2804 - myingress.example.com
2805 secretName: myingress.example.com`,
2806 },
2807 "fail to append to sequence using a distant index": {
2808 input: `apiVersion: networking.k8s.io/v1
2809 kind: Ingress
2810 metadata:
2811 name: myingress
2812 spec:
2813 rules:
2814 - host: myingress.example.com
2815 `,
2816 replacements: `replacements:
2817 - source:
2818 kind: Ingress
2819 name: myingress
2820 fieldPath: spec.rules.0.host
2821 targets:
2822 - select:
2823 kind: Ingress
2824 name: myingress
2825 fieldPaths:
2826 - spec.tls.5.hosts.5
2827 - spec.tls.5.secretName
2828 options:
2829 create: true
2830 `,
2831 expectedErr: "unable to find or create field \"spec.tls.5.hosts.5\" in replacement target: index 5 specified but only 0 elements found",
2832 },
2833 }
2834
2835 for tn, tc := range testCases {
2836 t.Run(tn, func(t *testing.T) {
2837 f := Filter{}
2838 err := yaml.Unmarshal([]byte(tc.replacements), &f)
2839 if !assert.NoError(t, err) {
2840 t.FailNow()
2841 }
2842 actual, err := filtertest.RunFilterE(t, tc.input, f)
2843 if err != nil {
2844 if tc.expectedErr == "" {
2845 t.Errorf("unexpected error: %s\n", err.Error())
2846 t.FailNow()
2847 }
2848 if !assert.Contains(t, err.Error(), tc.expectedErr) {
2849 t.FailNow()
2850 }
2851 }
2852 if !assert.Equal(t, strings.TrimSpace(tc.expected), strings.TrimSpace(actual)) {
2853 t.FailNow()
2854 }
2855 })
2856 }
2857 }
2858
View as plain text