podman

Форк
0
/
play_test.go 
1407 строк · 28.1 Кб
1
//go:build linux && !remote
2

3
package kube
4

5
import (
6
	"math"
7
	"runtime"
8
	"strconv"
9
	"testing"
10

11
	"github.com/containers/common/pkg/secrets"
12
	"github.com/containers/podman/v5/libpod/define"
13
	v1 "github.com/containers/podman/v5/pkg/k8s.io/api/core/v1"
14
	"github.com/containers/podman/v5/pkg/k8s.io/apimachinery/pkg/api/resource"
15
	v12 "github.com/containers/podman/v5/pkg/k8s.io/apimachinery/pkg/apis/meta/v1"
16
	"github.com/containers/podman/v5/pkg/k8s.io/apimachinery/pkg/util/intstr"
17
	"github.com/containers/podman/v5/pkg/specgen"
18
	"github.com/docker/docker/pkg/meminfo"
19
	"github.com/stretchr/testify/assert"
20
	"sigs.k8s.io/yaml"
21
)
22

23
func createSecrets(t *testing.T, d string) *secrets.SecretsManager {
24
	secretsManager, err := secrets.NewManager(d)
25
	assert.NoError(t, err)
26

27
	driver := "file"
28
	driverOpts := map[string]string{
29
		"path": d,
30
	}
31

32
	storeOpts := secrets.StoreOptions{
33
		DriverOpts: driverOpts,
34
	}
35

36
	for _, s := range k8sSecrets {
37
		data, err := yaml.Marshal(s)
38
		assert.NoError(t, err)
39

40
		_, err = secretsManager.Store(s.ObjectMeta.Name, data, driver, storeOpts)
41
		assert.NoError(t, err)
42
	}
43

44
	return secretsManager
45
}
46

47
func TestConfigMapVolumes(t *testing.T) {
48
	yes := true
49
	tests := []struct {
50
		name          string
51
		volume        v1.Volume
52
		configmaps    []v1.ConfigMap
53
		errorMessage  string
54
		expectedItems map[string][]byte
55
	}{
56
		{
57
			"VolumeFromConfigmap",
58
			v1.Volume{
59
				Name: "test-volume",
60
				VolumeSource: v1.VolumeSource{
61
					ConfigMap: &v1.ConfigMapVolumeSource{
62
						LocalObjectReference: v1.LocalObjectReference{
63
							Name: "bar",
64
						},
65
					},
66
				},
67
			},
68
			configMapList,
69
			"",
70
			map[string][]byte{"myvar": []byte("bar")},
71
		},
72
		{
73
			"VolumeFromBinaryConfigmap",
74
			v1.Volume{
75
				Name: "test-volume",
76
				VolumeSource: v1.VolumeSource{
77
					ConfigMap: &v1.ConfigMapVolumeSource{
78
						LocalObjectReference: v1.LocalObjectReference{
79
							Name: "binary-bar",
80
						},
81
					},
82
				},
83
			},
84
			configMapList,
85
			"",
86
			map[string][]byte{"myvar": []byte("bin-bar")},
87
		},
88
		{
89
			"ConfigmapMissing",
90
			v1.Volume{
91
				Name: "test-volume",
92
				VolumeSource: v1.VolumeSource{
93
					ConfigMap: &v1.ConfigMapVolumeSource{
94
						LocalObjectReference: v1.LocalObjectReference{
95
							Name: "fizz",
96
						},
97
					},
98
				},
99
			},
100
			configMapList,
101
			`no such ConfigMap "fizz"`,
102
			map[string][]byte{},
103
		},
104
		{
105
			"ConfigmapMissingOptional",
106
			v1.Volume{
107
				Name: "test-volume",
108
				VolumeSource: v1.VolumeSource{
109
					ConfigMap: &v1.ConfigMapVolumeSource{
110
						LocalObjectReference: v1.LocalObjectReference{
111
							Name: "fizz",
112
						},
113
						Optional: &yes,
114
					},
115
				},
116
			},
117
			configMapList,
118
			"",
119
			map[string][]byte{},
120
		},
121
		{
122
			"MultiValue",
123
			v1.Volume{
124
				Name: "test-volume",
125
				VolumeSource: v1.VolumeSource{
126
					ConfigMap: &v1.ConfigMapVolumeSource{
127
						LocalObjectReference: v1.LocalObjectReference{
128
							Name: "multi-item",
129
						},
130
						Optional: &yes,
131
					},
132
				},
133
			},
134
			configMapList,
135
			"",
136
			map[string][]byte{"foo": []byte("bar"), "fizz": []byte("buzz")},
137
		},
138
		{
139
			"SpecificValue",
140
			v1.Volume{
141
				Name: "test-volume",
142
				VolumeSource: v1.VolumeSource{
143
					ConfigMap: &v1.ConfigMapVolumeSource{
144
						LocalObjectReference: v1.LocalObjectReference{
145
							Name: "multi-item",
146
						},
147
						Optional: &yes,
148
						Items:    []v1.KeyToPath{{Key: "fizz", Path: "/custom/path"}},
149
					},
150
				},
151
			},
152
			configMapList,
153
			"",
154
			map[string][]byte{"/custom/path": []byte("buzz")},
155
		},
156
		{
157
			"MultiValueBinary",
158
			v1.Volume{
159
				Name: "test-volume",
160
				VolumeSource: v1.VolumeSource{
161
					ConfigMap: &v1.ConfigMapVolumeSource{
162
						LocalObjectReference: v1.LocalObjectReference{
163
							Name: "multi-binary-item",
164
						},
165
						Optional: &yes,
166
					},
167
				},
168
			},
169
			configMapList,
170
			"",
171
			map[string][]byte{"foo": []byte("bin-bar"), "fizz": []byte("bin-buzz")},
172
		},
173
		{
174
			"SpecificValueBinary",
175
			v1.Volume{
176
				Name: "test-volume",
177
				VolumeSource: v1.VolumeSource{
178
					ConfigMap: &v1.ConfigMapVolumeSource{
179
						LocalObjectReference: v1.LocalObjectReference{
180
							Name: "multi-binary-item",
181
						},
182
						Optional: &yes,
183
						Items:    []v1.KeyToPath{{Key: "fizz", Path: "/custom/path"}},
184
					},
185
				},
186
			},
187
			configMapList,
188
			"",
189
			map[string][]byte{"/custom/path": []byte("bin-buzz")},
190
		},
191
		{
192
			"DuplicateValues",
193
			v1.Volume{
194
				Name: "test-volume",
195
				VolumeSource: v1.VolumeSource{
196
					ConfigMap: &v1.ConfigMapVolumeSource{
197
						LocalObjectReference: v1.LocalObjectReference{
198
							Name: "dupe",
199
						},
200
					},
201
				},
202
			},
203
			configMapList,
204
			`the ConfigMap "dupe" is invalid: duplicate key "foo" present in data and binaryData`,
205
			map[string][]byte{},
206
		},
207
		{
208
			"DuplicateValuesSpecific",
209
			v1.Volume{
210
				Name: "test-volume",
211
				VolumeSource: v1.VolumeSource{
212
					ConfigMap: &v1.ConfigMapVolumeSource{
213
						LocalObjectReference: v1.LocalObjectReference{
214
							Name: "dupe",
215
						},
216
						Items: []v1.KeyToPath{{Key: "fizz", Path: "/custom/path"}},
217
					},
218
				},
219
			},
220
			configMapList,
221
			`the ConfigMap "dupe" is invalid: duplicate key "foo" present in data and binaryData`,
222
			map[string][]byte{},
223
		},
224
	}
225

226
	for _, test := range tests {
227
		test := test
228
		t.Run(test.name, func(t *testing.T) {
229
			result, err := VolumeFromConfigMap(test.volume.ConfigMap, test.configmaps)
230
			if test.errorMessage == "" {
231
				assert.NoError(t, err)
232
				assert.Equal(t, test.expectedItems, result.Items)
233
			} else {
234
				assert.Error(t, err)
235
				assert.Equal(t, test.errorMessage, err.Error())
236
			}
237
		})
238
	}
239
}
240

