kubelatte-ce

Форк
2
Форк от sbertech/kubelatte-ce
/
mutate_test.go 
615 строк · 28.6 Кб
1
package mutation
2

3
import (
4
	"context"
5
	"fmt"
6
	"github.com/InVisionApp/conjungo"
7
	"github.com/Masterminds/sprig/v3"
8
	"github.com/wI2L/jsondiff"
9
	"gitverse.ru/ktrntrsv/kubelatte-ce/pkg/api/common"
10
	"gitverse.ru/ktrntrsv/kubelatte-ce/pkg/api/v1alpha1"
11
	"gitverse.ru/ktrntrsv/kubelatte-ce/pkg/observability/logger/lib"
12
	"gitverse.ru/ktrntrsv/kubelatte-ce/pkg/storage"
13
	"gitverse.ru/ktrntrsv/kubelatte-ce/pkg/util"
14
	"gitverse.ru/ktrntrsv/kubelatte-ce/pkg/util/env"
15
	baseMatch "gitverse.ru/ktrntrsv/kubelatte-ce/pkg/util/match"
16
	"gitverse.ru/ktrntrsv/kubelatte-ce/pkg/util/templates"
17
	"go.uber.org/zap"
18
	"html/template"
19
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
20
	"k8s.io/apimachinery/pkg/util/yaml"
21
	"log"
22
	"os"
23
	"reflect"
24
	"strings"
25
	"testing"
26
)
27

28
func TestMutateController_CheckMatchSelector(t *testing.T) {
29
	type args struct {
30
		config *v1alpha1.MutationConfig
31
		obj    ObjInfo
32
	}
33
	tests := []struct {
34
		name string
35
		args args
36
		want bool
37
	}{
38
		{
39
			name: "wrong operator",
40
			args: args{
41
				config: &v1alpha1.MutationConfig{
42
					LabelSelector: metav1.LabelSelector{
43
						MatchExpressions: []metav1.LabelSelectorRequirement{{Key: "", Values: []string{}, Operator: "s0m3 wr0n9 0p3rat0r"}}},
44
				},
45
				obj: ObjInfo{
46
					labels: map[string]string{"str": "str"},
47
				},
48
			},
49
			want: false,
50
		},
51
		{
52
			name: "matching",
53
			args: args{
54
				obj: ObjInfo{
55
					Kind:   "pod",
56
					name:   "name",
57
					labels: map[string]string{"str": "str"},
58
				},
59
				config: &v1alpha1.MutationConfig{
60
					ObjectSelector: v1alpha1.ObjectSelector{Kind: "pod", Name: "name"},
61
					LabelSelector: metav1.LabelSelector{
62
						MatchExpressions: []metav1.LabelSelectorRequirement{{Key: "", Values: []string{}, Operator: "s0m3 wr0n9 0p3rat0r"}}},
63
				},
64
			},
65
			want: true,
66
		},
67
	}
68
	for _, tt := range tests {
69
		t.Run(tt.name, func(t *testing.T) {
70
			lib.ZapLogger = zap.NewNop()
71

72
			r := &MutRenderer{}
73
			if got := r.checkMatchSelector(context.Background(), tt.args.config, tt.args.obj); got != tt.want {
74
				t.Errorf("checkMatchSelector() = %v, want %v", got, tt.want)
75
			}
76
		})
77
	}
78
}
79

