1
2
3
4 package krusty_test
5
6 import (
7 "testing"
8
9 kusttest_test "sigs.k8s.io/kustomize/api/testutils/kusttest"
10 )
11
12 func TestPatchesInOneFile(t *testing.T) {
13 th := kusttest_test.MakeHarness(t)
14 th.WriteK("base", `
15 resources:
16 - namespace.yaml
17 - deployment-controller-manager.yaml
18 - deployment-audit-manager.yaml
19 `)
20 th.WriteF("base/namespace.yaml", `
21 apiVersion: v1
22 kind: Namespace
23 metadata:
24 labels:
25 control-plane: controller-manager
26 admission.gatekeeper.sh/ignore: no-self-managing
27 name: system
28 `)
29 th.WriteF("base/deployment-controller-manager.yaml", `
30 apiVersion: apps/v1
31 kind: Deployment
32 metadata:
33 name: controller-manager
34 namespace: system
35 labels:
36 control-plane: controller-manager
37 gatekeeper.sh/operation: webhook
38 spec:
39 selector:
40 matchLabels:
41 control-plane: controller-manager
42 gatekeeper.sh/operation: webhook
43 replicas: 3
44 template:
45 metadata:
46 annotations:
47 container.seccomp.security.alpha.kubernetes.io/manager: runtime/default
48 labels:
49 control-plane: controller-manager
50 gatekeeper.sh/operation: webhook
51 spec:
52 containers:
53 - command:
54 - /manager
55 args:
56 - "--port=8443"
57 - "--logtostderr"
58 - "--exempt-namespace=gatekeeper-system"
59 - "--operation=webhook"
60 image: openpolicyagent/gatekeeper:v3.4.0
61 imagePullPolicy: Always
62 name: manager
63 terminationGracePeriodSeconds: 60
64 nodeSelector:
65 kubernetes.io/os: linux
66 priorityClassName: system-cluster-critical
67 `)
68 th.WriteF("base/deployment-audit-manager.yaml", `
69 apiVersion: apps/v1
70 kind: Deployment
71 metadata:
72 name: audit
73 namespace: system
74 labels:
75 control-plane: audit-controller
76 gatekeeper.sh/operation: audit
77 spec:
78 selector:
79 matchLabels:
80 control-plane: audit-controller
81 gatekeeper.sh/operation: audit
82 replicas: 1
83 template:
84 metadata:
85 labels:
86 control-plane: audit-controller
87 gatekeeper.sh/operation: audit
88 annotations:
89 container.seccomp.security.alpha.kubernetes.io/manager: runtime/default
90 spec:
91 automountServiceAccountToken: true
92 containers:
93 - args:
94 - --operation=audit
95 - --operation=status
96 - --logtostderr
97 command:
98 - /manager
99 env:
100 - name: POD_NAMESPACE
101 valueFrom:
102 fieldRef:
103 apiVersion: v1
104 fieldPath: metadata.namespace
105 - name: POD_NAME
106 valueFrom:
107 fieldRef:
108 fieldPath: metadata.name
109 image: openpolicyagent/gatekeeper:v3.4.0
110 imagePullPolicy: Always
111 livenessProbe:
112 httpGet:
113 path: /healthz
114 port: 9090
115 name: manager
116 serviceAccountName: gatekeeper-admin
117 terminationGracePeriodSeconds: 60
118 nodeSelector:
119 kubernetes.io/os: linux
120 priorityClassName: system-cluster-critical
121 `)
122 const imagePatchAuditManager = `
123 apiVersion: apps/v1
124 kind: Deployment
125 metadata:
126 name: audit
127 namespace: system
128 spec:
129 template:
130 spec:
131 containers:
132 - image: AUDIT_IMAGE
133 name: manager
134 args:
135 - --port=8443
136 - --logtostderr
137 - --emit-admission-events
138 - --exempt-namespace=gatekeeper-system
139 - --operation=webhook
140 - --disable-opa-builtin=http.send
141 `
142 const imagePatchControllerManager = `
143 apiVersion: apps/v1
144 kind: Deployment
145 metadata:
146 name: controller-manager
147 namespace: system
148 spec:
149 template:
150 spec:
151 containers:
152 - image: CONTROLLER_IMAGE
153 name: manager
154 args:
155 - --emit-audit-events
156 - --operation=audit
157 - --operation=status
158 - --logtostderr
159 `
160 th.WriteF(
161 "overlay/image_patch_audit_manager.yaml",
162 imagePatchAuditManager)
163 th.WriteF(
164 "overlay/image_patch_controller_manager.yaml",
165 imagePatchControllerManager)
166 const expected = `
167 apiVersion: v1
168 kind: Namespace
169 metadata:
170 labels:
171 admission.gatekeeper.sh/ignore: no-self-managing
172 control-plane: controller-manager
173 name: system
174 ---
175 apiVersion: apps/v1
176 kind: Deployment
177 metadata:
178 labels:
179 control-plane: controller-manager
180 gatekeeper.sh/operation: webhook
181 name: controller-manager
182 namespace: system
183 spec:
184 replicas: 3
185 selector:
186 matchLabels:
187 control-plane: controller-manager
188 gatekeeper.sh/operation: webhook
189 template:
190 metadata:
191 annotations:
192 container.seccomp.security.alpha.kubernetes.io/manager: runtime/default
193 labels:
194 control-plane: controller-manager
195 gatekeeper.sh/operation: webhook
196 spec:
197 containers:
198 - args:
199 - --emit-audit-events
200 - --operation=audit
201 - --operation=status
202 - --logtostderr
203 command:
204 - /manager
205 image: CONTROLLER_IMAGE
206 imagePullPolicy: Always
207 name: manager
208 nodeSelector:
209 kubernetes.io/os: linux
210 priorityClassName: system-cluster-critical
211 terminationGracePeriodSeconds: 60
212 ---
213 apiVersion: apps/v1
214 kind: Deployment
215 metadata:
216 labels:
217 control-plane: audit-controller
218 gatekeeper.sh/operation: audit
219 name: audit
220 namespace: system
221 spec:
222 replicas: 1
223 selector:
224 matchLabels:
225 control-plane: audit-controller
226 gatekeeper.sh/operation: audit
227 template:
228 metadata:
229 annotations:
230 container.seccomp.security.alpha.kubernetes.io/manager: runtime/default
231 labels:
232 control-plane: audit-controller
233 gatekeeper.sh/operation: audit
234 spec:
235 automountServiceAccountToken: true
236 containers:
237 - args:
238 - --port=8443
239 - --logtostderr
240 - --emit-admission-events
241 - --exempt-namespace=gatekeeper-system
242 - --operation=webhook
243 - --disable-opa-builtin=http.send
244 command:
245 - /manager
246 env:
247 - name: POD_NAMESPACE
248 valueFrom:
249 fieldRef:
250 apiVersion: v1
251 fieldPath: metadata.namespace
252 - name: POD_NAME
253 valueFrom:
254 fieldRef:
255 fieldPath: metadata.name
256 image: AUDIT_IMAGE
257 imagePullPolicy: Always
258 livenessProbe:
259 httpGet:
260 path: /healthz
261 port: 9090
262 name: manager
263 nodeSelector:
264 kubernetes.io/os: linux
265 priorityClassName: system-cluster-critical
266 serviceAccountName: gatekeeper-admin
267 terminationGracePeriodSeconds: 60
268 `
269
270 th.WriteK("overlay", `
271 resources:
272 - ../base
273 patchesStrategicMerge:
274 - image_patch_controller_manager.yaml
275 - image_patch_audit_manager.yaml
276 `)
277 m := th.Run("overlay", th.MakeDefaultOptions())
278 th.AssertActualEqualsExpected(m, expected)
279
280
281 th.WriteK("overlay", `
282 resources:
283 - ../base
284 patches:
285 - path: image_patch_controller_manager.yaml
286 - path: image_patch_audit_manager.yaml
287 `)
288 m = th.Run("overlay", th.MakeDefaultOptions())
289 th.AssertActualEqualsExpected(m, expected)
290
291
292 th.WriteK("overlay", `
293 resources:
294 - ../base
295 patchesStrategicMerge:
296 - twoPatchesInOneFile.yaml
297 `)
298 th.WriteF(
299 "overlay/twoPatchesInOneFile.yaml",
300 imagePatchAuditManager+"\n---\n"+imagePatchControllerManager)
301 m = th.Run("overlay", th.MakeDefaultOptions())
302 th.AssertActualEqualsExpected(m, expected)
303
304
305 th.WriteK("overlay", `
306 resources:
307 - ../base
308 patches:
309 - path: twoPatchesInOneFile.yaml
310 `)
311 m = th.Run("overlay", th.MakeDefaultOptions())
312 th.AssertActualEqualsExpected(m, expected)
313 }
314
315 func TestRemoveEmptyDirWithNullFieldInSmp(t *testing.T) {
316 th := kusttest_test.MakeHarness(t)
317 th.WriteK(".", `
318 resources:
319 - deployment.yaml
320 patchesStrategicMerge:
321 - patch.yaml
322 `)
323 th.WriteF("deployment.yaml", `
324 apiVersion: apps/v1
325 kind: Deployment
326 metadata:
327 name: nginx
328 spec:
329 template:
330 spec:
331 volumes:
332 - name: fancyDisk
333 emptyDir: {}
334 `)
335 th.WriteF("patch.yaml", `
336 apiVersion: apps/v1
337 kind: Deployment
338 metadata:
339 name: nginx
340 spec:
341 template:
342 spec:
343 volumes:
344 - name: fancyDisk
345 emptyDir: null
346 `)
347 m := th.Run(".", th.MakeDefaultOptions())
348 th.AssertActualEqualsExpected(m, `
349 apiVersion: apps/v1
350 kind: Deployment
351 metadata:
352 name: nginx
353 spec:
354 template:
355 spec:
356 volumes:
357 - name: fancyDisk
358 `)
359 }
360
361 func TestRemoveEmptyDirAddPersistentDisk(t *testing.T) {
362 th := kusttest_test.MakeHarness(t)
363 th.WriteK(".", `
364 resources:
365 - deployment.yaml
366 patchesStrategicMerge:
367 - patch.yaml
368 `)
369 th.WriteF("deployment.yaml", `
370 apiVersion: apps/v1
371 kind: Deployment
372 metadata:
373 name: nginx
374 spec:
375 template:
376 spec:
377 volumes:
378 - name: fancyDisk
379 emptyDir: {}
380 `)
381 th.WriteF("patch.yaml", `
382 apiVersion: apps/v1
383 kind: Deployment
384 metadata:
385 name: nginx
386 spec:
387 template:
388 spec:
389 volumes:
390 - name: fancyDisk
391 emptyDir: null
392 gcePersistentDisk:
393 pdName: fancyDisk
394 `)
395 m := th.Run(".", th.MakeDefaultOptions())
396 th.AssertActualEqualsExpected(m, `
397 apiVersion: apps/v1
398 kind: Deployment
399 metadata:
400 name: nginx
401 spec:
402 template:
403 spec:
404 volumes:
405 - gcePersistentDisk:
406 pdName: fancyDisk
407 name: fancyDisk
408 `)
409 }
410
411 func TestVolumeRemoveEmptyDirInOverlay(t *testing.T) {
412 th := kusttest_test.MakeHarness(t)
413 th.WriteK("base", `
414 resources:
415 - deployment.yaml
416 configMapGenerator:
417 - name: baseCm
418 literals:
419 - foo=bar
420 `)
421 th.WriteF("base/deployment.yaml", `
422 apiVersion: apps/v1
423 kind: Deployment
424 metadata:
425 name: nginx
426 spec:
427 template:
428 spec:
429 containers:
430 - name: nginx
431 image: nginx
432 volumeMounts:
433 - name: fancyDisk
434 mountPath: /tmp/ps
435 volumes:
436 - name: fancyDisk
437 emptyDir: {}
438 - configMap:
439 name: baseCm
440 name: baseCm
441 `)
442 m := th.Run("base", th.MakeDefaultOptions())
443 th.AssertActualEqualsExpected(m, `
444 apiVersion: apps/v1
445 kind: Deployment
446 metadata:
447 name: nginx
448 spec:
449 template:
450 spec:
451 containers:
452 - image: nginx
453 name: nginx
454 volumeMounts:
455 - mountPath: /tmp/ps
456 name: fancyDisk
457 volumes:
458 - emptyDir: {}
459 name: fancyDisk
460 - configMap:
461 name: baseCm-798k5k7g9f
462 name: baseCm
463 ---
464 apiVersion: v1
465 data:
466 foo: bar
467 kind: ConfigMap
468 metadata:
469 name: baseCm-798k5k7g9f
470 `)
471
472 th.WriteK("overlay", `
473 patchesStrategicMerge:
474 - patch.yaml
475 resources:
476 - ../base
477 configMapGenerator:
478 - name: overlayCm
479 literals:
480 - hello=world
481 `)
482 th.WriteF("overlay/patch.yaml", `
483 apiVersion: apps/v1
484 kind: Deployment
485 metadata:
486 name: nginx
487 spec:
488 template:
489 spec:
490 volumes:
491 - name: fancyDisk
492 emptyDir: null
493 gcePersistentDisk:
494 pdName: fancyDisk
495 - configMap:
496 name: overlayCm
497 name: overlayCm
498 `)
499 m = th.Run("overlay", th.MakeDefaultOptions())
500 th.AssertActualEqualsExpected(m, `
501 apiVersion: apps/v1
502 kind: Deployment
503 metadata:
504 name: nginx
505 spec:
506 template:
507 spec:
508 containers:
509 - image: nginx
510 name: nginx
511 volumeMounts:
512 - mountPath: /tmp/ps
513 name: fancyDisk
514 volumes:
515 - gcePersistentDisk:
516 pdName: fancyDisk
517 name: fancyDisk
518 - configMap:
519 name: overlayCm-dc6fm46dhm
520 name: overlayCm
521 - configMap:
522 name: baseCm-798k5k7g9f
523 name: baseCm
524 ---
525 apiVersion: v1
526 data:
527 foo: bar
528 kind: ConfigMap
529 metadata:
530 name: baseCm-798k5k7g9f
531 ---
532 apiVersion: v1
533 data:
534 hello: world
535 kind: ConfigMap
536 metadata:
537 name: overlayCm-dc6fm46dhm
538 `)
539 }
540
541
542 func TestRemoveEmptyDirWithPatchesAtSameLevel(t *testing.T) {
543 th := kusttest_test.MakeHarness(t)
544 th.WriteK("base", `
545 resources:
546 - deployment.yaml
547 `)
548 th.WriteF("base/deployment.yaml", `
549 apiVersion: apps/v1
550 kind: Deployment
551 metadata:
552 name: nginx
553 spec:
554 template:
555 spec:
556 containers:
557 - name: nginx
558 image: nginx
559 - name: sidecar
560 image: sidecar:latest
561 volumes:
562 - name: nginx-persistent-storage
563 emptyDir: {}
564 `)
565 th.WriteK("overlay", `
566 patchesStrategicMerge:
567 - deployment-patch1.yaml
568 - deployment-patch2.yaml
569 resources:
570 - ../base
571 `)
572 th.WriteF("overlay/deployment-patch1.yaml", `
573 apiVersion: apps/v1
574 kind: Deployment
575 metadata:
576 name: nginx
577 spec:
578 template:
579 spec:
580 volumes:
581 - name: nginx-persistent-storage
582 emptyDir: null
583 gcePersistentDisk:
584 pdName: nginx-persistent-storage
585 `)
586 th.WriteF("overlay/deployment-patch2.yaml", `
587 apiVersion: apps/v1
588 kind: Deployment
589 metadata:
590 name: nginx
591 spec:
592 template:
593 spec:
594 containers:
595 - image: nginx
596 name: nginx
597 env:
598 - name: ANOTHERENV
599 value: FOO
600 volumes:
601 - name: nginx-persistent-storage
602 `)
603 opts := th.MakeDefaultOptions()
604 m := th.Run("overlay", opts)
605 th.AssertActualEqualsExpected(
606 m, `
607 apiVersion: apps/v1
608 kind: Deployment
609 metadata:
610 name: nginx
611 spec:
612 template:
613 spec:
614 containers:
615 - env:
616 - name: ANOTHERENV
617 value: FOO
618 image: nginx
619 name: nginx
620 - image: sidecar:latest
621 name: sidecar
622 volumes:
623 - gcePersistentDisk:
624 pdName: nginx-persistent-storage
625 name: nginx-persistent-storage
626 `)
627 }
628
629 func TestSimpleMultiplePatches(t *testing.T) {
630 th := kusttest_test.MakeHarness(t)
631 th.WriteK("base", `
632 namePrefix: b-
633 commonLabels:
634 team: foo
635 resources:
636 - deployment.yaml
637 - service.yaml
638 configMapGenerator:
639 - name: configmap-in-base
640 literals:
641 - foo=bar
642 `)
643 th.WriteF("base/deployment.yaml", `
644 apiVersion: apps/v1
645 kind: Deployment
646 metadata:
647 name: nginx
648 spec:
649 template:
650 spec:
651 containers:
652 - name: nginx
653 image: nginx
654 volumeMounts:
655 - name: nginx-persistent-storage
656 mountPath: /tmp/ps
657 - name: sidecar
658 image: sidecar:latest
659 volumes:
660 - configMap:
661 name: configmap-in-base
662 name: configmap-in-base
663 `)
664 th.WriteF("base/service.yaml", `
665 apiVersion: v1
666 kind: Service
667 metadata:
668 name: nginx
669 spec:
670 ports:
671 - port: 80
672 `)
673 th.WriteK("overlay", `
674 namePrefix: a-
675 commonLabels:
676 env: staging
677 patchesStrategicMerge:
678 - deployment-patch1.yaml
679 - deployment-patch2.yaml
680 resources:
681 - ../base
682 configMapGenerator:
683 - name: configmap-in-overlay
684 literals:
685 - hello=world
686 `)
687 th.WriteF("overlay/deployment-patch1.yaml", `
688 apiVersion: apps/v1
689 kind: Deployment
690 metadata:
691 name: nginx
692 spec:
693 template:
694 spec:
695 containers:
696 - name: nginx
697 image: nginx:latest
698 env:
699 - name: ENVKEY
700 value: ENVVALUE
701 volumes:
702 - name: nginx-persistent-storage
703 gcePersistentDisk:
704 pdName: nginx-persistent-storage
705 - configMap:
706 name: configmap-in-overlay
707 name: configmap-in-overlay
708 `)
709 th.WriteF("overlay/deployment-patch2.yaml", `
710 apiVersion: apps/v1
711 kind: Deployment
712 metadata:
713 name: nginx
714 spec:
715 template:
716 spec:
717 containers:
718 - name: nginx
719 env:
720 - name: ANOTHERENV
721 value: FOO
722 `)
723 m := th.Run("overlay", th.MakeDefaultOptions())
724 th.AssertActualEqualsExpected(m, `
725 apiVersion: apps/v1
726 kind: Deployment
727 metadata:
728 labels:
729 env: staging
730 team: foo
731 name: a-b-nginx
732 spec:
733 selector:
734 matchLabels:
735 env: staging
736 team: foo
737 template:
738 metadata:
739 labels:
740 env: staging
741 team: foo
742 spec:
743 containers:
744 - env:
745 - name: ANOTHERENV
746 value: FOO
747 - name: ENVKEY
748 value: ENVVALUE
749 image: nginx:latest
750 name: nginx
751 volumeMounts:
752 - mountPath: /tmp/ps
753 name: nginx-persistent-storage
754 - image: sidecar:latest
755 name: sidecar
756 volumes:
757 - gcePersistentDisk:
758 pdName: nginx-persistent-storage
759 name: nginx-persistent-storage
760 - configMap:
761 name: a-configmap-in-overlay-dc6fm46dhm
762 name: configmap-in-overlay
763 - configMap:
764 name: a-b-configmap-in-base-798k5k7g9f
765 name: configmap-in-base
766 ---
767 apiVersion: v1
768 kind: Service
769 metadata:
770 labels:
771 env: staging
772 team: foo
773 name: a-b-nginx
774 spec:
775 ports:
776 - port: 80
777 selector:
778 env: staging
779 team: foo
780 ---
781 apiVersion: v1
782 data:
783 foo: bar
784 kind: ConfigMap
785 metadata:
786 labels:
787 env: staging
788 team: foo
789 name: a-b-configmap-in-base-798k5k7g9f
790 ---
791 apiVersion: v1
792 data:
793 hello: world
794 kind: ConfigMap
795 metadata:
796 labels:
797 env: staging
798 name: a-configmap-in-overlay-dc6fm46dhm
799 `)
800 }
801
802 func makeCommonFilesForMultiplePatchTests(th kusttest_test.Harness) {
803 th.WriteK("base", `
804 namePrefix: team-foo-
805 commonLabels:
806 app: mynginx
807 org: example.com
808 team: foo
809 commonAnnotations:
810 note: This is a test annotation
811 resources:
812 - deployment.yaml
813 - service.yaml
814 configMapGenerator:
815 - name: configmap-in-base
816 literals:
817 - foo=bar
818 `)
819 th.WriteF("base/deployment.yaml", `
820 apiVersion: apps/v1
821 kind: Deployment
822 metadata:
823 name: nginx
824 labels:
825 app: nginx
826 spec:
827 template:
828 metadata:
829 labels:
830 app: nginx
831 spec:
832 containers:
833 - name: nginx
834 image: nginx
835 volumeMounts:
836 - name: nginx-persistent-storage
837 mountPath: /tmp/ps
838 - name: sidecar
839 image: sidecar:latest
840 volumes:
841 - configMap:
842 name: configmap-in-base
843 name: configmap-in-base
844 `)
845 th.WriteF("base/service.yaml", `
846 apiVersion: v1
847 kind: Service
848 metadata:
849 name: nginx
850 labels:
851 app: nginx
852 spec:
853 ports:
854 - port: 80
855 selector:
856 app: nginx
857 `)
858 th.WriteK("overlay/staging", `
859 namePrefix: staging-
860 commonLabels:
861 env: staging
862 patchesStrategicMerge:
863 - deployment-patch1.yaml
864 - deployment-patch2.yaml
865 resources:
866 - ../../base
867 configMapGenerator:
868 - name: configmap-in-overlay
869 literals:
870 - hello=world
871 `)
872 }
873
874 func TestMultiplePatchesNoConflict(t *testing.T) {
875 th := kusttest_test.MakeHarness(t)
876 makeCommonFilesForMultiplePatchTests(th)
877 th.WriteF("overlay/staging/deployment-patch1.yaml", `
878 apiVersion: apps/v1
879 kind: Deployment
880 metadata:
881 name: nginx
882 spec:
883 template:
884 spec:
885 containers:
886 - name: nginx
887 image: nginx:latest
888 env:
889 - name: ENVKEY
890 value: ENVVALUE
891 volumes:
892 - name: nginx-persistent-storage
893 gcePersistentDisk:
894 pdName: nginx-persistent-storage
895 - configMap:
896 name: configmap-in-overlay
897 name: configmap-in-overlay
898 `)
899 th.WriteF("overlay/staging/deployment-patch2.yaml", `
900 apiVersion: apps/v1
901 kind: Deployment
902 metadata:
903 name: nginx
904 spec:
905 template:
906 spec:
907 containers:
908 - name: nginx
909 env:
910 - name: ANOTHERENV
911 value: FOO
912 `)
913 m := th.Run("overlay/staging", th.MakeDefaultOptions())
914 th.AssertActualEqualsExpected(m, `
915 apiVersion: apps/v1
916 kind: Deployment
917 metadata:
918 annotations:
919 note: This is a test annotation
920 labels:
921 app: mynginx
922 env: staging
923 org: example.com
924 team: foo
925 name: staging-team-foo-nginx
926 spec:
927 selector:
928 matchLabels:
929 app: mynginx
930 env: staging
931 org: example.com
932 team: foo
933 template:
934 metadata:
935 annotations:
936 note: This is a test annotation
937 labels:
938 app: mynginx
939 env: staging
940 org: example.com
941 team: foo
942 spec:
943 containers:
944 - env:
945 - name: ANOTHERENV
946 value: FOO
947 - name: ENVKEY
948 value: ENVVALUE
949 image: nginx:latest
950 name: nginx
951 volumeMounts:
952 - mountPath: /tmp/ps
953 name: nginx-persistent-storage
954 - image: sidecar:latest
955 name: sidecar
956 volumes:
957 - gcePersistentDisk:
958 pdName: nginx-persistent-storage
959 name: nginx-persistent-storage
960 - configMap:
961 name: staging-configmap-in-overlay-dc6fm46dhm
962 name: configmap-in-overlay
963 - configMap:
964 name: staging-team-foo-configmap-in-base-798k5k7g9f
965 name: configmap-in-base
966 ---
967 apiVersion: v1
968 kind: Service
969 metadata:
970 annotations:
971 note: This is a test annotation
972 labels:
973 app: mynginx
974 env: staging
975 org: example.com
976 team: foo
977 name: staging-team-foo-nginx
978 spec:
979 ports:
980 - port: 80
981 selector:
982 app: mynginx
983 env: staging
984 org: example.com
985 team: foo
986 ---
987 apiVersion: v1
988 data:
989 foo: bar
990 kind: ConfigMap
991 metadata:
992 annotations:
993 note: This is a test annotation
994 labels:
995 app: mynginx
996 env: staging
997 org: example.com
998 team: foo
999 name: staging-team-foo-configmap-in-base-798k5k7g9f
1000 ---
1001 apiVersion: v1
1002 data:
1003 hello: world
1004 kind: ConfigMap
1005 metadata:
1006 labels:
1007 env: staging
1008 name: staging-configmap-in-overlay-dc6fm46dhm
1009 `)
1010 }
1011
1012 func TestNonCommutablePatches(t *testing.T) {
1013 th := kusttest_test.MakeHarness(t)
1014 makeCommonFilesForMultiplePatchTests(th)
1015 th.WriteF("overlay/staging/deployment-patch1.yaml", `
1016 apiVersion: apps/v1
1017 kind: Deployment
1018 metadata:
1019 name: nginx
1020 spec:
1021 template:
1022 spec:
1023 containers:
1024 - name: nginx
1025 env:
1026 - name: ENABLE_FEATURE_FOO
1027 value: TRUE
1028 volumes:
1029 - name: nginx-persistent-storage
1030 gcePersistentDisk:
1031 pdName: nginx-persistent-storage
1032 - configMap:
1033 name: configmap-in-overlay
1034 name: configmap-in-overlay
1035 `)
1036 th.WriteF("overlay/staging/deployment-patch2.yaml", `
1037 apiVersion: apps/v1
1038 kind: Deployment
1039 metadata:
1040 name: nginx
1041 spec:
1042 template:
1043 spec:
1044 containers:
1045 - name: nginx
1046 env:
1047 - name: ENABLE_FEATURE_FOO
1048 value: FALSE
1049 `)
1050
1051
1052 m := th.Run("overlay/staging", th.MakeDefaultOptions())
1053 th.AssertActualEqualsExpected(m, `
1054 apiVersion: apps/v1
1055 kind: Deployment
1056 metadata:
1057 annotations:
1058 note: This is a test annotation
1059 labels:
1060 app: mynginx
1061 env: staging
1062 org: example.com
1063 team: foo
1064 name: staging-team-foo-nginx
1065 spec:
1066 selector:
1067 matchLabels:
1068 app: mynginx
1069 env: staging
1070 org: example.com
1071 team: foo
1072 template:
1073 metadata:
1074 annotations:
1075 note: This is a test annotation
1076 labels:
1077 app: mynginx
1078 env: staging
1079 org: example.com
1080 team: foo
1081 spec:
1082 containers:
1083 - env:
1084 - name: ENABLE_FEATURE_FOO
1085 value: false
1086 image: nginx
1087 name: nginx
1088 volumeMounts:
1089 - mountPath: /tmp/ps
1090 name: nginx-persistent-storage
1091 - image: sidecar:latest
1092 name: sidecar
1093 volumes:
1094 - gcePersistentDisk:
1095 pdName: nginx-persistent-storage
1096 name: nginx-persistent-storage
1097 - configMap:
1098 name: staging-configmap-in-overlay-dc6fm46dhm
1099 name: configmap-in-overlay
1100 - configMap:
1101 name: staging-team-foo-configmap-in-base-798k5k7g9f
1102 name: configmap-in-base
1103 ---
1104 apiVersion: v1
1105 kind: Service
1106 metadata:
1107 annotations:
1108 note: This is a test annotation
1109 labels:
1110 app: mynginx
1111 env: staging
1112 org: example.com
1113 team: foo
1114 name: staging-team-foo-nginx
1115 spec:
1116 ports:
1117 - port: 80
1118 selector:
1119 app: mynginx
1120 env: staging
1121 org: example.com
1122 team: foo
1123 ---
1124 apiVersion: v1
1125 data:
1126 foo: bar
1127 kind: ConfigMap
1128 metadata:
1129 annotations:
1130 note: This is a test annotation
1131 labels:
1132 app: mynginx
1133 env: staging
1134 org: example.com
1135 team: foo
1136 name: staging-team-foo-configmap-in-base-798k5k7g9f
1137 ---
1138 apiVersion: v1
1139 data:
1140 hello: world
1141 kind: ConfigMap
1142 metadata:
1143 labels:
1144 env: staging
1145 name: staging-configmap-in-overlay-dc6fm46dhm
1146 `)
1147 }
1148
1149 func TestMultiplePatchesWithOnePatchDeleteDirective(t *testing.T) {
1150 additivePatch := `apiVersion: apps/v1
1151 kind: Deployment
1152 metadata:
1153 name: nginx
1154 spec:
1155 template:
1156 spec:
1157 containers:
1158 - name: nginx
1159 env:
1160 - name: SOME_NAME
1161 value: somevalue
1162 `
1163 deletePatch := `apiVersion: apps/v1
1164 kind: Deployment
1165 metadata:
1166 name: nginx
1167 spec:
1168 template:
1169 spec:
1170 containers:
1171 - $patch: delete
1172 name: sidecar
1173 `
1174 cases := map[string]struct {
1175 patch1 string
1176 patch2 string
1177 expectError bool
1178 }{
1179 "Patch with delete directive first": {
1180 patch1: deletePatch,
1181 patch2: additivePatch,
1182 },
1183 "Patch with delete directive second": {
1184 patch1: additivePatch,
1185 patch2: deletePatch,
1186 },
1187 }
1188 for name := range cases {
1189 c := cases[name]
1190 t.Run(name, func(t *testing.T) {
1191 th := kusttest_test.MakeHarness(t)
1192 makeCommonFilesForMultiplePatchTests(th)
1193 th.WriteF("overlay/staging/deployment-patch1.yaml", c.patch1)
1194 th.WriteF("overlay/staging/deployment-patch2.yaml", c.patch2)
1195 m := th.Run("overlay/staging", th.MakeDefaultOptions())
1196 th.AssertActualEqualsExpected(m, `apiVersion: apps/v1
1197 kind: Deployment
1198 metadata:
1199 annotations:
1200 note: This is a test annotation
1201 labels:
1202 app: mynginx
1203 env: staging
1204 org: example.com
1205 team: foo
1206 name: staging-team-foo-nginx
1207 spec:
1208 selector:
1209 matchLabels:
1210 app: mynginx
1211 env: staging
1212 org: example.com
1213 team: foo
1214 template:
1215 metadata:
1216 annotations:
1217 note: This is a test annotation
1218 labels:
1219 app: mynginx
1220 env: staging
1221 org: example.com
1222 team: foo
1223 spec:
1224 containers:
1225 - env:
1226 - name: SOME_NAME
1227 value: somevalue
1228 image: nginx
1229 name: nginx
1230 volumeMounts:
1231 - mountPath: /tmp/ps
1232 name: nginx-persistent-storage
1233 volumes:
1234 - configMap:
1235 name: staging-team-foo-configmap-in-base-798k5k7g9f
1236 name: configmap-in-base
1237 ---
1238 apiVersion: v1
1239 kind: Service
1240 metadata:
1241 annotations:
1242 note: This is a test annotation
1243 labels:
1244 app: mynginx
1245 env: staging
1246 org: example.com
1247 team: foo
1248 name: staging-team-foo-nginx
1249 spec:
1250 ports:
1251 - port: 80
1252 selector:
1253 app: mynginx
1254 env: staging
1255 org: example.com
1256 team: foo
1257 ---
1258 apiVersion: v1
1259 data:
1260 foo: bar
1261 kind: ConfigMap
1262 metadata:
1263 annotations:
1264 note: This is a test annotation
1265 labels:
1266 app: mynginx
1267 env: staging
1268 org: example.com
1269 team: foo
1270 name: staging-team-foo-configmap-in-base-798k5k7g9f
1271 ---
1272 apiVersion: v1
1273 data:
1274 hello: world
1275 kind: ConfigMap
1276 metadata:
1277 labels:
1278 env: staging
1279 name: staging-configmap-in-overlay-dc6fm46dhm
1280 `)
1281 })
1282 }
1283 }
1284
1285 func TestMultiplePatchesBothWithPatchDeleteDirective(t *testing.T) {
1286 th := kusttest_test.MakeHarness(t)
1287 makeCommonFilesForMultiplePatchTests(th)
1288 th.WriteF("overlay/staging/deployment-patch1.yaml", `
1289 apiVersion: apps/v1
1290 kind: Deployment
1291 metadata:
1292 name: nginx
1293 spec:
1294 template:
1295 spec:
1296 containers:
1297 - $patch: delete
1298 name: sidecar
1299 `)
1300 th.WriteF("overlay/staging/deployment-patch2.yaml", `
1301 apiVersion: apps/v1
1302 kind: Deployment
1303 metadata:
1304 name: nginx
1305 spec:
1306 template:
1307 spec:
1308 containers:
1309 - $patch: delete
1310 name: nginx
1311 `)
1312
1313
1314 m := th.Run("overlay/staging", th.MakeDefaultOptions())
1315 th.AssertActualEqualsExpected(m, `
1316 apiVersion: apps/v1
1317 kind: Deployment
1318 metadata:
1319 annotations:
1320 note: This is a test annotation
1321 labels:
1322 app: mynginx
1323 env: staging
1324 org: example.com
1325 team: foo
1326 name: staging-team-foo-nginx
1327 spec:
1328 selector:
1329 matchLabels:
1330 app: mynginx
1331 env: staging
1332 org: example.com
1333 team: foo
1334 template:
1335 metadata:
1336 annotations:
1337 note: This is a test annotation
1338 labels:
1339 app: mynginx
1340 env: staging
1341 org: example.com
1342 team: foo
1343 spec:
1344 containers: []
1345 volumes:
1346 - configMap:
1347 name: staging-team-foo-configmap-in-base-798k5k7g9f
1348 name: configmap-in-base
1349 ---
1350 apiVersion: v1
1351 kind: Service
1352 metadata:
1353 annotations:
1354 note: This is a test annotation
1355 labels:
1356 app: mynginx
1357 env: staging
1358 org: example.com
1359 team: foo
1360 name: staging-team-foo-nginx
1361 spec:
1362 ports:
1363 - port: 80
1364 selector:
1365 app: mynginx
1366 env: staging
1367 org: example.com
1368 team: foo
1369 ---
1370 apiVersion: v1
1371 data:
1372 foo: bar
1373 kind: ConfigMap
1374 metadata:
1375 annotations:
1376 note: This is a test annotation
1377 labels:
1378 app: mynginx
1379 env: staging
1380 org: example.com
1381 team: foo
1382 name: staging-team-foo-configmap-in-base-798k5k7g9f
1383 ---
1384 apiVersion: v1
1385 data:
1386 hello: world
1387 kind: ConfigMap
1388 metadata:
1389 labels:
1390 env: staging
1391 name: staging-configmap-in-overlay-dc6fm46dhm
1392 `)
1393 }
1394
1395
1396 func TestSmpWithDifferentKeysOnDifferentPorts(t *testing.T) {
1397 th := kusttest_test.MakeHarness(t)
1398 th.WriteK(".", `
1399 resources:
1400 - resource.yaml
1401 patches:
1402 - path: patch.yaml
1403 target:
1404 kind: StatefulSet
1405 name: myapp
1406 `)
1407 th.WriteF("resource.yaml", `
1408 apiVersion: apps/v1
1409 kind: StatefulSet
1410 metadata:
1411 name: myapp
1412 spec:
1413 template:
1414 spec:
1415 containers:
1416 - name: consul
1417 image: "dashicorp/consul:1.9.1"
1418 ports:
1419 - containerPort: 8500
1420 name: http
1421 - containerPort: 8501
1422 name: https
1423 - containerPort: 8301
1424 protocol: "TCP"
1425 name: serflan-tcp
1426 - containerPort: 8301
1427 protocol: "UDP"
1428 name: serflan-udp
1429 - containerPort: 8302
1430 name: serfwan
1431 - containerPort: 8300
1432 name: server
1433 - containerPort: 8600
1434 name: dns-tcp
1435 protocol: "TCP"
1436 - containerPort: 8600
1437 name: dns-udp
1438 protocol: "UDP"`)
1439 th.WriteF("patch.yaml", `
1440 kind: StatefulSet
1441 metadata:
1442 name: myapp
1443 labels:
1444 test: label
1445 `)
1446 m := th.Run(".", th.MakeDefaultOptions())
1447 th.AssertActualEqualsExpected(m, `
1448 apiVersion: apps/v1
1449 kind: StatefulSet
1450 metadata:
1451 labels:
1452 test: label
1453 name: myapp
1454 spec:
1455 template:
1456 spec:
1457 containers:
1458 - image: dashicorp/consul:1.9.1
1459 name: consul
1460 ports:
1461 - containerPort: 8500
1462 name: http
1463 - containerPort: 8501
1464 name: https
1465 - containerPort: 8301
1466 name: serflan-tcp
1467 protocol: TCP
1468 - containerPort: 8301
1469 name: serflan-udp
1470 protocol: UDP
1471 - containerPort: 8302
1472 name: serfwan
1473 - containerPort: 8300
1474 name: server
1475 - containerPort: 8600
1476 name: dns-tcp
1477 protocol: TCP
1478 - containerPort: 8600
1479 name: dns-udp
1480 protocol: UDP
1481 `)
1482 }
1483
1484
1485 func TestSmpDeleteOnResource(t *testing.T) {
1486 th := kusttest_test.MakeHarness(t)
1487 th.WriteK(".", `
1488 resources:
1489 - workloads.yaml
1490 patches:
1491 - patch: |
1492 apiVersion: monitoring.coreos.com/v1
1493 kind: PrometheusRule
1494 metadata:
1495 name: rule1
1496 $patch: delete
1497 `)
1498 th.WriteF("workloads.yaml", `
1499 apiVersion: monitoring.coreos.com/v1
1500 kind: PrometheusRule
1501 metadata:
1502 labels:
1503 role: alert-rules
1504 name: rule1
1505 spec:
1506 groups:
1507 - name: rabbitmq.rules
1508 ---
1509 apiVersion: monitoring.coreos.com/v1
1510 kind: PrometheusRule
1511 metadata:
1512 labels:
1513 role: alert-rules
1514 name: rule2
1515 spec:
1516 groups:
1517 - name: rabbitmq.rules
1518 `)
1519 m := th.Run(".", th.MakeDefaultOptions())
1520 th.AssertActualEqualsExpected(m, `
1521 apiVersion: monitoring.coreos.com/v1
1522 kind: PrometheusRule
1523 metadata:
1524 labels:
1525 role: alert-rules
1526 name: rule2
1527 spec:
1528 groups:
1529 - name: rabbitmq.rules
1530 `)
1531 }
1532
1533
1534 func TestPatchPortHasNoProtocol(t *testing.T) {
1535 th := kusttest_test.MakeHarness(t)
1536 th.WriteK(".", `
1537 resources:
1538 - service.yaml
1539 patchesStrategicMerge:
1540 - patch.yaml
1541 `)
1542 th.WriteF("service.yaml", `
1543 apiVersion: v1
1544 kind: Service
1545 metadata:
1546 name: web
1547 spec:
1548 ports:
1549 - port: 30900
1550 targetPort: 30900
1551 protocol: TCP
1552 type: NodePort
1553 `)
1554 th.WriteF("patch.yaml", `
1555 apiVersion: v1
1556 kind: Service
1557 metadata:
1558 name: web
1559 labels:
1560 service: web
1561 spec:
1562 ports:
1563 - port: 30900
1564 targetPort: 30900
1565 selector:
1566 service: web
1567 `)
1568 m := th.Run(".", th.MakeDefaultOptions())
1569 th.AssertActualEqualsExpected(m, `
1570 apiVersion: v1
1571 kind: Service
1572 metadata:
1573 labels:
1574 service: web
1575 name: web
1576 spec:
1577 ports:
1578 - port: 30900
1579 protocol: TCP
1580 targetPort: 30900
1581 selector:
1582 service: web
1583 type: NodePort
1584 `)
1585 }
1586
1587
1588 func TestPatchAddNewServicePort(t *testing.T) {
1589 th := kusttest_test.MakeHarness(t)
1590 th.WriteK(".", `
1591 resources:
1592 - service.yaml
1593 patchesStrategicMerge:
1594 - patch.yaml
1595 `)
1596 th.WriteF("service.yaml", `
1597 apiVersion: v1
1598 kind: Service
1599 metadata:
1600 name: web
1601 spec:
1602 ports:
1603 - port: 30900
1604 targetPort: 30900
1605 protocol: TCP
1606 type: NodePort
1607 `)
1608 th.WriteF("patch.yaml", `
1609 apiVersion: v1
1610 kind: Service
1611 metadata:
1612 name: web
1613 labels:
1614 service: web
1615 spec:
1616 ports:
1617 - port: 30901
1618 targetPort: 30901
1619 selector:
1620 service: web
1621 `)
1622 m := th.Run(".", th.MakeDefaultOptions())
1623 th.AssertActualEqualsExpected(m, `
1624 apiVersion: v1
1625 kind: Service
1626 metadata:
1627 labels:
1628 service: web
1629 name: web
1630 spec:
1631 ports:
1632 - port: 30901
1633 targetPort: 30901
1634 - port: 30900
1635 protocol: TCP
1636 targetPort: 30900
1637 selector:
1638 service: web
1639 type: NodePort
1640 `)
1641 }
1642
1643
1644 func TestPatchPreservesInternalAnnotations(t *testing.T) {
1645 th := kusttest_test.MakeHarness(t)
1646 th.WriteK(".", `
1647 nameSuffix: -abc
1648 resources:
1649 - fluentd.yaml
1650 patchesJson6902:
1651 - path: patch.yaml
1652 target:
1653 name: fluentd-sa
1654 kind: ServiceAccount
1655 version: v1
1656 `)
1657 th.WriteF("fluentd.yaml", `
1658 apiVersion: v1
1659 kind: DaemonSet
1660 metadata:
1661 name: fluentd
1662 spec:
1663 template:
1664 spec:
1665 containers:
1666 - image: fluentd:latest
1667 name: fluentd
1668 serviceAccountName: fluentd-sa
1669 ---
1670 apiVersion: v1
1671 kind: ServiceAccount
1672 metadata:
1673 name: fluentd-sa
1674 `)
1675 th.WriteF("patch.yaml", `
1676 - op: add
1677 path: /metadata/annotations
1678 value:
1679 note: this is a test annotation
1680 `)
1681 m := th.Run(".", th.MakeDefaultOptions())
1682 th.AssertActualEqualsExpected(m, `
1683 apiVersion: v1
1684 kind: DaemonSet
1685 metadata:
1686 name: fluentd-abc
1687 spec:
1688 template:
1689 spec:
1690 containers:
1691 - image: fluentd:latest
1692 name: fluentd
1693 serviceAccountName: fluentd-sa-abc
1694 ---
1695 apiVersion: v1
1696 kind: ServiceAccount
1697 metadata:
1698 annotations:
1699 note: this is a test annotation
1700 name: fluentd-sa-abc
1701 `)
1702 }
1703
View as plain text