kubelatte-ce
Форк от sbertech/kubelatte-ce
822 строки · 20.7 Кб
1package mutation2
3import (4"context"5"gitverse.ru/ktrntrsv/kubelatte-ce/pkg/api/v1alpha1"6"gitverse.ru/ktrntrsv/kubelatte-ce/pkg/observability/logger/lib"7"gitverse.ru/ktrntrsv/kubelatte-ce/pkg/util"8baseMatch "gitverse.ru/ktrntrsv/kubelatte-ce/pkg/util/match"9"go.uber.org/zap"10"reflect"11"testing"12)
13
14var templateWithAContainer = v1alpha1.Template{15Spec: v1alpha1.TemplateSpec{Data: `spec:16containers:
17- name: container_mutated
18image: imagemut
19env:
20- name: env_name_mutated
21value: '_mutated'
22- name: ENV_10_mutated
23value: '_mutated'
24resources:
25limits:
26cpu: '55_mutated'
27memory: '55_mutated'
28requests:
29cpu: 55_mutated
30memory: 55_mutated
31args:
32- arg1mut
33securityContext:
34capabilities:
35drop:
36- ALL_mutated`,37},38}
39
40var templateWithContainers = v1alpha1.Template{41Spec: v1alpha1.TemplateSpec{42Data: `spec:43containers:
44- name: container_mutated
45image: image-1
46env:
47- name: ENV_1_ADD
48value: 'false'
49- name: ENV_2
50value: 'false'
51- name: some-other-container
52image: image-2
53resources:
54limits:
55cpu: '51m'
56memory: '51Mi'
57requests:
58cpu: 50m
59memory: 50Mi`,60},61}
62
63var templateWithContainersWithIntersections = v1alpha1.Template{64Spec: v1alpha1.TemplateSpec{65Data: `spec:66containers:
67- name: container_mutated
68image: image-1
69env:
70- name: ENV_1_ADD
71value: 'false'
72- name: ENV_2
73value: 'false'
74- name: some-other-container
75image: image-2
76resources:
77limits:
78cpu: '51m'
79memory: '51Mi'
80requests:
81cpu: 50m
82memory: 50Mi
83- name: container_mutated
84image: image-1-REPLACED
85env:
86- name: ENV_1_ADD-REPLACED
87value: 'false-REPLACED'
88- name: ENV_2-REPLACED
89value: 'false-REPLACED'
90`,91},92}
93
94var templateWithAVolume = v1alpha1.Template{95Spec: v1alpha1.TemplateSpec{96Data: `spec:97volumes:
98- name: volume_mutated1
99configMap:
100name: istio`,101},102}
103
104var templateWithAVolumeWithIntersection = v1alpha1.Template{105Spec: v1alpha1.TemplateSpec{106Data: `spec:107volumes:
108- name: volume_mutated1
109configMap:
110name: istio
111- name: volume_mutated1
112configMap:
113name: istio-REPLACED`,114},115}
116
117var templateWithVolumes = v1alpha1.Template{118Spec: v1alpha1.TemplateSpec{119Data: `spec:120volumes:
121- name: volume_mutated1
122configMap:
123name: istio
124- name: volume_mutated2
125hostPath:
126path: /data
127type: Directory
128- name: volume_mutated3
129secret:
130secretName: mysecret
131optional: true`,132},133}
134
135var templateWithVolumesWithIntersections = v1alpha1.Template{136Spec: v1alpha1.TemplateSpec{137Data: `spec:138volumes:
139- name: volume_mutated1
140configMap:
141name: istio
142- name: volume_mutated2
143hostPath:
144path: /data
145type: Directory
146- name: volume_mutated1
147configMap:
148name: istio-REPLACED
149secret:
150secretName: mysecret
151optional: true`,152},153}
154
155var templateWithAnAnnotation = v1alpha1.Template{156Spec: v1alpha1.TemplateSpec{157Data: `metadata:158annotations:
159annotation_mutated1: val-after-mutation`,160},161}
162
163var templateWithAnnotations = v1alpha1.Template{164Spec: v1alpha1.TemplateSpec{165Data: `metadata:166annotations:
167annotation_mutated1: val-after-mutation
168annotation_mutated2: another-val-after-mutation`,169},170}
171
172func TestMutateController_getRendersOldLogic(t *testing.T) {173type args struct {174obj map[string]interface{}175config v1alpha1.MutationConfig176}177tests := []struct {178name string179args args
180
181templates map[string]v1alpha1.Template182
183want []util.RenderItem184}{185{186name: "merge_mutation_with_a_container",187args: args{188config: v1alpha1.MutationConfig{189Name: "mutation cfg",190UpdateStrategy: string(MergeStrategy),191Containers: []string{"some-ns/some-templ/container_mutated"},192},193},194templates: map[string]v1alpha1.Template{"some-ns/some-templ": templateWithAContainer},195want: []util.RenderItem{{Render: `spec:196containers:
197- args:
198- arg1mut
199env:
200- name: env_name_mutated
201value: _mutated
202- name: ENV_10_mutated
203value: _mutated
204image: imagemut
205name: container_mutated
206resources:
207limits:
208cpu: 55_mutated
209memory: 55_mutated
210requests:
211cpu: 55_mutated
212memory: 55_mutated
213securityContext:
214capabilities:
215drop:
216- ALL_mutated
217`}},218},219{220name: "merge_mutation_with_containers",221args: args{222config: v1alpha1.MutationConfig{223Name: "mutation cfg",224UpdateStrategy: string(MergeStrategy),225Containers: []string{"some-ns/some-templ/container_mutated",226"some-ns/some-templ/some-other-container"},227},228},229templates: map[string]v1alpha1.Template{"some-ns/some-templ": templateWithContainers},230want: []util.RenderItem{{231Render: `spec:232containers:
233- env:
234- name: ENV_1_ADD
235value: "false"
236- name: ENV_2
237value: "false"
238image: image-1
239name: container_mutated
240`},241{Render: `spec:242containers:
243- image: image-2
244name: some-other-container
245resources:
246limits:
247cpu: 51m
248memory: 51Mi
249requests:
250cpu: 50m
251memory: 50Mi
252`}},253},254{255name: "merge_mutation_with_containers_with_intersections",256args: args{257config: v1alpha1.MutationConfig{258Name: "mutation cfg",259UpdateStrategy: string(MergeStrategy),260Containers: []string{"some-ns/some-templ/container_mutated",261"some-ns/some-templ/some-other-container"},262},263},264templates: map[string]v1alpha1.Template{"some-ns/some-templ": templateWithContainersWithIntersections},265want: []util.RenderItem{{266Render: `spec:267containers:
268- env:
269- name: ENV_1_ADD
270value: "false"
271- name: ENV_2
272value: "false"
273image: image-1
274name: container_mutated
275`},276{Render: `spec:277containers:
278- env:
279- name: ENV_1_ADD-REPLACED
280value: false-REPLACED
281- name: ENV_2-REPLACED
282value: false-REPLACED
283image: image-1-REPLACED
284name: container_mutated
285`},286{Render: `spec:287containers:
288- image: image-2
289name: some-other-container
290resources:
291limits:
292cpu: 51m
293memory: 51Mi
294requests:
295cpu: 50m
296memory: 50Mi
297`}},298},299{300name: "merge_mutation_with_a_volume",301args: args{302config: v1alpha1.MutationConfig{303Name: "mutation volume",304UpdateStrategy: string(MergeStrategy),305Volumes: []string{"some-ns/some-templ/volume_mutated1"},306},307},308templates: map[string]v1alpha1.Template{"some-ns/some-templ": templateWithAVolume},309want: []util.RenderItem{{310Render: `spec:311volumes:
312- configMap:
313name: istio
314name: volume_mutated1
315`}},316},317{318name: "merge_mutation_with_volumes",319args: args{320config: v1alpha1.MutationConfig{321Name: "mutation volume",322UpdateStrategy: string(MergeStrategy),323Volumes: []string{"some-ns/some-templ/volume_mutated1", "some-ns/some-templ/volume_mutated2", "some-ns/some-templ/volume_mutated3"},324},325},326templates: map[string]v1alpha1.Template{"some-ns/some-templ": templateWithVolumes},327want: []util.RenderItem{{328Render: `spec:329volumes:
330- configMap:
331name: istio
332name: volume_mutated1
333`}, {334Render: `spec:335volumes:
336- hostPath:
337path: /data
338type: Directory
339name: volume_mutated2
340`}, {341Render: `spec:342volumes:
343- name: volume_mutated3
344secret:
345optional: true
346secretName: mysecret
347`}},348},349{350name: "merge_mutation_with_volumes_with_intersections",351args: args{352config: v1alpha1.MutationConfig{353Name: "mutation volume",354UpdateStrategy: string(MergeStrategy),355Volumes: []string{"some-ns/some-templ/volume_mutated1", "some-ns/some-templ/volume_mutated2"},356},357},358templates: map[string]v1alpha1.Template{"some-ns/some-templ": templateWithVolumesWithIntersections},359want: []util.RenderItem{{360Render: `spec:361volumes:
362- configMap:
363name: istio
364name: volume_mutated1
365`}, {366Render: `spec:367volumes:
368- configMap:
369name: istio-REPLACED
370name: volume_mutated1
371secret:
372optional: true
373secretName: mysecret
374`}, {375Render: `spec:376volumes:
377- hostPath:
378path: /data
379type: Directory
380name: volume_mutated2
381`}},382},383{384name: "merge_mutation_with_an_annotation",385args: args{386config: v1alpha1.MutationConfig{387Name: "mutation annot",388UpdateStrategy: string(MergeStrategy),389Annotations: []string{"some-ns/some-templ/annotation_mutated1"},390},391},392templates: map[string]v1alpha1.Template{"some-ns/some-templ": templateWithAnAnnotation},393want: []util.RenderItem{{394Render: `metadata:395annotations:
396annotation_mutated1: val-after-mutation
397`}},398},399{400name: "replace_mutation_with_an_annotation",401args: args{402config: v1alpha1.MutationConfig{403Name: "mutation annot",404UpdateStrategy: string(ReplaceStrategy),405Annotations: []string{"some-ns/some-templ/annotation_mutated1"},406},407},408templates: map[string]v1alpha1.Template{"some-ns/some-templ": templateWithAnAnnotation},409want: []util.RenderItem{{410Render: `metadata:411annotations:
412annotation_mutated1: val-after-mutation
413`}},414},415{416name: "merge_mutation_with_annotations",417args: args{418config: v1alpha1.MutationConfig{419Name: "mutation annot",420UpdateStrategy: string(MergeStrategy),421Annotations: []string{"some-ns/some-templ/annotation_mutated1",422"some-ns/some-templ/annotation_mutated2"},423},424},425templates: map[string]v1alpha1.Template{"some-ns/some-templ": templateWithAnnotations},426want: []util.RenderItem{427{Render: `metadata:428annotations:
429annotation_mutated1: val-after-mutation
430`},431{Render: `metadata:432annotations:
433annotation_mutated2: another-val-after-mutation
434`}},435},436{437name: "merge_mutation_with_annotations",438args: args{439config: v1alpha1.MutationConfig{440Name: "mutation annot",441UpdateStrategy: string(ReplaceStrategy),442Annotations: []string{"some-ns/some-templ/annotation_mutated1",443"some-ns/some-templ/annotation_mutated2"},444},445},446templates: map[string]v1alpha1.Template{"some-ns/some-templ": templateWithAnnotations},447want: []util.RenderItem{448{Render: `metadata:449annotations:
450annotation_mutated1: val-after-mutation
451`},452{Render: `metadata:453annotations:
454annotation_mutated2: another-val-after-mutation
455`}},456},457{458name: "merge_mutation_with_annotations_with_adding",459args: args{460obj: map[string]interface{}{"metadata": map[string]interface{}{461"annotations": map[string]interface{}{462"annotation_mutated1": "val-after-mutation",463"annot2": "value2",464},465}},466config: v1alpha1.MutationConfig{467Name: "mutation annot",468UpdateStrategy: string(ReplaceStrategy),469Annotations: []string{"some-ns/some-templ/annotation_mutated1",470"some-ns/some-templ/annotation_mutated2"},471},472},473templates: map[string]v1alpha1.Template{"some-ns/some-templ": templateWithAnnotations},474want: []util.RenderItem{475{Render: `metadata:476annotations:
477annotation_mutated1: val-after-mutation
478`},479{Render: `metadata:480annotations:
481annotation_mutated2: another-val-after-mutation
482`}},483},484{485name: "replace_mutation_adding_container", // replaced container not in obj486args: args{487obj: map[string]interface{}{"spec": map[string]interface{}{488"containers": []interface{}{489map[string]interface{}{490"name": "orig_to-test-latte",491"image": "orig_img",492"resources": map[string]interface{}{493"limits": map[string]interface{}{"cpu": "orig_100m", "memory": "orig_100Mi"},494"requests": map[string]interface{}{"cpu": "orig_100m", "memory": "orig_100Mi"},495},496},497},498}},499config: v1alpha1.MutationConfig{500Name: "mutation cfg",501UpdateStrategy: string(ReplaceStrategy),502Containers: []string{"some-ns/some-templ/container_mutated"},503},504},505templates: map[string]v1alpha1.Template{"some-ns/some-templ": templateWithAContainer},506want: []util.RenderItem{{Render: `spec:507containers:
508- image: orig_img
509name: orig_to-test-latte
510resources:
511limits:
512cpu: orig_100m
513memory: orig_100Mi
514requests:
515cpu: orig_100m
516memory: orig_100Mi
517- args:
518- arg1mut
519env:
520- name: env_name_mutated
521value: _mutated
522- name: ENV_10_mutated
523value: _mutated
524image: imagemut
525name: container_mutated
526resources:
527limits:
528cpu: 55_mutated
529memory: 55_mutated
530requests:
531cpu: 55_mutated
532memory: 55_mutated
533securityContext:
534capabilities:
535drop:
536- ALL_mutated
537`}},538},539{540name: "replace_mutation_replacing_container", // replaced container in obj541args: args{542obj: map[string]interface{}{"spec": map[string]interface{}{543"containers": []interface{}{544map[string]interface{}{545"name": "container_mutated",546"image": "orig_img",547"resources": map[string]interface{}{548"limits": map[string]interface{}{"cpu": "orig_100m", "memory": "orig_100Mi"},549"requests": map[string]interface{}{"cpu": "orig_100m", "memory": "orig_100Mi"},550},551},552},553}},554config: v1alpha1.MutationConfig{555Name: "mutation cfg",556UpdateStrategy: string(ReplaceStrategy),557Containers: []string{"some-ns/some-templ/container_mutated"},558},559},560templates: map[string]v1alpha1.Template{"some-ns/some-templ": templateWithAContainer},561want: []util.RenderItem{{Render: `spec:562containers:
563- args:
564- arg1mut
565env:
566- name: env_name_mutated
567value: _mutated
568- name: ENV_10_mutated
569value: _mutated
570image: imagemut
571name: container_mutated
572resources:
573limits:
574cpu: 55_mutated
575memory: 55_mutated
576requests:
577cpu: 55_mutated
578memory: 55_mutated
579securityContext:
580capabilities:
581drop:
582- ALL_mutated
583`}},584},585{586name: "replace_mutation_intersection_container", // replaced container in obj587args: args{588obj: map[string]interface{}{"spec": map[string]interface{}{589"containers": []interface{}{590map[string]interface{}{591"name": "container_mutated",592"image": "orig_img",593"resources": map[string]interface{}{594"limits": map[string]interface{}{"cpu": "orig_100m", "memory": "orig_100Mi"},595"requests": map[string]interface{}{"cpu": "orig_100m", "memory": "orig_100Mi"},596},597},598},599}},600config: v1alpha1.MutationConfig{601Name: "mutation cfg",602UpdateStrategy: string(ReplaceStrategy),603Containers: []string{"some-ns/some-templ/container_mutated",604"some-ns/some-templ/some-other-container"},605},606},607templates: map[string]v1alpha1.Template{"some-ns/some-templ": templateWithContainersWithIntersections},608want: []util.RenderItem{{609Render: `spec:610containers:
611- env:
612- name: ENV_1_ADD
613value: "false"
614- name: ENV_2
615value: "false"
616image: image-1
617name: container_mutated
618`}, {Render: `spec:619containers:
620- env:
621- name: ENV_1_ADD-REPLACED
622value: false-REPLACED
623- name: ENV_2-REPLACED
624value: false-REPLACED
625image: image-1-REPLACED
626name: container_mutated
627`}, {Render: `spec:628containers:
629- env:
630- name: ENV_1_ADD-REPLACED
631value: false-REPLACED
632- name: ENV_2-REPLACED
633value: false-REPLACED
634image: image-1-REPLACED
635name: container_mutated
636- image: image-2
637name: some-other-container
638resources:
639limits:
640cpu: 51m
641memory: 51Mi
642requests:
643cpu: 50m
644memory: 50Mi
645`}},646},647{648name: "replace_mutation_with_a_volume_adding_vol",649args: args{650obj: map[string]interface{}{"spec": map[string]interface{}{651"volumes": []interface{}{652map[string]interface{}{653"name": "volume_mutated",654"image": "orig_img",655"resources": map[string]interface{}{656"limits": map[string]interface{}{"cpu": "orig_100m", "memory": "orig_100Mi"},657"requests": map[string]interface{}{"cpu": "orig_100m", "memory": "orig_100Mi"},658},659},660},661}},662
663config: v1alpha1.MutationConfig{664Name: "mutation volume",665UpdateStrategy: string(ReplaceStrategy),666Volumes: []string{"some-ns/some-templ/volume_mutated1"},667},668},669templates: map[string]v1alpha1.Template{"some-ns/some-templ": templateWithAVolume},670want: []util.RenderItem{{671Render: `spec:672volumes:
673- image: orig_img
674name: volume_mutated
675resources:
676limits:
677cpu: orig_100m
678memory: orig_100Mi
679requests:
680cpu: orig_100m
681memory: orig_100Mi
682- configMap:
683name: istio
684name: volume_mutated1
685`}},686},687{688name: "replace_mutation_with_a_volume_replace_vol",689args: args{690obj: map[string]interface{}{"spec": map[string]interface{}{691"volumes": []interface{}{692map[string]interface{}{693"name": "volume_mutated1",694"image": "orig_img",695"resources": map[string]interface{}{696"limits": map[string]interface{}{"cpu": "orig_100m", "memory": "orig_100Mi"},697"requests": map[string]interface{}{"cpu": "orig_100m", "memory": "orig_100Mi"},698},699},700},701}},702
703config: v1alpha1.MutationConfig{704Name: "mutation volume",705UpdateStrategy: string(ReplaceStrategy),706Volumes: []string{"some-ns/some-templ/volume_mutated1"},707},708},709templates: map[string]v1alpha1.Template{"some-ns/some-templ": templateWithAVolume},710want: []util.RenderItem{{711Render: `spec:712volumes:
713- configMap:
714name: istio
715name: volume_mutated1
716`}},717},718{719name: "replace_mutation_with_a_volume_replace_vol",720args: args{721obj: map[string]interface{}{"spec": map[string]interface{}{722"volumes": []interface{}{723map[string]interface{}{724"name": "volume_mutated1",725"image": "orig_img",726"resources": map[string]interface{}{727"limits": map[string]interface{}{"cpu": "orig_100m", "memory": "orig_100Mi"},728"requests": map[string]interface{}{"cpu": "orig_100m", "memory": "orig_100Mi"},729},730},731},732}},733
734config: v1alpha1.MutationConfig{735Name: "mutation volume",736UpdateStrategy: string(ReplaceStrategy),737Volumes: []string{"some-ns/some-templ/volume_mutated1"},738},739},740templates: map[string]v1alpha1.Template{"some-ns/some-templ": templateWithAVolumeWithIntersection},741want: []util.RenderItem{{742Render: `spec:743volumes:
744- configMap:
745name: istio
746name: volume_mutated1
747`}, {Render: `spec:748volumes:
749- configMap:
750name: istio-REPLACED
751name: volume_mutated1
752`}},753},754}755for _, tt := range tests {756t.Run(tt.name, func(t *testing.T) {757lib.ZapLogger = zap.NewNop()758
759rI := NewMutRenderer(baseMatch.NewMatcher(), nil)760r := rI.(*MutRenderer)761got := r.getRendersForPod(context.Background(), tt.templates, tt.args.obj, tt.args.config)762
763if len(got) != len(tt.want) {764t.Fatalf("len got = %v, len want = %v.\ngot: %v\n",765len(got), len(tt.want), got)766}767
768for i := range got {769if !reflect.DeepEqual(got[i].Render, tt.want[i].Render) {770t.Errorf("getRendersForPod()[%v].Render = \n%+v, want \n%+v", i, got[i].Render, tt.want[i].Render)771}772}773})774}775}
776
777func Test_convert(t *testing.T) {778type args struct {779i interface{}780}781tests := []struct {782name string783args args
784want interface{}785}{786{787name: "map string interface",788args: args{789i: map[string]interface{}{790"metadata": map[string]interface{}{791"test": "value",792},793},794},795want: map[string]interface{}{796"metadata": map[string]interface{}{797"test": "value",798},799},800},801{802name: "map slice of interfaces",803args: args{804i: []interface{}{805map[string]string{806"test": "value",807},808},809},810want: []interface{}{811map[string]string{"test": "value"},812},813},814}815for _, tt := range tests {816t.Run(tt.name, func(t *testing.T) {817if got := convert(tt.args.i); !reflect.DeepEqual(got, tt.want) {818t.Errorf("convert() = %v, want %v", got, tt.want)819}820})821}822}
823