80
func TestMutateController_GetRenders(t *testing.T) {
81
	tests := []struct {
82
		name     string
83
		obj      map[string]interface{}
84
		trigger  v1alpha1.Trigger
85
		template v1alpha1.Template
86
		want     []util.RenderItem
87
	}{
88
		{
89
			name: "merge",
90
			obj: map[string]interface{}{
91
				"metadata": map[string]interface{}{
92
					"annotations": map[string]interface{}{
93
						"ns/annotK": "enabled",
94
					},
95
					"labels": map[string]interface{}{
96
						"labK": "labV",
97
					},
98
				},
99
			},
100
			trigger: v1alpha1.Trigger{
101
				TypeMeta:   metav1.TypeMeta{},
102
				ObjectMeta: metav1.ObjectMeta{},
103
				Spec: v1alpha1.TriggerSpec{
104
					MutationConfigs: []v1alpha1.MutationConfig{{
105
						UpdateStrategy:      "",
106
						AnnotationNamespace: "ns",
107
						AnnotationTrigger:   "annotK",
108
						TemplateRefs:        []string{"templNs/templName"},
109
						LabelSelector: metav1.LabelSelector{
110
							MatchLabels: nil,
111
							MatchExpressions: []metav1.LabelSelectorRequirement{
112
								{
113
									Key:      "labK",
114
									Operator: "Exists",
115
									Values:   nil,
116
								},
117
							},
118
						},
119
					}}},
120
				Status: v1alpha1.TriggerStatus{},
121
			},
122
			template: v1alpha1.Template{
123
				TypeMeta: metav1.TypeMeta{},
124
				ObjectMeta: metav1.ObjectMeta{
125
					Namespace: "templNs",
126
					Name:      "templName",
127
				},
128
				Spec:   v1alpha1.TemplateSpec{},
129
				Status: v1alpha1.TemplateStatus{},
130
			},
131
			want: []util.RenderItem{{
132
				Template: v1alpha1.Template{
133
					TypeMeta: metav1.TypeMeta{},
134
					ObjectMeta: metav1.ObjectMeta{
135
						Namespace: "templNs",
136
						Name:      "templName",
137
					},
138
					Spec:   v1alpha1.TemplateSpec{},
139
					Status: v1alpha1.TemplateStatus{},
140
				},
141
				Render: "",
142
				Action: "",
143
			},
144
			},
145
		},
146
		{
147
			name: "replace",
148
			obj: map[string]interface{}{
149
				"metadata": map[string]interface{}{
150
					"annotations": map[string]interface{}{
151
						"ns/annotK": "enabled",
152
					},
153
					"labels": map[string]interface{}{
154
						"labK": "labV",
155
					},
156
				},
157
			},
158
			trigger: v1alpha1.Trigger{
159
				TypeMeta:   metav1.TypeMeta{},
160
				ObjectMeta: metav1.ObjectMeta{},
161
				Spec: v1alpha1.TriggerSpec{
162
					MutationConfigs: []v1alpha1.MutationConfig{{
163
						Name:                "",
164
						UpdateStrategy:      "replace",
165
						AnnotationNamespace: "ns",
166
						AnnotationTrigger:   "annotK",
167
						TemplateRefs:        []string{"templNs/templName"},
168
						LabelSelector: metav1.LabelSelector{
169
							MatchLabels: nil,
170
							MatchExpressions: []metav1.LabelSelectorRequirement{
171
								{
172
									Key:      "labK",
173
									Operator: "Exists",
174
									Values:   nil,
175
								},
176
							},
177
						},
178
					}}},
179
				Status: v1alpha1.TriggerStatus{},
180
			},
181
			template: v1alpha1.Template{
182
				TypeMeta: metav1.TypeMeta{},
183
				ObjectMeta: metav1.ObjectMeta{
184
					Namespace: "templNs",
185
					Name:      "templName",
186
				},
187
				Spec:   v1alpha1.TemplateSpec{},
188
				Status: v1alpha1.TemplateStatus{},
189
			},
190
			want: []util.RenderItem{{
191
				Template: v1alpha1.Template{
192
					TypeMeta: metav1.TypeMeta{},
193
					ObjectMeta: metav1.ObjectMeta{
194
						Namespace: "templNs",
195
						Name:      "templName",
196
					},
197
					Spec:   v1alpha1.TemplateSpec{},
198
					Status: v1alpha1.TemplateStatus{},
199
				},
200
				Render: "",
201
				Action: "replace",
202
			},
203
			},
204
		},
205
	}
206
	for _, tt := range tests {
207
		t.Run(tt.name, func(t *testing.T) {
208
			lib.ZapLogger = zap.NewNop()
209
			matcher := baseMatch.NewMatcher()
210
			renderer := NewMutRenderer(matcher, nil)
211
			r := Mutator{renderer}
212
			storage.Storage = &storage.StorageController{}
213
			storage.Storage.Start(false, false)
214
			storage.Storage.UpdateTrigger(&tt.trigger)
215
			storage.Storage.UpdateTemplate(&tt.template)
216

217
			if got := r.renderer.GetRenders(context.Background(), &common.ARFields{Object: tt.obj}); !reflect.DeepEqual(got, tt.want) {
218
				t.Errorf("getRenders() = %v, want %v", got, tt.want)
219
			}
220
		})
221
	}
222
}
223