241
func TestEnvVarsFrom(t *testing.T) {
242
	d := t.TempDir()
243
	secretsManager := createSecrets(t, d)
244

245
	tests := []struct {
246
		name     string
247
		envFrom  v1.EnvFromSource
248
		options  CtrSpecGenOptions
249
		succeed  bool
250
		expected map[string]string
251
	}{
252
		{
253
			"ConfigMapExists",
254
			v1.EnvFromSource{
255
				ConfigMapRef: &v1.ConfigMapEnvSource{
256
					LocalObjectReference: v1.LocalObjectReference{
257
						Name: "foo",
258
					},
259
				},
260
			},
261
			CtrSpecGenOptions{
262
				ConfigMaps: configMapList,
263
			},
264
			true,
265
			map[string]string{
266
				"myvar": "foo",
267
			},
268
		},
269
		{
270
			"ConfigMapDoesNotExist",
271
			v1.EnvFromSource{
272
				ConfigMapRef: &v1.ConfigMapEnvSource{
273
					LocalObjectReference: v1.LocalObjectReference{
274
						Name: "doesnotexist",
275
					},
276
				},
277
			},
278
			CtrSpecGenOptions{
279
				ConfigMaps: configMapList,
280
			},
281
			false,
282
			nil,
283
		},
284
		{
285
			"OptionalConfigMapDoesNotExist",
286
			v1.EnvFromSource{
287
				ConfigMapRef: &v1.ConfigMapEnvSource{
288
					LocalObjectReference: v1.LocalObjectReference{
289
						Name: "doesnotexist",
290
					},
291
					Optional: &optional,
292
				},
293
			},
294
			CtrSpecGenOptions{
295
				ConfigMaps: configMapList,
296
			},
297
			true,
298
			map[string]string{},
299
		},
300
		{
301
			"EmptyConfigMapList",
302
			v1.EnvFromSource{
303
				ConfigMapRef: &v1.ConfigMapEnvSource{
304
					LocalObjectReference: v1.LocalObjectReference{
305
						Name: "foo",
306
					},
307
				},
308
			},
309
			CtrSpecGenOptions{
310
				ConfigMaps: []v1.ConfigMap{},
311
			},
312
			false,
313
			nil,
314
		},
315
		{
316
			"OptionalEmptyConfigMapList",
317
			v1.EnvFromSource{
318
				ConfigMapRef: &v1.ConfigMapEnvSource{
319
					LocalObjectReference: v1.LocalObjectReference{
320
						Name: "foo",
321
					},
322
					Optional: &optional,
323
				},
324
			},
325
			CtrSpecGenOptions{
326
				ConfigMaps: []v1.ConfigMap{},
327
			},
328
			true,
329
			map[string]string{},
330
		},
331
		{
332
			"SecretExists",
333
			v1.EnvFromSource{
334
				SecretRef: &v1.SecretEnvSource{
335
					LocalObjectReference: v1.LocalObjectReference{
336
						Name: "foo",
337
					},
338
				},
339
			},
340
			CtrSpecGenOptions{
341
				SecretsManager: secretsManager,
342
			},
343
			true,
344
			map[string]string{
345
				"myvar": "foo",
346
			},
347
		},
348
		{
349
			"SecretDoesNotExist",
350
			v1.EnvFromSource{
351
				SecretRef: &v1.SecretEnvSource{
352
					LocalObjectReference: v1.LocalObjectReference{
353
						Name: "doesnotexist",
354
					},
355
				},
356
			},
357
			CtrSpecGenOptions{
358
				SecretsManager: secretsManager,
359
			},
360
			false,
361
			nil,
362
		},
363
		{
364
			"SecretExistsMultipleDataEntries",
365
			v1.EnvFromSource{
366
				SecretRef: &v1.SecretEnvSource{
367
					LocalObjectReference: v1.LocalObjectReference{
368
						Name: "multi-data",
369
					},
370
				},
371
			},
372
			CtrSpecGenOptions{
373
				SecretsManager: secretsManager,
374
			},
375
			true,
376
			map[string]string{
377
				"myvar":  "foo",
378
				"myvar1": "foo1",
379
			},
380
		},
381
		{
382
			"SecretExistsMultipleStringDataEntries",
383
			v1.EnvFromSource{
384
				SecretRef: &v1.SecretEnvSource{
385
					LocalObjectReference: v1.LocalObjectReference{
386
						Name: "multi-stringdata",
387
					},
388
				},
389
			},
390
			CtrSpecGenOptions{
391
				SecretsManager: secretsManager,
392
			},
393
			true,
394
			map[string]string{
395
				"myvar":  "foo",
396
				"myvar1": "foo1",
397
			},
398
		},
399
		{
400
			"SecretExistsMultipleDataStringDataEntries",
401
			v1.EnvFromSource{
402
				SecretRef: &v1.SecretEnvSource{
403
					LocalObjectReference: v1.LocalObjectReference{
404
						Name: "multi-data-stringdata",
405
					},
406
				},
407
			},
408
			CtrSpecGenOptions{
409
				SecretsManager: secretsManager,
410
			},
411
			true,
412
			map[string]string{
413
				"myvardata":   "foodata",
414
				"myvar1":      "foo1string", // stringData overwrites data
415
				"myvarstring": "foostring",
416
			},
417
		},
418
		{
419
			"OptionalSecretDoesNotExist",
420
			v1.EnvFromSource{
421
				SecretRef: &v1.SecretEnvSource{
422
					LocalObjectReference: v1.LocalObjectReference{
423
						Name: "doesnotexist",
424
					},
425
					Optional: &optional,
426
				},
427
			},
428
			CtrSpecGenOptions{
429
				SecretsManager: secretsManager,
430
			},
431
			true,
432
			map[string]string{},
433
		},
434
	}
435

436
	for _, test := range tests {
437
		test := test
438
		t.Run(test.name, func(t *testing.T) {
439
			result, err := envVarsFrom(test.envFrom, &test.options)
440
			assert.Equal(t, err == nil, test.succeed)
441
			assert.Equal(t, test.expected, result)
442
		})
443
	}
444
}
445

