1
2
3
4 package patchstrategicmerge
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 patch *yaml.RNode
19 expected string
20 }{
21 "simple": {
22 input: `apiVersion: v1
23 kind: Deployment
24 metadata:
25 name: clown
26 spec:
27 numReplicas: 1
28 `,
29 patch: yaml.MustParse(`apiVersion: v1
30 kind: Deployment
31 metadata:
32 name: clown
33 spec:
34 numReplicas: 999
35 `),
36 expected: `apiVersion: v1
37 kind: Deployment
38 metadata:
39 name: clown
40 spec:
41 numReplicas: 999
42 `,
43 },
44 "nullMapEntry1": {
45 input: `
46 apiVersion: example.com/v1
47 kind: Foo
48 metadata:
49 name: my-foo
50 spec:
51 bar:
52 B:
53 C: Z
54 `,
55 patch: yaml.MustParse(`
56 apiVersion: example.com/v1
57 kind: Foo
58 metadata:
59 name: my-foo
60 spec:
61 bar:
62 C: Z
63 D: W
64 baz:
65 hello: world
66 `),
67 expected: `
68 apiVersion: example.com/v1
69 kind: Foo
70 metadata:
71 name: my-foo
72 spec:
73 bar:
74 C: Z
75 D: W
76 baz:
77 hello: world
78 `,
79 },
80 "nullMapEntry2": {
81 input: `
82 apiVersion: example.com/v1
83 kind: Foo
84 metadata:
85 name: my-foo
86 spec:
87 bar:
88 C: Z
89 D: W
90 baz:
91 hello: world
92 `,
93 patch: yaml.MustParse(`
94 apiVersion: example.com/v1
95 kind: Foo
96 metadata:
97 name: my-foo
98 spec:
99 bar:
100 B:
101 C: Z
102 `),
103 expected: `
104 apiVersion: example.com/v1
105 kind: Foo
106 metadata:
107 name: my-foo
108 spec:
109 bar:
110 C: Z
111 D: W
112 baz:
113 hello: world
114 `,
115 },
116 "simple patch": {
117 input: `
118 apiVersion: apps/v1
119 metadata:
120 name: myDeploy
121 kind: Deployment
122 `,
123 patch: yaml.MustParse(`
124 metadata:
125 name: yourDeploy
126 `),
127 expected: `
128 apiVersion: apps/v1
129 metadata:
130 name: yourDeploy
131 kind: Deployment
132 `,
133 },
134 "container patch": {
135 input: `
136 apiVersion: apps/v1
137 metadata:
138 name: myDeploy
139 kind: Deployment
140 spec:
141 template:
142 spec:
143 containers:
144 - name: foo1
145 - name: foo2
146 - name: foo3
147 `,
148 patch: yaml.MustParse(`
149 apiVersion: apps/v1
150 metadata:
151 name: myDeploy
152 kind: Deployment
153 spec:
154 template:
155 spec:
156 containers:
157 - name: foo0
158 `),
159 expected: `
160 apiVersion: apps/v1
161 metadata:
162 name: myDeploy
163 kind: Deployment
164 spec:
165 template:
166 spec:
167 containers:
168 - name: foo0
169 - name: foo1
170 - name: foo2
171 - name: foo3
172 `,
173 },
174 "volumes patch": {
175 input: `
176 apiVersion: apps/v1
177 metadata:
178 name: myDeploy
179 kind: Deployment
180 spec:
181 template:
182 spec:
183 volumes:
184 - name: foo1
185 - name: foo2
186 - name: foo3
187 `,
188 patch: yaml.MustParse(`
189 apiVersion: apps/v1
190 metadata:
191 name: myDeploy
192 kind: Deployment
193 spec:
194 template:
195 spec:
196 volumes:
197 - name: foo0
198 `),
199 expected: `
200 apiVersion: apps/v1
201 metadata:
202 name: myDeploy
203 kind: Deployment
204 spec:
205 template:
206 spec:
207 volumes:
208 - name: foo0
209 - name: foo1
210 - name: foo2
211 - name: foo3
212 `,
213 },
214 "nested patch": {
215 input: `
216 apiVersion: apps/v1
217 metadata:
218 name: myDeploy
219 kind: Deployment
220 spec:
221 containers:
222 - name: nginx
223 args:
224 - abc
225 `,
226 patch: yaml.MustParse(`
227 spec:
228 containers:
229 - name: nginx
230 args:
231 - def
232 `),
233 expected: `
234 apiVersion: apps/v1
235 metadata:
236 name: myDeploy
237 kind: Deployment
238 spec:
239 containers:
240 - name: nginx
241 args:
242 - def
243 `,
244 },
245 "remove mapping - directive": {
246 input: `
247 apiVersion: apps/v1
248 kind: Deployment
249 metadata:
250 name: myDeploy
251 spec:
252 template:
253 spec:
254 containers:
255 - name: test
256 image: test
257 `,
258 patch: yaml.MustParse(`
259 apiVersion: apps/v1
260 kind: Deployment
261 metadata:
262 name: myDeploy
263 spec:
264 template:
265 spec:
266 containers:
267 - name: test
268 image: test
269 $patch: delete
270 `),
271 expected: `
272 apiVersion: apps/v1
273 kind: Deployment
274 metadata:
275 name: myDeploy
276 spec:
277 template:
278 spec:
279 containers: []
280 `,
281 },
282 "replace mapping - directive": {
283 input: `
284 apiVersion: apps/v1
285 kind: Deployment
286 metadata:
287 name: myDeploy
288 spec:
289 template:
290 spec:
291 containers:
292 - name: test
293 image: test
294 `,
295 patch: yaml.MustParse(`
296 apiVersion: apps/v1
297 kind: Deployment
298 metadata:
299 name: myDeploy
300 spec:
301 template:
302 spec:
303 $patch: replace
304 containers:
305 - name: new
306 `),
307 expected: `
308 apiVersion: apps/v1
309 kind: Deployment
310 metadata:
311 name: myDeploy
312 spec:
313 template:
314 spec:
315 containers:
316 - name: new
317 `,
318 },
319 "merge mapping - directive": {
320 input: `
321 apiVersion: apps/v1
322 kind: Deployment
323 metadata:
324 name: myDeploy
325 spec:
326 template:
327 spec:
328 containers:
329 - name: test
330 image: test
331 `,
332 patch: yaml.MustParse(`
333 apiVersion: apps/v1
334 kind: Deployment
335 metadata:
336 name: myDeploy
337 spec:
338 template:
339 spec:
340 containers:
341 - name: test
342 image: test1
343 $patch: merge
344 `),
345 expected: `
346 apiVersion: apps/v1
347 kind: Deployment
348 metadata:
349 name: myDeploy
350 spec:
351 template:
352 spec:
353 containers:
354 - name: test
355 image: test1
356 `,
357 },
358 "remove list - directive": {
359 input: `
360 apiVersion: apps/v1
361 kind: Deployment
362 metadata:
363 name: myDeploy
364 spec:
365 template:
366 spec:
367 containers:
368 - name: test
369 image: test
370 `,
371 patch: yaml.MustParse(`
372 apiVersion: apps/v1
373 kind: Deployment
374 metadata:
375 name: myDeploy
376 spec:
377 template:
378 spec:
379 containers:
380 - whatever
381 - $patch: delete
382 `),
383 expected: `
384 apiVersion: apps/v1
385 kind: Deployment
386 metadata:
387 name: myDeploy
388 spec:
389 template:
390 spec: {}
391 `,
392 },
393 "replace list - directive": {
394 input: `
395 apiVersion: apps/v1
396 kind: Deployment
397 metadata:
398 name: myDeploy
399 spec:
400 template:
401 spec:
402 containers:
403 - name: test
404 image: test
405 `,
406 patch: yaml.MustParse(`
407 apiVersion: apps/v1
408 kind: Deployment
409 metadata:
410 name: myDeploy
411 spec:
412 template:
413 spec:
414 containers:
415 - name: replace
416 image: replace
417 - $patch: replace
418 `),
419 expected: `
420 apiVersion: apps/v1
421 kind: Deployment
422 metadata:
423 name: myDeploy
424 spec:
425 template:
426 spec:
427 containers:
428 - name: replace
429 image: replace
430 `,
431 },
432 "merge list - directive": {
433 input: `
434 apiVersion: apps/v1
435 kind: Deployment
436 metadata:
437 name: myDeploy
438 spec:
439 template:
440 spec:
441 containers:
442 - name: test
443 image: test
444 `,
445 patch: yaml.MustParse(`
446 apiVersion: apps/v1
447 kind: Deployment
448 metadata:
449 name: myDeploy
450 spec:
451 template:
452 spec:
453 containers:
454 - name: test2
455 image: test2
456 - $patch: merge
457 `),
458 expected: `
459 apiVersion: apps/v1
460 kind: Deployment
461 metadata:
462 name: myDeploy
463 spec:
464 template:
465 spec:
466 containers:
467 - name: test2
468 image: test2
469 - name: test
470 image: test
471 `,
472 },
473 "list map keys - add a port, no names": {
474 input: `
475 apiVersion: apps/v1
476 kind: Deployment
477 metadata:
478 name: test-deployment
479 spec:
480 template:
481 spec:
482 containers:
483 - image: test-image
484 name: test-deployment
485 ports:
486 - containerPort: 8080
487 protocol: TCP
488 `,
489 patch: yaml.MustParse(`
490 apiVersion: apps/v1
491 kind: Deployment
492 metadata:
493 name: test-deployment
494 spec:
495 template:
496 spec:
497 containers:
498 - image: test-image
499 name: test-deployment
500 ports:
501 - containerPort: 8080
502 protocol: UDP
503 - containerPort: 80
504 protocol: UDP
505 `),
506 expected: `
507 apiVersion: apps/v1
508 kind: Deployment
509 metadata:
510 name: test-deployment
511 spec:
512 template:
513 spec:
514 containers:
515 - image: test-image
516 name: test-deployment
517 ports:
518 - containerPort: 8080
519 protocol: UDP
520 - containerPort: 80
521 protocol: UDP
522 - containerPort: 8080
523 protocol: TCP
524 `,
525 },
526 "list map keys - add name to port": {
527 input: `
528 apiVersion: apps/v1
529 kind: Deployment
530 metadata:
531 name: test-deployment
532 spec:
533 template:
534 spec:
535 containers:
536 - image: test-image
537 name: test-deployment
538 ports:
539 - containerPort: 8080
540 protocol: UDP
541 - containerPort: 8080
542 protocol: TCP
543 `,
544 patch: yaml.MustParse(`
545 apiVersion: apps/v1
546 kind: Deployment
547 metadata:
548 name: test-deployment
549 spec:
550 template:
551 spec:
552 containers:
553 - image: test-image
554 name: test-deployment
555 ports:
556 - containerPort: 8080
557 protocol: UDP
558 name: UDP-name-patch
559 `),
560 expected: `
561 apiVersion: apps/v1
562 kind: Deployment
563 metadata:
564 name: test-deployment
565 spec:
566 template:
567 spec:
568 containers:
569 - image: test-image
570 name: test-deployment
571 ports:
572 - containerPort: 8080
573 protocol: UDP
574 name: UDP-name-patch
575 - containerPort: 8080
576 protocol: TCP
577 `,
578 },
579 "list map keys - replace port name": {
580 input: `
581 apiVersion: apps/v1
582 kind: Deployment
583 metadata:
584 name: test-deployment
585 spec:
586 template:
587 spec:
588 containers:
589 - image: test-image
590 name: test-deployment
591 ports:
592 - containerPort: 8080
593 protocol: UDP
594 name: UDP-name-original
595 - containerPort: 8080
596 protocol: TCP
597 name: TCP-name-original
598 `,
599 patch: yaml.MustParse(`
600 apiVersion: apps/v1
601 kind: Deployment
602 metadata:
603 name: test-deployment
604 spec:
605 template:
606 spec:
607 containers:
608 - image: test-image
609 name: test-deployment
610 ports:
611 - containerPort: 8080
612 protocol: UDP
613 name: UDP-name-patch
614 `),
615 expected: `
616 apiVersion: apps/v1
617 kind: Deployment
618 metadata:
619 name: test-deployment
620 spec:
621 template:
622 spec:
623 containers:
624 - image: test-image
625 name: test-deployment
626 ports:
627 - containerPort: 8080
628 protocol: UDP
629 name: UDP-name-patch
630 - containerPort: 8080
631 protocol: TCP
632 name: TCP-name-original
633 `,
634 },
635 "list map keys - add a port, no protocol": {
636 input: `
637 apiVersion: apps/v1
638 kind: Deployment
639 metadata:
640 name: test-deployment
641 spec:
642 template:
643 spec:
644 containers:
645 - image: test-image
646 name: test-deployment
647 ports:
648 - containerPort: 8080
649 `,
650 patch: yaml.MustParse(`
651 apiVersion: apps/v1
652 kind: Deployment
653 metadata:
654 name: test-deployment
655 spec:
656 template:
657 spec:
658 containers:
659 - image: test-image
660 name: test-deployment
661 ports:
662 - containerPort: 80
663 `),
664 expected: `
665 apiVersion: apps/v1
666 kind: Deployment
667 metadata:
668 name: test-deployment
669 spec:
670 template:
671 spec:
672 containers:
673 - image: test-image
674 name: test-deployment
675 ports:
676 - containerPort: 80
677 - containerPort: 8080
678 `,
679 },
680
681
682
683
684
685
686
687 "list map keys - protocol only present on some ports": {
688 input: `
689 apiVersion: apps/v1
690 kind: Deployment
691 metadata:
692 name: test-deployment
693 spec:
694 template:
695 spec:
696 containers:
697 - name: consul
698 image: "dashicorp/consul:1.9.1"
699 ports:
700 - containerPort: 8500
701 name: http
702 - containerPort: 8301
703 protocol: "TCP"
704 - containerPort: 8301
705 protocol: "UDP"
706 `,
707 patch: yaml.MustParse(`
708 apiVersion: apps/v1
709 kind: Deployment
710 metadata:
711 name: test-deployment
712 labels:
713 test: label
714 `),
715 expected: `
716 apiVersion: apps/v1
717 kind: Deployment
718 metadata:
719 name: test-deployment
720 labels:
721 test: label
722 spec:
723 template:
724 spec:
725 containers:
726 - name: consul
727 image: "dashicorp/consul:1.9.1"
728 ports:
729 - containerPort: 8500
730 name: http
731 - containerPort: 8301
732 protocol: "TCP"
733 - containerPort: 8301
734 protocol: "UDP"
735 `,
736 },
737
738
739 "should retain existing null values in targets": {
740 input: `
741 apiVersion: helm.toolkit.fluxcd.io/v2beta1
742 kind: HelmRelease
743 metadata:
744 name: chart
745 spec:
746 releaseName: helm-chart
747 timeout: 15m
748 values:
749 chart:
750 replicaCount: null
751 autoscaling: true
752 `,
753 patch: yaml.MustParse(`
754 apiVersion: helm.toolkit.fluxcd.io/v2beta1
755 kind: HelmRelease
756 metadata:
757 name: chart
758 spec:
759 releaseName: helm-chart
760 timeout: 15m
761 values:
762 deepgram-api:
763 some: value
764 `),
765 expected: `
766 apiVersion: helm.toolkit.fluxcd.io/v2beta1
767 kind: HelmRelease
768 metadata:
769 name: chart
770 spec:
771 releaseName: helm-chart
772 timeout: 15m
773 values:
774 chart:
775 replicaCount: null
776 autoscaling: true
777 deepgram-api:
778 some: value
779 `,
780 },
781
782
783 "support numeric keys": {
784 input: `
785 apiVersion: v1
786 kind: ConfigMap
787 metadata:
788 name: blabla
789 namespace: blabla-ns
790 data:
791 "6443": "foobar"
792 `,
793 patch: yaml.MustParse(`
794 apiVersion: v1
795 kind: ConfigMap
796 metadata:
797 name: blabla
798 namespace: blabla-ns
799 data:
800 "6443": "barfoo"
801 "9110": "foo-foo"
802 `),
803 expected: `
804 apiVersion: v1
805 kind: ConfigMap
806 metadata:
807 name: blabla
808 namespace: blabla-ns
809 data:
810 "6443": "barfoo"
811 "9110": "foo-foo"
812 `,
813 },
814
815 "honor different key style one": {
816 input: `
817 apiVersion: v1
818 kind: ConfigMap
819 metadata:
820 name: blabla
821 namespace: blabla-ns
822 data:
823 '6443': "foobar"
824 `,
825 patch: yaml.MustParse(`
826 apiVersion: v1
827 kind: ConfigMap
828 metadata:
829 name: blabla
830 namespace: blabla-ns
831 data:
832 "6443": "barfoo"
833 9110: "foo-foo"
834 `),
835 expected: `
836 apiVersion: v1
837 kind: ConfigMap
838 metadata:
839 name: blabla
840 namespace: blabla-ns
841 data:
842 '6443': "barfoo"
843 9110: "foo-foo"
844 `,
845 },
846
847 "honor different key style two": {
848 input: `
849 apiVersion: v1
850 kind: ConfigMap
851 metadata:
852 name: blabla
853 namespace: blabla-ns
854 data:
855 "6443": "foobar"
856 `,
857 patch: yaml.MustParse(`
858 apiVersion: v1
859 kind: ConfigMap
860 metadata:
861 name: blabla
862 namespace: blabla-ns
863 data:
864 "6443": "barfoo"
865 '9110': "foo-foo"
866 `),
867 expected: `
868 apiVersion: v1
869 kind: ConfigMap
870 metadata:
871 name: blabla
872 namespace: blabla-ns
873 data:
874 "6443": "barfoo"
875 '9110': "foo-foo"
876 `,
877 },
878
879 "different key types": {
880 input: `
881 apiVersion: v1
882 kind: ConfigMap
883 metadata:
884 name: blabla
885 namespace: blabla-ns
886 data:
887 "6443": "key-string-double-quoted"
888 `,
889 patch: yaml.MustParse(`
890 apiVersion: v1
891 kind: ConfigMap
892 metadata:
893 name: blabla
894 namespace: blabla-ns
895 data:
896 6443: "key-int"
897 `),
898 expected: `
899 apiVersion: v1
900 kind: ConfigMap
901 metadata:
902 name: blabla
903 namespace: blabla-ns
904 data:
905 "6443": "key-int"
906 `,
907 },
908 }
909
910 for tn, tc := range testCases {
911 t.Run(tn, func(t *testing.T) {
912 f := Filter{
913 Patch: tc.patch,
914 }
915 if !assert.Equal(t,
916 strings.TrimSpace(tc.expected),
917 strings.TrimSpace(
918 filtertest.RunFilter(t, tc.input, f))) {
919 t.FailNow()
920 }
921 })
922 }
923 }
924
View as plain text