224
func TestMutateController_Mutate(t *testing.T) {
225
	type args struct {
226
		obj map[string]interface{}
227
		raw []byte
228
	}
229
	tests := []struct {
230
		name     string
231
		trigger  v1alpha1.Trigger
232
		template v1alpha1.Template
233
		args     args
234
		want     []jsondiff.Operation
235
	}{
236
		{
237
			name: "ok",
238
			want: []jsondiff.Operation{
239
				{
240
					Value:    nil,
241
					OldValue: "annotV",
242
					Type:     "remove",
243
					From:     "",
244
					Path:     "/metadata/annotations/annotK",
245
				},
246
				{
247
					Value:    "annotVal",
248
					OldValue: nil,
249
					Type:     "add",
250
					From:     "",
251
					Path:     "/metadata/annotations/annotKey",
252
				},
253
				{
254
					Value:    nil,
255
					OldValue: map[string]interface{}{"labK": "labV"},
256
					Type:     "remove",
257
					From:     "",
258
					Path:     "/metadata/labels",
259
				},
260
			},
261
			args: args{
262
				obj: map[string]interface{}{
263
					"metadata": map[string]interface{}{
264
						"annotations": map[string]interface{}{
265
							"annotK": "annotV",
266
						},
267
						"labels": map[string]interface{}{
268
							"labK": "labV",
269
						},
270
					},
271
				},
272
				raw: []byte("{\n  \"metadata\": {\n    \"annotations\": {\n      \"annotKey\": \"annotVal\"\n    }\n  }\n}"),
273
			},
274
			trigger: v1alpha1.Trigger{
275
				TypeMeta:   metav1.TypeMeta{},
276
				ObjectMeta: metav1.ObjectMeta{},
277
				Spec: v1alpha1.TriggerSpec{
278
					MutationConfigs: []v1alpha1.MutationConfig{{
279
						Name:           "",
280
						UpdateStrategy: "",
281
						TemplateRefs:   []string{"templNs/templName"},
282
						LabelSelector: metav1.LabelSelector{
283
							MatchLabels: nil,
284
							MatchExpressions: []metav1.LabelSelectorRequirement{
285
								{
286
									Key:      "labK",
287
									Operator: "Exists",
288
									Values:   nil,
289
								},
290
							},
291
						},
292
					}}},
293
				Status: v1alpha1.TriggerStatus{},
294
			},
295
			template: v1alpha1.Template{
296
				TypeMeta: metav1.TypeMeta{},
297
				ObjectMeta: metav1.ObjectMeta{
298
					Namespace: "templNs",
299
					Name:      "templName",
300
				},
301
				Spec:   v1alpha1.TemplateSpec{},
302
				Status: v1alpha1.TemplateStatus{},
303
			},
304
		},
305
		{
306
			name: "ok2",
307
			args: args{
308
				obj: map[string]interface{}{
309
					"kind": "Pod",
310
					"metadata": map[string]interface{}{
311
						"annotations": map[string]interface{}{
312
							"ann_ns/ann_trig": "enabled",
313
						},
314
					},
315
				},
316
				raw: []byte("{\"spec\": {\"containers\": [{\"name\": \"cont1\",\"image\": \"noimage\"}]}}")},
317
			trigger: v1alpha1.Trigger{
318
				Spec: v1alpha1.TriggerSpec{
319
					MutationConfigs: []v1alpha1.MutationConfig{
320
						{
321
							AnnotationNamespace: "ann_ns",
322
							AnnotationTrigger:   "ann_trig",
323
							Name:                "mutation cfg",
324
							UpdateStrategy:      string(MergeStrategy),
325
							Containers:          []string{"some-ns/some-templ/container_mutated"}},
326
					},
327
				},
328
			},
329

330
			template: v1alpha1.Template{
331
				ObjectMeta: metav1.ObjectMeta{Namespace: "some-ns", Name: "some-templ"},
332
				Spec: v1alpha1.TemplateSpec{Data: `spec:
333
  containers:
334
    - name: container_mutated
335
      image: imagemut`,
336
				},
337
			},
338
			want: []jsondiff.Operation{
339
				{Type: "remove", Path: "/kind", OldValue: "Pod"},
340
				{Type: "remove", Path: "/metadata/annotations", OldValue: map[string]interface{}{"ann_ns/ann_trig": "enabled"}},
341
				{Value: map[string]interface{}{env.ServiceAnnotationPrefix + "mutation.resource": "true"}, Type: "add", Path: "/metadata/labels"},
342
				{Value: map[string]interface{}{
343
					"containers": []interface{}{
344
						map[string]interface{}{"image": "noimage", "name": "cont1"},
345
						map[string]interface{}{"image": "imagemut", "name": "container_mutated"},
346
					},
347
				}, Type: "add", Path: "/spec"},
348
			},
349
		},
350
		{
351
			name: "location",
352
			args: args{obj: map[string]interface{}{
353
				"Kind": "Deployment",
354
				"metadata": map[string]interface{}{
355
					"annotations": map[string]interface{}{
356
						"ann_ns/ann_trig": "enabled",
357
					},
358
				},
359
			},
360
				raw: []byte("{\n    \"apiVersion\": \"apps/v1\",\n    \"Kind\": \"Deployment\",\n    \"metadata\": {\n        \"name\": \"scope-volume-deployment\",\n        \"namespace\": \"kblt-dev\",\n        \"labels\": {\n            \"kblt.dev\": \"test\",\n            \"kblt.testname\": \"scope_volume_aft\",\n            \"app\": \"to-test-latte\"\n        },\n        \"annotations\": {\n            \"kblt.annotations/merge\": \"enabled\"\n        }\n    },\n    \"spec\": {\n        \"strategy\": {\n            \"type\": \"Recreate\"\n        },\n        \"replicas\": 1,\n        \"selector\": {\n            \"matchLabels\": {\n                \"app\": \"to-test-latte\"\n            }\n        },\n        \"template\": {\n            \"metadata\": {\n                \"labels\": {\n                    \"kblt.dev\": \"test\",\n                    \"kblt.testname\": \"scope_volume_aft\",\n                    \"app\": \"to-test-latte\",\n                    \"find-pod\": \"scope-volume-aft\",\n                    \"sidecar.istio.io/inject\": \"false\"\n                },\n                \"annotations\": {\n                    \"kblt.annotations/merge\": \"enabled\"\n                }\n            },\n            \"spec\": {\n                \"securityContext\": {\n                    \"seccompProfile\": {\n                        \"type\": \"RuntimeDefault\"\n                    },\n                    \"runAsNonRoot\": true\n                },\n                \"containers\": [\n                    {\n                        \"name\": \"to-test-latte-2\",\n                        \"image\": \"dzo.sw.sbc.space/sbt/ci90000221_fedmesh/federation-demo@sha256:548cc416011c86bb1e2c6d06289aab0771a0f749c044656deaac5fc86d891fea\",\n                        \"securityContext\": {\n                            \"capabilities\": {\n                                \"drop\": [\n                                    \"ALL\"\n                                ]\n                            },\n                            \"allowPrivilegeEscalation\": false\n                        },\n                        \"resources\": {\n                            \"limits\": {\n                                \"cpu\": \"100m\",\n                                \"memory\": \"100Mi\"\n                            },\n                            \"requests\": {\n                                \"cpu\": \"100m\",\n                                \"memory\": \"100Mi\"\n                            }\n                        }\n                    },\n                    {\n                        \"name\": \"to-test-latte-1\",\n                        \"image\": \"dzo.sw.sbc.space/sbt/ci90000221_fedmesh/federation-demo@sha256:548cc416011c86bb1e2c6d06289aab0771a0f749c044656deaac5fc86d891fea\",\n                        \"securityContext\": {\n                            \"capabilities\": {\n                                \"drop\": [\n                                    \"ALL\"\n                                ]\n                            },\n                            \"allowPrivilegeEscalation\": false\n                        },\n                        \"resources\": {\n                            \"limits\": {\n                                \"cpu\": \"100m\",\n                                \"memory\": \"100Mi\"\n                            },\n                            \"requests\": {\n                                \"cpu\": \"100m\",\n                                \"memory\": \"100Mi\"\n                            }\n                        }\n                    }\n                ],\n                \"volumes\": [\n                    {\n                        \"name\": \"test-volume-1\",\n                        \"emptyDir\": {\n                            \"sizeLimit\": \"49Mi\"\n                        }\n                    }\n                ]\n            }\n        }\n    }\n}")},
361
			trigger: v1alpha1.Trigger{
362
				Spec: v1alpha1.TriggerSpec{
363
					MutationConfigs: []v1alpha1.MutationConfig{
364
						{
365
							AnnotationNamespace: "ann_ns",
366
							AnnotationTrigger:   "ann_trig",
367
							Name:                "mutation cfg",
368
							UpdateStrategy:      string(ReplaceStrategy),
369
							TemplateRefs:        []string{"some-ns/some-templ"}},
370
					},
371
				},
372
			},
373

374
			template: v1alpha1.Template{
375
				ObjectMeta: metav1.ObjectMeta{Namespace: "some-ns", Name: "some-templ"},
376
				Spec: v1alpha1.TemplateSpec{Data: `
377

378
      name: container_mutated
379
      image: imagemut
380
  `,
381
					Location: "spec.template.spec.containers[@.name==`to-test-latte-2`]",
382
				},
383
			},
384
			want: []jsondiff.Operation{
385
				{
386
					Value: "apps/v1",
387
					Path:  "/apiVersion",
388
					Type:  "add",
389
				},
390
				{
391
					Type:     "remove",
392
					Path:     "/metadata/annotations/ann_ns~1ann_trig",
393
					OldValue: "enabled",
394
				},
395
				{
396
					Value: "enabled",
397
					Type:  "add",
398
					Path:  "/metadata/annotations/kblt.annotations~1merge",
399
				},
400
				{
401
					Value: map[string]interface{}{"app": "to-test-latte", "kblt.dev": "test", env.ServiceAnnotationPrefix + "mutation.resource": "true", "kblt.testname": "scope_volume_aft"},
402
					Type:  "add",
403
					Path:  "/metadata/labels",
404
				},
405
				{
406
					Value: "scope-volume-deployment",
407
					Type:  "add",
408
					Path:  "/metadata/name",
409
				},
410
				{
411
					Value:    "kblt-dev",
412
					OldValue: nil,
413
					Type:     "add",
414
					From:     "",
415
					Path:     "/metadata/namespace",
416
				},
417
				{
418
					Value: map[string]interface{}{"replicas": float64(1),
419
						"selector": map[string]interface{}{"matchLabels": map[string]interface{}{"app": "to-test-latte"}},
420
						"strategy": map[string]interface{}{"type": "Recreate"},
421
						"template": map[string]interface{}{"metadata": map[string]interface{}{"annotations": map[string]interface{}{"kblt.annotations/merge": "enabled"},
422
							"labels": map[string]interface{}{"app": "to-test-latte", "find-pod": "scope-volume-aft", "kblt.dev": "test", "kblt.testname": "scope_volume_aft", "sidecar.istio.io/inject": "false"}},
423
							"spec": map[string]interface{}{"containers": []interface{}{map[string]interface{}{"image": "imagemut", "name": "container_mutated"}, map[string]interface{}{"image": "dzo.sw.sbc.space/sbt/ci90000221_fedmesh/federation-demo@sha256:548cc416011c86bb1e2c6d06289aab0771a0f749c044656deaac5fc86d891fea", "name": "to-test-latte-1", "resources": map[string]interface{}{"limits": map[string]interface{}{"cpu": "100m", "memory": "100Mi"}, "requests": map[string]interface{}{"cpu": "100m", "memory": "100Mi"}}, "securityContext": map[string]interface{}{"allowPrivilegeEscalation": false, "capabilities": map[string]interface{}{"drop": []interface{}{"ALL"}}}}},
424
								"securityContext": map[string]interface{}{"runAsNonRoot": true, "seccompProfile": map[string]interface{}{"type": "RuntimeDefault"}}, "volumes": []interface{}{map[string]interface{}{"emptyDir": map[string]interface{}{"sizeLimit": "49Mi"}, "name": "test-volume-1"}}},
425
						}},
426
					Type: "add",
427
					Path: "/spec",
428
				},
429
			},
430
		},
431
	}
432
	for _, tt := range tests {
433
		t.Run(tt.name, func(t *testing.T) {
434
			lib.ZapLogger = zap.NewNop()
435
			matcher := baseMatch.NewMatcher()
436
			renderer := NewMutRenderer(matcher, nil)
437
			r := NewMutator(renderer)
438
			storage.Storage = &storage.StorageController{}
439
			storage.Storage.Start(false, false)
440
			storage.Storage.UpdateTrigger(&tt.trigger)
441
			storage.Storage.UpdateTemplate(&tt.template)
442

443
			if got, _ := r.ApplyMutation(context.Background(), &common.ARFields{Object: tt.args.obj}, tt.args.raw); !reflect.DeepEqual(got, tt.want) {
444
				t.Errorf("ApplyMutation() = %v, want %v\n", got, tt.want)
445
				for i := 0; i < len(got); i++ {
446
					fmt.Printf("%v: result: %+v\n", i, got[i])
447
					fmt.Printf("%v: want  : %+v\n", i, tt.want[i])
448
				}
449
			}
450
		})
451
	}
452
}
453