446
func TestEnvVarValue(t *testing.T) {
447
	d := t.TempDir()
448
	secretsManager := createSecrets(t, d)
449
	stringNumCPUs := strconv.Itoa(runtime.NumCPU())
450

451
	mi, err := meminfo.Read()
452
	assert.Nil(t, err)
453
	stringMemTotal := strconv.FormatInt(mi.MemTotal, 10)
454

455
	tests := []struct {
456
		name     string
457
		envVar   v1.EnvVar
458
		options  CtrSpecGenOptions
459
		succeed  bool
460
		expected string
461
	}{
462
		{
463
			"ConfigMapExists",
464
			v1.EnvVar{
465
				Name: "FOO",
466
				ValueFrom: &v1.EnvVarSource{
467
					ConfigMapKeyRef: &v1.ConfigMapKeySelector{
468
						LocalObjectReference: v1.LocalObjectReference{
469
							Name: "foo",
470
						},
471
						Key: "myvar",
472
					},
473
				},
474
			},
475
			CtrSpecGenOptions{
476
				ConfigMaps: configMapList,
477
			},
478
			true,
479
			"foo",
480
		},
481
		{
482
			"ContainerKeyDoesNotExistInConfigMap",
483
			v1.EnvVar{
484
				Name: "FOO",
485
				ValueFrom: &v1.EnvVarSource{
486
					ConfigMapKeyRef: &v1.ConfigMapKeySelector{
487
						LocalObjectReference: v1.LocalObjectReference{
488
							Name: "foo",
489
						},
490
						Key: "doesnotexist",
491
					},
492
				},
493
			},
494
			CtrSpecGenOptions{
495
				ConfigMaps: configMapList,
496
			},
497
			false,
498
			nilString,
499
		},
500
		{
501
			"OptionalContainerKeyDoesNotExistInConfigMap",
502
			v1.EnvVar{
503
				Name: "FOO",
504
				ValueFrom: &v1.EnvVarSource{
505
					ConfigMapKeyRef: &v1.ConfigMapKeySelector{
506
						LocalObjectReference: v1.LocalObjectReference{
507
							Name: "foo",
508
						},
509
						Key:      "doesnotexist",
510
						Optional: &optional,
511
					},
512
				},
513
			},
514
			CtrSpecGenOptions{
515
				ConfigMaps: configMapList,
516
			},
517
			true,
518
			nilString,
519
		},
520
		{
521
			"ConfigMapDoesNotExist",
522
			v1.EnvVar{
523
				Name: "FOO",
524
				ValueFrom: &v1.EnvVarSource{
525
					ConfigMapKeyRef: &v1.ConfigMapKeySelector{
526
						LocalObjectReference: v1.LocalObjectReference{
527
							Name: "doesnotexist",
528
						},
529
						Key: "myvar",
530
					},
531
				},
532
			},
533
			CtrSpecGenOptions{
534
				ConfigMaps: configMapList,
535
			},
536
			false,
537
			nilString,
538
		},
539
		{
540
			"OptionalConfigMapDoesNotExist",
541
			v1.EnvVar{
542
				Name: "FOO",
543
				ValueFrom: &v1.EnvVarSource{
544
					ConfigMapKeyRef: &v1.ConfigMapKeySelector{
545
						LocalObjectReference: v1.LocalObjectReference{
546
							Name: "doesnotexist",
547
						},
548
						Key:      "myvar",
549
						Optional: &optional,
550
					},
551
				},
552
			},
553
			CtrSpecGenOptions{
554
				ConfigMaps: configMapList,
555
			},
556
			true,
557
			nilString,
558
		},
559
		{
560
			"EmptyConfigMapList",
561
			v1.EnvVar{
562
				Name: "FOO",
563
				ValueFrom: &v1.EnvVarSource{
564
					ConfigMapKeyRef: &v1.ConfigMapKeySelector{
565
						LocalObjectReference: v1.LocalObjectReference{
566
							Name: "foo",
567
						},
568
						Key: "myvar",
569
					},
570
				},
571
			},
572
			CtrSpecGenOptions{
573
				ConfigMaps: []v1.ConfigMap{},
574
			},
575
			false,
576
			nilString,
577
		},
578
		{
579
			"OptionalEmptyConfigMapList",
580
			v1.EnvVar{
581
				Name: "FOO",
582
				ValueFrom: &v1.EnvVarSource{
583
					ConfigMapKeyRef: &v1.ConfigMapKeySelector{
584
						LocalObjectReference: v1.LocalObjectReference{
585
							Name: "foo",
586
						},
587
						Key:      "myvar",
588
						Optional: &optional,
589
					},
590
				},
591
			},
592
			CtrSpecGenOptions{
593
				ConfigMaps: []v1.ConfigMap{},
594
			},
595
			true,
596
			nilString,
597
		},
598
		{
599
			"SecretExists",
600
			v1.EnvVar{
601
				Name: "FOO",
602
				ValueFrom: &v1.EnvVarSource{
603
					SecretKeyRef: &v1.SecretKeySelector{
604
						LocalObjectReference: v1.LocalObjectReference{
605
							Name: "foo",
606
						},
607
						Key: "myvar",
608
					},
609
				},
610
			},
611
			CtrSpecGenOptions{
612
				SecretsManager: secretsManager,
613
			},
614
			true,
615
			"foo",
616
		},
617
		{
618
			"ContainerKeyDoesNotExistInSecret",
619
			v1.EnvVar{
620
				Name: "FOO",
621
				ValueFrom: &v1.EnvVarSource{
622
					SecretKeyRef: &v1.SecretKeySelector{
623
						LocalObjectReference: v1.LocalObjectReference{
624
							Name: "foo",
625
						},
626
						Key: "doesnotexist",
627
					},
628
				},
629
			},
630
			CtrSpecGenOptions{
631
				SecretsManager: secretsManager,
632
			},
633
			false,
634
			nilString,
635
		},
636
		{
637
			"OptionalContainerKeyDoesNotExistInSecret",
638
			v1.EnvVar{
639
				Name: "FOO",
640
				ValueFrom: &v1.EnvVarSource{
641
					SecretKeyRef: &v1.SecretKeySelector{
642
						LocalObjectReference: v1.LocalObjectReference{
643
							Name: "foo",
644
						},
645
						Key:      "doesnotexist",
646
						Optional: &optional,
647
					},
648
				},
649
			},
650
			CtrSpecGenOptions{
651
				SecretsManager: secretsManager,
652
			},
653
			true,
654
			nilString,
655
		},
656
		{
657
			"SecretDoesNotExist",
658
			v1.EnvVar{
659
				Name: "FOO",
660
				ValueFrom: &v1.EnvVarSource{
661
					SecretKeyRef: &v1.SecretKeySelector{
662
						LocalObjectReference: v1.LocalObjectReference{
663
							Name: "doesnotexist",
664
						},
665
						Key: "myvar",
666
					},
667
				},
668
			},
669
			CtrSpecGenOptions{
670
				SecretsManager: secretsManager,
671
			},
672
			false,
673
			nilString,
674
		},
675
		{
676
			"OptionalSecretDoesNotExist",
677
			v1.EnvVar{
678
				Name: "FOO",
679
				ValueFrom: &v1.EnvVarSource{
680
					SecretKeyRef: &v1.SecretKeySelector{
681
						LocalObjectReference: v1.LocalObjectReference{
682
							Name: "doesnotexist",
683
						},
684
						Key:      "myvar",
685
						Optional: &optional,
686
					},
687
				},
688
			},
689
			CtrSpecGenOptions{
690
				SecretsManager: secretsManager,
691
			},
692
			true,
693
			nilString,
694
		},
695
		{
696
			"FieldRefMetadataName",
697
			v1.EnvVar{
698
				Name: "FOO",
699
				ValueFrom: &v1.EnvVarSource{
700
					FieldRef: &v1.ObjectFieldSelector{
701
						FieldPath: "metadata.name",
702
					},
703
				},
704
			},
705
			CtrSpecGenOptions{
706
				PodName: "test",
707
			},
708
			true,
709
			"test",
710
		},
711
		{
712
			"FieldRefMetadataUID",
713
			v1.EnvVar{
714
				Name: "FOO",
715
				ValueFrom: &v1.EnvVarSource{
716
					FieldRef: &v1.ObjectFieldSelector{
717
						FieldPath: "metadata.uid",
718
					},
719
				},
720
			},
721
			CtrSpecGenOptions{
722
				PodID: "ec71ff37c67b688598c0008187ab0960dc34e1dfdcbf3a74e3d778bafcfe0977",
723
			},
724
			true,
725
			"ec71ff37c67b688598c0008187ab0960dc34e1dfdcbf3a74e3d778bafcfe0977",
726
		},
727
		{
728
			"FieldRefMetadataLabelsExist",
729
			v1.EnvVar{
730
				Name: "FOO",
731
				ValueFrom: &v1.EnvVarSource{
732
					FieldRef: &v1.ObjectFieldSelector{
733
						FieldPath: "metadata.labels['label']",
734
					},
735
				},
736
			},
737
			CtrSpecGenOptions{
738
				Labels: map[string]string{"label": "label"},
739
			},
740
			true,
741
			"label",
742
		},
743
		{
744
			"FieldRefMetadataLabelsEmpty",
745
			v1.EnvVar{
746
				Name: "FOO",
747
				ValueFrom: &v1.EnvVarSource{
748
					FieldRef: &v1.ObjectFieldSelector{
749
						FieldPath: "metadata.labels['label']",
750
					},
751
				},
752
			},
753
			CtrSpecGenOptions{
754
				Labels: map[string]string{"label": ""},
755
			},
756
			true,
757
			"",
758
		},
759
		{
760
			"FieldRefMetadataLabelsNotExist",
761
			v1.EnvVar{
762
				Name: "FOO",
763
				ValueFrom: &v1.EnvVarSource{
764
					FieldRef: &v1.ObjectFieldSelector{
765
						FieldPath: "metadata.labels['label']",
766
					},
767
				},
768
			},
769
			CtrSpecGenOptions{},
770
			true,
771
			"",
772
		},
773
		{
774
			"FieldRefMetadataAnnotationsExist",
775
			v1.EnvVar{
776
				Name: "FOO",
777
				ValueFrom: &v1.EnvVarSource{
778
					FieldRef: &v1.ObjectFieldSelector{
779
						FieldPath: "metadata.annotations['annotation']",
780
					},
781
				},
782
			},
783
			CtrSpecGenOptions{
784
				Annotations: map[string]string{"annotation": "annotation"},
785
			},
786
			true,
787
			"annotation",
788
		},
789
		{
790
			"FieldRefMetadataAnnotationsEmpty",
791
			v1.EnvVar{
792
				Name: "FOO",
793
				ValueFrom: &v1.EnvVarSource{
794
					FieldRef: &v1.ObjectFieldSelector{
795
						FieldPath: "metadata.annotations['annotation']",
796
					},
797
				},
798
			},
799
			CtrSpecGenOptions{
800
				Annotations: map[string]string{"annotation": ""},
801
			},
802
			true,
803
			"",
804
		},
805
		{
806
			"FieldRefMetadataAnnotationsNotExist",
807
			v1.EnvVar{
808
				Name: "FOO",
809
				ValueFrom: &v1.EnvVarSource{
810
					FieldRef: &v1.ObjectFieldSelector{
811
						FieldPath: "metadata.annotations['annotation']",
812
					},
813
				},
814
			},
815
			CtrSpecGenOptions{},
816
			true,
817
			"",
818
		},
819
		{
820
			"FieldRefInvalid1",
821
			v1.EnvVar{
822
				Name: "FOO",
823
				ValueFrom: &v1.EnvVarSource{
824
					FieldRef: &v1.ObjectFieldSelector{
825
						FieldPath: "metadata.annotations['annotation]",
826
					},
827
				},
828
			},
829
			CtrSpecGenOptions{},
830
			false,
831
			nilString,
832
		},
833
		{
834
			"FieldRefInvalid2",
835
			v1.EnvVar{
836
				Name: "FOO",
837
				ValueFrom: &v1.EnvVarSource{
838
					FieldRef: &v1.ObjectFieldSelector{
839
						FieldPath: "metadata.dummy['annotation']",
840
					},
841
				},
842
			},
843
			CtrSpecGenOptions{},
844
			false,
845
			nilString,
846
		},
847
		{
848
			"FieldRefNotSupported",
849
			v1.EnvVar{
850
				Name: "FOO",
851
				ValueFrom: &v1.EnvVarSource{
852
					FieldRef: &v1.ObjectFieldSelector{
853
						FieldPath: "metadata.namespace",
854
					},
855
				},
856
			},
857
			CtrSpecGenOptions{},
858
			false,
859
			nilString,
860
		},
861
		{
862
			"ResourceFieldRefNotSupported",
863
			v1.EnvVar{
864
				Name: "FOO",
865
				ValueFrom: &v1.EnvVarSource{
866
					ResourceFieldRef: &v1.ResourceFieldSelector{
867
						Resource: "limits.dummy",
868
					},
869
				},
870
			},
871
			CtrSpecGenOptions{},
872
			false,
873
			nilString,
874
		},
875
		{
876
			"ResourceFieldRefMemoryDivisorNotValid",
877
			v1.EnvVar{
878
				Name: "FOO",
879
				ValueFrom: &v1.EnvVarSource{
880
					ResourceFieldRef: &v1.ResourceFieldSelector{
881
						Resource: "limits.memory",
882
						Divisor:  resource.MustParse("2M"),
883
					},
884
				},
885
			},
886
			CtrSpecGenOptions{},
887
			false,
888
			nilString,
889
		},
890
		{
891
			"ResourceFieldRefCpuDivisorNotValid",
892
			v1.EnvVar{
893
				Name: "FOO",
894
				ValueFrom: &v1.EnvVarSource{
895
					ResourceFieldRef: &v1.ResourceFieldSelector{
896
						Resource: "limits.cpu",
897
						Divisor:  resource.MustParse("2m"),
898
					},
899
				},
900
			},
901
			CtrSpecGenOptions{},
902
			false,
903
			nilString,
904
		},
905
		{
906
			"ResourceFieldRefNoDivisor",
907
			v1.EnvVar{
908
				Name: "FOO",
909
				ValueFrom: &v1.EnvVarSource{
910
					ResourceFieldRef: &v1.ResourceFieldSelector{
911
						Resource: "limits.memory",
912
					},
913
				},
914
			},
915
			CtrSpecGenOptions{
916
				Container: container,
917
			},
918
			true,
919
			memoryString,
920
		},
921
		{
922
			"ResourceFieldRefMemoryDivisor",
923
			v1.EnvVar{
924
				Name: "FOO",
925
				ValueFrom: &v1.EnvVarSource{
926
					ResourceFieldRef: &v1.ResourceFieldSelector{
927
						Resource: "limits.memory",
928
						Divisor:  resource.MustParse("1Mi"),
929
					},
930
				},
931
			},
932
			CtrSpecGenOptions{
933
				Container: container,
934
			},
935
			true,
936
			strconv.Itoa(int(math.Ceil(float64(memoryInt) / 1024 / 1024))),
937
		},
938
		{
939
			"ResourceFieldRefCpuDivisor",
940
			v1.EnvVar{
941
				Name: "FOO",
942
				ValueFrom: &v1.EnvVarSource{
943
					ResourceFieldRef: &v1.ResourceFieldSelector{
944
						Resource: "requests.cpu",
945
						Divisor:  resource.MustParse("1m"),
946
					},
947
				},
948
			},
949
			CtrSpecGenOptions{
950
				Container: container,
951
			},
952
			true,
953
			strconv.Itoa(int(float64(cpuInt) / 0.001)),
954
		},
955
		{
956
			"ResourceFieldRefNoLimitMemory",
957
			v1.EnvVar{
958
				Name: "FOO",
959
				ValueFrom: &v1.EnvVarSource{
960
					ResourceFieldRef: &v1.ResourceFieldSelector{
961
						Resource: "limits.memory",
962
					},
963
				},
964
			},
965
			CtrSpecGenOptions{
966
				Container: v1.Container{
967
					Name: "test",
968
				},
969
			},
970
			true,
971
			stringMemTotal,
972
		},
973
		{
974
			"ResourceFieldRefNoRequestMemory",
975
			v1.EnvVar{
976
				Name: "FOO",
977
				ValueFrom: &v1.EnvVarSource{
978
					ResourceFieldRef: &v1.ResourceFieldSelector{
979
						Resource: "requests.memory",
980
					},
981
				},
982
			},
983
			CtrSpecGenOptions{
984
				Container: v1.Container{
985
					Name: "test",
986
				},
987
			},
988
			true,
989
			stringMemTotal,
990
		},
991
		{
992
			"ResourceFieldRefNoLimitCPU",
993
			v1.EnvVar{
994
				Name: "FOO",
995
				ValueFrom: &v1.EnvVarSource{
996
					ResourceFieldRef: &v1.ResourceFieldSelector{
997
						Resource: "limits.cpu",
998
					},
999
				},
1000
			},
1001
			CtrSpecGenOptions{
1002
				Container: v1.Container{
1003
					Name: "test",
1004
				},
1005
			},
1006
			true,
1007
			stringNumCPUs,
1008
		},
1009
		{
1010
			"ResourceFieldRefNoRequestCPU",
1011
			v1.EnvVar{
1012
				Name: "FOO",
1013
				ValueFrom: &v1.EnvVarSource{
1014
					ResourceFieldRef: &v1.ResourceFieldSelector{
1015
						Resource: "requests.cpu",
1016
					},
1017
				},
1018
			},
1019
			CtrSpecGenOptions{
1020
				Container: v1.Container{
1021
					Name: "test",
1022
				},
1023
			},
1024
			true,
1025
			stringNumCPUs,
1026
		},
1027
	}
1028

1029
	for _, test := range tests {
1030
		test := test
1031
		t.Run(test.name, func(t *testing.T) {
1032
			result, err := envVarValue(test.envVar, &test.options)
1033
			assert.Equal(t, err == nil, test.succeed)
1034
			if test.expected == nilString {
1035
				assert.Nil(t, result)
1036
			} else {
1037
				assert.Equal(t, test.expected, *result)
1038
			}
1039
		})
1040
	}
1041
}
1042