454
func TestMergeFunc(t *testing.T) {
455
	ym1 := "containers: \n - name: test\n   image: aaaaaa\n   testdt:\n    - asda\n    - adad\n    - cvbcvb\n - name: test1\n   image: bbbbbb\n - name: test2\n   image: cccccc    "
456
	ym2 := "containers: \n - name: test\n   image: ssssss\n   testdt:\n    - xxx\n    - yyy\n    - zzz\n - name: test2\n   image: zzzzzz    "
457
	var obj1 map[string]interface{}
458
	var obj2 map[string]interface{}
459
	yaml.Unmarshal([]byte(ym1), &obj1)
460
	yaml.Unmarshal([]byte(ym2), &obj2)
461
	opts := conjungo.NewOptions()
462
	opts.SetKindMergeFunc(
463
		reflect.Slice,
464

465
		func(t, s reflect.Value, o *conjungo.Options) (reflect.Value, error) {
466
			aT, _ := t.Interface().([]interface{})
467
			aS, _ := s.Interface().([]interface{})
468

469
			aT = util.MergeSlice(aT, aS)
470

471
			return reflect.ValueOf(aT), nil
472
		},
473
	)
474
	opts.Overwrite = false
475
	err := conjungo.Merge(&obj1, obj2, opts)
476
	if err != nil {
477
		fmt.Printf("%s", err)
478
	}
479
	fmt.Printf("Data %v\n", obj1)
480
}
481

482
func TestRangeTemplate(t *testing.T) {
483
	data := "spec:\n      template:\n          spec:\n            containers:\n            {{% range .spec.template.spec.containers %}}\n              - name: {{% .name %}}\n                securityContext:\n                  privileged: false\n                  runAsUser: 10000\n                  runAsGroup: 5000\n                  readOnlyRootFilesystem: true\n                  allowPrivilegeEscalation: false\n                  capabilities:\n                    drop:\n                      - ALL       \n            {{% end %}}"
484
	templateEngine := template.New("common").
485
		Delims("{{%", "%}}").
486
		Funcs(template.FuncMap{
487
			"fromYaml": templates.FromYAML,
488
		}).
489
		Funcs(sprig.TxtFuncMap())
490
	temp, err := templateEngine.New("test").Parse(data)
491
	if err != nil {
492
		log.Fatalf("Failed parse %s", err)
493
	}
494

495
	var inputObj interface{}
496
	input := "apiVersion: apps/v1\nKind: Deployment\nmetadata:\n  name: test-igeg\n  namespace: synapse-metrics-system\n  annotations:\n    kblt.synapse/deploymentigeg: enabled\n    kblt.synapse/deployment-all: enabled\n  labels:\n    secman-injector: enabled\n    user-label: 'true'\nspec:\n  replicas: 1\n  selector:\n    matchLabels:\n      app: egw-syn-metrics-synapse-metrics-system\n      istio: egw-syn-metrics-synapse-metrics-system\n  template:\n    metadata:\n      labels:\n        app: egw-syn-metrics-synapse-metrics-system\n        istio: egw-syn-metrics-synapse-metrics-system\n      annotations:\n        openshift.io/scc: restricted\n        sidecar.istio.io/inject: 'false'\n    spec:\n      volumes:\n        - configMap:\n            defaultMode: 256\n            name: istio-basic\n            optional: true\n          name: config-volume\n        - name: istiod-ca-cert\n          configMap:\n            name: istio-ca-root-cert\n            defaultMode: 256\n        - name: podinfo\n          downwardAPI:\n            items:\n              - path: labels\n                fieldRef:\n                  apiVersion: v1\n                  fieldPath: metadata.labels\n              - path: annotations\n                fieldRef:\n                  apiVersion: v1\n                  fieldPath: metadata.annotations\n            defaultMode: 256\n        - name: istio-envoy\n          emptyDir: {}\n        - name: istio-data\n          emptyDir: {}\n        - name: istio-token\n          projected:\n            sources:\n              - serviceAccountToken:\n                  audience: istio-ca\n                  expirationSeconds: 43200\n                  path: istio-token\n            defaultMode: 256\n      containers:\n        - name: istio-proxy\n          image: image\n          args:\n            - proxy\n            - router\n            - '--domain'\n            - $(POD_NAMESPACE).svc.cluster.local\n            - '--proxyLogLevel=warning'\n            - '--proxyComponentLogLevel=misc:error'\n            - '--log_output_level=default:info'\n            - '--serviceCluster'\n            - $(POD_NAMESPACE)\n            - '--trust-domain=cluster.local'\n          ports:\n            - name: status-port\n              containerPort: 15021\n              protocol: TCP\n            - name: https-kubeapi\n              containerPort: 4443\n              protocol: TCP\n          env:\n            - name: JWT_POLICY\n              value: first-party-jwt\n            - name: TRUST_DOMAIN\n              value: cluster.local\n            - name: ISTIO_META_UNPRIVILEGED_POD\n              value: 'true'\n            - name: PILOT_CERT_PROVIDER\n              value: istiod\n            - name: CA_ADDR\n              value: blabla.ci00000-cp.svc:15012\n            - name: NODE_NAME\n              valueFrom:\n                fieldRef:\n                  apiVersion: v1\n                  fieldPath: spec.nodeName\n            - name: POD_NAME\n              valueFrom:\n                fieldRef:\n                  apiVersion: v1\n                  fieldPath: metadata.name\n            - name: POD_NAMESPACE\n              valueFrom:\n                fieldRef:\n                  apiVersion: v1\n                  fieldPath: metadata.namespace\n            - name: INSTANCE_IP\n              valueFrom:\n                fieldRef:\n                  apiVersion: v1\n                  fieldPath: status.podIP\n            - name: HOST_IP\n              valueFrom:\n                fieldRef:\n                  apiVersion: v1\n                  fieldPath: status.hostIP\n            - name: SERVICE_ACCOUNT\n              valueFrom:\n                fieldRef:\n                  apiVersion: v1\n                  fieldPath: spec.serviceAccountName\n            - name: CANONICAL_SERVICE\n              valueFrom:\n                fieldRef:\n                  apiVersion: v1\n                  fieldPath: metadata.labels['service.istio.io/canonical-name']\n            - name: CANONICAL_REVISION\n              valueFrom:\n                fieldRef:\n                  apiVersion: v1\n                  fieldPath: metadata.labels['service.istio.io/canonical-revision']\n            - name: ISTIO_META_WORKLOAD_NAME\n              value: egressgateway-synapse-metrics\n            - name: ISTIO_META_OWNER\n              value: >-\n                kubernetes://apis/apps/v1/namespaces/synapse-metrics-system/deployments/egw-syn-metrics-synapse-metrics-system\n            - name: ISTIO_META_MESH_ID\n              value: cluster.local\n            - name: ISTIO_META_ROUTER_MODE\n              value: sni-dnat\n            - name: ISTIO_META_CLUSTER_ID\n              value: Kubernetes\n          resources:\n            limits:\n              cpu: 300m\n              ephemeral-storage: 500Mi\n              memory: 500Mi\n            requests:\n              cpu: 300m\n              ephemeral-storage: 500Mi\n              memory: 500Mi\n          volumeMounts:\n            - mountPath: /etc/istio/config\n              name: config-volume\n            - name: istio-envoy\n              mountPath: /etc/istio/proxy\n            - name: istiod-ca-cert\n              mountPath: /var/run/secrets/istio\n            - name: podinfo\n              mountPath: /etc/istio/pod\n            - name: istio-token\n              readOnly: true\n              mountPath: /var/run/secrets/tokens\n            - name: istio-data\n              mountPath: /var/lib/istio/data\n          readinessProbe:\n            httpGet:\n              path: /healthz/ready\n              port: 15021\n              scheme: HTTP\n            initialDelaySeconds: 1\n            timeoutSeconds: 1\n            periodSeconds: 2\n            successThreshold: 1\n            failureThreshold: 30\n          terminationMessagePath: /dev/termination-log\n          terminationMessagePolicy: File\n          imagePullPolicy: Always\n          securityContext:\n            readOnlyRootFilesystem: true\n      restartPolicy: Always\n      terminationGracePeriodSeconds: 30\n      dnsPolicy: ClusterFirst\n      affinity:\n        nodeAffinity:\n          requiredDuringSchedulingIgnoredDuringExecution:\n            nodeSelectorTerms:\n              - matchExpressions:\n                  - key: kubernetes.io/arch\n                    operator: In\n                    values:\n                      - amd64\n                      - ppc64le\n                      - s390x\n          preferredDuringSchedulingIgnoredDuringExecution:\n            - weight: 2\n              preference:\n                matchExpressions:\n                  - key: kubernetes.io/arch\n                    operator: In\n                    values:\n                      - amd64\n            - weight: 2\n              preference:\n                matchExpressions:\n                  - key: kubernetes.io/arch\n                    operator: In\n                    values:\n                      - ppc64le\n            - weight: 2\n              preference:\n                matchExpressions:\n                  - key: kubernetes.io/arch\n                    operator: In\n                    values:\n                      - s390x\n      schedulerName: default-scheduler\n  strategy:\n    type: RollingUpdate\n    rollingUpdate:\n      maxUnavailable: 25%\n      maxSurge: 100%\n  revisionHistoryLimit: 10\n  progressDeadlineSeconds: 600"
497
	err = yaml.Unmarshal([]byte(input), &inputObj)
498
	if err != nil {
499
		log.Fatalf("Failed Unmarshal %s", err)
500
	}
501

502
	var tempBuffer strings.Builder
503
	err = temp.Execute(&tempBuffer, inputObj)
504
	if err != nil {
505
		log.Fatalf("Failed Execute %s", err)
506
	}
507

508
	log.Printf("%s", tempBuffer.String())
509
}
510