1043
var (
1044
	nilString     = "<nil>"
1045
	configMapList = []v1.ConfigMap{
1046
		{
1047
			TypeMeta: v12.TypeMeta{
1048
				Kind: "ConfigMap",
1049
			},
1050
			ObjectMeta: v12.ObjectMeta{
1051
				Name: "bar",
1052
			},
1053
			Data: map[string]string{
1054
				"myvar": "bar",
1055
			},
1056
		},
1057
		{
1058
			TypeMeta: v12.TypeMeta{
1059
				Kind: "ConfigMap",
1060
			},
1061
			ObjectMeta: v12.ObjectMeta{
1062
				Name: "foo",
1063
			},
1064
			Data: map[string]string{
1065
				"myvar": "foo",
1066
			},
1067
		},
1068
		{
1069
			TypeMeta: v12.TypeMeta{
1070
				Kind: "ConfigMap",
1071
			},
1072
			ObjectMeta: v12.ObjectMeta{
1073
				Name: "binary-bar",
1074
			},
1075
			BinaryData: map[string][]byte{
1076
				"myvar": []byte("bin-bar"),
1077
			},
1078
		},
1079
		{
1080
			TypeMeta: v12.TypeMeta{
1081
				Kind: "ConfigMap",
1082
			},
1083
			ObjectMeta: v12.ObjectMeta{
1084
				Name: "multi-item",
1085
			},
1086
			Data: map[string]string{
1087
				"foo":  "bar",
1088
				"fizz": "buzz",
1089
			},
1090
		},
1091
		{
1092
			TypeMeta: v12.TypeMeta{
1093
				Kind: "ConfigMap",
1094
			},
1095
			ObjectMeta: v12.ObjectMeta{
1096
				Name: "multi-binary-item",
1097
			},
1098
			BinaryData: map[string][]byte{
1099
				"foo":  []byte("bin-bar"),
1100
				"fizz": []byte("bin-buzz"),
1101
			},
1102
		},
1103
		{
1104
			TypeMeta: v12.TypeMeta{
1105
				Kind: "ConfigMap",
1106
			},
1107
			ObjectMeta: v12.ObjectMeta{
1108
				Name: "dupe",
1109
			},
1110
			BinaryData: map[string][]byte{
1111
				"fiz": []byte("bin-buzz"),
1112
				"foo": []byte("bin-bar"),
1113
			},
1114
			Data: map[string]string{
1115
				"foo": "bar",
1116
			},
1117
		},
1118
	}
1119

1120
	optional = true
1121

1122
	k8sSecrets = []v1.Secret{
1123
		{
1124
			TypeMeta: v12.TypeMeta{
1125
				Kind: "Secret",
1126
			},
1127
			ObjectMeta: v12.ObjectMeta{
1128
				Name: "bar",
1129
			},
1130
			Data: map[string][]byte{
1131
				"myvar": []byte("bar"),
1132
			},
1133
		},
1134
		{
1135
			TypeMeta: v12.TypeMeta{
1136
				Kind: "Secret",
1137
			},
1138
			ObjectMeta: v12.ObjectMeta{
1139
				Name: "foo",
1140
			},
1141
			Data: map[string][]byte{
1142
				"myvar": []byte("foo"),
1143
			},
1144
		},
1145
		{
1146
			TypeMeta: v12.TypeMeta{
1147
				Kind: "Secret",
1148
			},
1149
			ObjectMeta: v12.ObjectMeta{
1150
				Name: "multi-data",
1151
			},
1152
			Data: map[string][]byte{
1153
				"myvar":  []byte("foo"),
1154
				"myvar1": []byte("foo1"),
1155
			},
1156
		},
1157
		{
1158
			TypeMeta: v12.TypeMeta{
1159
				Kind: "Secret",
1160
			},
1161
			ObjectMeta: v12.ObjectMeta{
1162
				Name: "multi-stringdata",
1163
			},
1164
			StringData: map[string]string{
1165
				"myvar":  string("foo"),
1166
				"myvar1": string("foo1"),
1167
			},
1168
		},
1169
		{
1170
			TypeMeta: v12.TypeMeta{
1171
				Kind: "Secret",
1172
			},
1173
			ObjectMeta: v12.ObjectMeta{
1174
				Name: "multi-data-stringdata",
1175
			},
1176
			Data: map[string][]byte{
1177
				"myvardata": []byte("foodata"),
1178
				"myvar1":    []byte("foo1data"),
1179
			},
1180
			StringData: map[string]string{
1181
				"myvarstring": string("foostring"),
1182
				"myvar1":      string("foo1string"),
1183
			},
1184
		},
1185
	}
1186

1187
	cpuInt       = 4
1188
	cpuString    = strconv.Itoa(cpuInt)
1189
	memoryInt    = 30000000
1190
	memoryString = strconv.Itoa(memoryInt)
1191
	container    = v1.Container{
1192
		Name: "test",
1193
		Resources: v1.ResourceRequirements{
1194
			Limits: v1.ResourceList{
1195
				v1.ResourceCPU:    resource.MustParse(cpuString),
1196
				v1.ResourceMemory: resource.MustParse(memoryString),
1197
			},
1198
			Requests: v1.ResourceList{
1199
				v1.ResourceCPU:    resource.MustParse(cpuString),
1200
				v1.ResourceMemory: resource.MustParse(memoryString),
1201
			},
1202
		},
1203
	}
1204
)
1205