511
func TestGetSelector(t *testing.T) {
512
	os.Setenv("CONFIGS_PATH", "./configs")
513
	os.Setenv("LOGS_PATH", "./logs")
514
	os.Setenv("TMPDIR", "./logs")
515
	os.Setenv("KBLT_PORT_MAIN", "9998")
516
	os.Setenv("KBLT_PORT_LOG", "9999")
517
	os.Setenv("KBLT_ENABLED_TRIGGER_PREFIX", "true")
518

519
	//noexception
520
	getSelectorKey("simple-key", []string{"value"})
521
	//exception
522
	os.Setenv("KBLT_PREFIX_EXCEPTION", "true")
523
	env.InitEnvWebhookServer()
524
	getSelectorKey("simple-key", []string{"value"})
525
	//istio
526
	os.Setenv("KBLT_PREFIX_EXCEPTION", "true")
527
	env.InitEnvWebhookServer()
528
	getSelectorKey("app", []string{"istiod"})
529
}
530

531
func TestGetNewEmtyObject(t *testing.T) {
532
	lib.ZapLogger = zap.NewNop()
533

534
	ctrl := Mutator{}
535
	obj := ctrl.getNewObject(context.Background(), util.RenderItem{}, nil)
536

537
	if obj != nil {
538
		t.Errorf("should be nil object")
539
	}
540
}
541

542
func TestGetNewBrokenObject(t *testing.T) {
543
	lib.ZapLogger = zap.NewNop()
544

545
	ctrl := Mutator{}
546
	obj := ctrl.getNewObject(context.Background(), util.RenderItem{}, []byte("1"))
547

548
	if obj != nil {
549
		t.Errorf("should be nil object")
550
	}
551
}
552

553
func TestController_getNewObject(t *testing.T) {
554
	lib.ZapLogger = zap.NewNop()
555

556
	type args struct {
557
		templateRender util.RenderItem
558
		raw            []byte
559
	}
560
	tests := []struct {
561
		name    string
562
		args    args
563
		wantMap bool
564
	}{
565
		{
566
			name: "templateRender.Template.Spec.Location != ''",
567
			args: args{
568
				templateRender: util.RenderItem{
569
					Template: v1alpha1.Template{
570
						Spec: v1alpha1.TemplateSpec{
571
							Location: "location",
572
						},
573
					},
574
				},
575
				raw: []byte("{\"key\": \"value\"}"),
576
			},
577
			wantMap: true,
578
		},
579
		{
580
			name: "error when Unmarshal",
581
			args: args{
582
				templateRender: util.RenderItem{
583
					Render: "1",
584
				},
585
				raw: []byte("{\"key\": \"value\"}"),
586
			},
587
			wantMap: false,
588
		},
589
		{
590
			name: "error when Unmarshal with location",
591
			args: args{
592
				templateRender: util.RenderItem{
593
					Render: "1",
594
					Template: v1alpha1.Template{
595
						Spec: v1alpha1.TemplateSpec{
596
							Location: "location",
597
						},
598
					},
599
				},
600
				raw: []byte("{\"key\": \"value\"}"),
601
			},
602
			wantMap: true,
603
		},
604
	}
605
	for _, tt := range tests {
606
		t.Run(tt.name, func(t *testing.T) {
607
			r := &Mutator{}
608
			got := r.getNewObject(context.Background(), tt.args.templateRender, tt.args.raw)
609

610
			if (got != nil) != tt.wantMap {
611
				t.Errorf("return map required")
612
			}
613
		})
614
	}
615
}
616

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.