1206
func TestHttpLivenessProbe(t *testing.T) {
1207
	tests := []struct {
1208
		name          string
1209
		specGenerator specgen.SpecGenerator
1210
		container     v1.Container
1211
		restartPolicy string
1212
		succeed       bool
1213
		expectedURL   string
1214
	}{
1215
		{
1216
			"HttpLivenessProbeUrlSetCorrectly",
1217
			specgen.SpecGenerator{},
1218
			v1.Container{
1219
				LivenessProbe: &v1.Probe{
1220
					Handler: v1.Handler{
1221
						HTTPGet: &v1.HTTPGetAction{
1222
							Scheme: "http",
1223
							Host:   "127.0.0.1",
1224
							Port:   intstr.FromInt(8080),
1225
							Path:   "/health",
1226
						},
1227
					},
1228
				},
1229
			},
1230
			"always",
1231
			true,
1232
			"http://127.0.0.1:8080/health",
1233
		},
1234
		{
1235
			"HttpLivenessProbeUrlUsesDefaults",
1236
			specgen.SpecGenerator{},
1237
			v1.Container{
1238
				LivenessProbe: &v1.Probe{
1239
					Handler: v1.Handler{
1240
						HTTPGet: &v1.HTTPGetAction{
1241
							Port: intstr.FromInt(80),
1242
						},
1243
					},
1244
				},
1245
			},
1246
			"always",
1247
			true,
1248
			"http://localhost:80/",
1249
		},
1250
		{
1251
			"HttpLivenessProbeNamedPort",
1252
			specgen.SpecGenerator{},
1253
			v1.Container{
1254
				LivenessProbe: &v1.Probe{
1255
					Handler: v1.Handler{
1256
						HTTPGet: &v1.HTTPGetAction{
1257
							Port: intstr.FromString("httpPort"),
1258
						},
1259
					},
1260
				},
1261
				Ports: []v1.ContainerPort{
1262
					{Name: "servicePort", ContainerPort: 7000},
1263
					{Name: "httpPort", ContainerPort: 8000},
1264
				},
1265
			},
1266
			"always",
1267
			true,
1268
			"http://localhost:8000/",
1269
		},
1270
	}
1271

1272
	for _, test := range tests {
1273
		test := test
1274
		t.Run(test.name, func(t *testing.T) {
1275
			err := setupLivenessProbe(&test.specGenerator, test.container, test.restartPolicy)
1276
			if err == nil {
1277
				assert.Equal(t, err == nil, test.succeed)
1278
				assert.Contains(t, test.specGenerator.ContainerHealthCheckConfig.HealthConfig.Test, test.expectedURL)
1279
			}
1280
		})
1281
	}
1282
}
1283

1284
func TestTCPLivenessProbe(t *testing.T) {
1285
	tests := []struct {
1286
		name          string
1287
		specGenerator specgen.SpecGenerator
1288
		container     v1.Container
1289
		restartPolicy string
1290
		succeed       bool
1291
		expectedHost  string
1292
		expectedPort  string
1293
	}{
1294
		{
1295
			"TCPLivenessProbeNormal",
1296
			specgen.SpecGenerator{},
1297
			v1.Container{
1298
				LivenessProbe: &v1.Probe{
1299
					Handler: v1.Handler{
1300
						TCPSocket: &v1.TCPSocketAction{
1301
							Host: "127.0.0.1",
1302
							Port: intstr.FromInt(8080),
1303
						},
1304
					},
1305
				},
1306
			},
1307
			"always",
1308
			true,
1309
			"127.0.0.1",
1310
			"8080",
1311
		},
1312
		{
1313
			"TCPLivenessProbeHostUsesDefault",
1314
			specgen.SpecGenerator{},
1315
			v1.Container{
1316
				LivenessProbe: &v1.Probe{
1317
					Handler: v1.Handler{
1318
						TCPSocket: &v1.TCPSocketAction{
1319
							Port: intstr.FromInt(200),
1320
						},
1321
					},
1322
				},
1323
			},
1324
			"always",
1325
			true,
1326
			"localhost",
1327
			"200",
1328
		},
1329
		{
1330
			"TCPLivenessProbeUseNamedPort",
1331
			specgen.SpecGenerator{},
1332
			v1.Container{
1333
				LivenessProbe: &v1.Probe{
1334
					Handler: v1.Handler{
1335
						TCPSocket: &v1.TCPSocketAction{
1336
							Port: intstr.FromString("servicePort"),
1337
							Host: "myservice.domain.com",
1338
						},
1339
					},
1340
				},
1341
				Ports: []v1.ContainerPort{
1342
					{ContainerPort: 6000},
1343
					{Name: "servicePort", ContainerPort: 4000},
1344
					{Name: "2ndServicePort", ContainerPort: 3000},
1345
				},
1346
			},
1347
			"always",
1348
			true,
1349
			"myservice.domain.com",
1350
			"4000",
1351
		},
1352
		{
1353
			"TCPLivenessProbeInvalidPortName",
1354
			specgen.SpecGenerator{},
1355
			v1.Container{
1356
				LivenessProbe: &v1.Probe{
1357
					Handler: v1.Handler{
1358
						TCPSocket: &v1.TCPSocketAction{
1359
							Port: intstr.FromString("3rdservicePort"),
1360
							Host: "myservice.domain.com",
1361
						},
1362
					},
1363
				},
1364
				Ports: []v1.ContainerPort{
1365
					{ContainerPort: 6000},
1366
					{Name: "servicePort", ContainerPort: 4000},
1367
					{Name: "2ndServicePort", ContainerPort: 3000},
1368
				},
1369
			},
1370
			"always",
1371
			false,
1372
			"myservice.domain.com",
1373
			"4000",
1374
		},
1375
		{
1376
			"TCPLivenessProbeNormalWithOnFailureRestartPolicy",
1377
			specgen.SpecGenerator{},
1378
			v1.Container{
1379
				LivenessProbe: &v1.Probe{
1380
					Handler: v1.Handler{
1381
						TCPSocket: &v1.TCPSocketAction{
1382
							Host: "127.0.0.1",
1383
							Port: intstr.FromInt(8080),
1384
						},
1385
					},
1386
				},
1387
			},
1388
			"on-failure",
1389
			true,
1390
			"127.0.0.1",
1391
			"8080",
1392
		},
1393
	}
1394

1395
	for _, test := range tests {
1396
		test := test
1397
		t.Run(test.name, func(t *testing.T) {
1398
			err := setupLivenessProbe(&test.specGenerator, test.container, test.restartPolicy)
1399
			assert.Equal(t, err == nil, test.succeed)
1400
			if err == nil {
1401
				assert.Equal(t, int(test.specGenerator.ContainerHealthCheckConfig.HealthCheckOnFailureAction), define.HealthCheckOnFailureActionRestart)
1402
				assert.Contains(t, test.specGenerator.ContainerHealthCheckConfig.HealthConfig.Test, test.expectedHost)
1403
				assert.Contains(t, test.specGenerator.ContainerHealthCheckConfig.HealthConfig.Test, test.expectedPort)
1404
			}
1405
		})
1406
	}
1407
}
1408

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

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

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

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