1
16
17 package securitycontext
18
19 import (
20 "reflect"
21 "testing"
22
23 "k8s.io/apimachinery/pkg/util/diff"
24 api "k8s.io/kubernetes/pkg/apis/core"
25 "k8s.io/utils/pointer"
26 )
27
28 func TestPodSecurityContextAccessor(t *testing.T) {
29 fsGroup := int64(2)
30 runAsUser := int64(1)
31 runAsGroup := int64(1)
32 runAsNonRoot := true
33
34 testcases := []*api.PodSecurityContext{
35 nil,
36 {},
37 {FSGroup: &fsGroup},
38 {HostIPC: true},
39 {HostNetwork: true},
40 {HostPID: true},
41 {RunAsNonRoot: &runAsNonRoot},
42 {RunAsUser: &runAsUser},
43 {RunAsGroup: &runAsGroup},
44 {SELinuxOptions: &api.SELinuxOptions{User: "bob"}},
45 {SeccompProfile: &api.SeccompProfile{Type: api.SeccompProfileTypeRuntimeDefault}},
46 {SupplementalGroups: []int64{1, 2, 3}},
47 }
48
49 for i, tc := range testcases {
50 expected := tc
51 if expected == nil {
52 expected = &api.PodSecurityContext{}
53 }
54
55 a := NewPodSecurityContextAccessor(tc)
56
57 if v := a.FSGroup(); !reflect.DeepEqual(expected.FSGroup, v) {
58 t.Errorf("%d: expected %#v, got %#v", i, expected.FSGroup, v)
59 }
60 if v := a.HostIPC(); !reflect.DeepEqual(expected.HostIPC, v) {
61 t.Errorf("%d: expected %#v, got %#v", i, expected.HostIPC, v)
62 }
63 if v := a.HostNetwork(); !reflect.DeepEqual(expected.HostNetwork, v) {
64 t.Errorf("%d: expected %#v, got %#v", i, expected.HostNetwork, v)
65 }
66 if v := a.HostPID(); !reflect.DeepEqual(expected.HostPID, v) {
67 t.Errorf("%d: expected %#v, got %#v", i, expected.HostPID, v)
68 }
69 if v := a.RunAsNonRoot(); !reflect.DeepEqual(expected.RunAsNonRoot, v) {
70 t.Errorf("%d: expected %#v, got %#v", i, expected.RunAsNonRoot, v)
71 }
72 if v := a.RunAsUser(); !reflect.DeepEqual(expected.RunAsUser, v) {
73 t.Errorf("%d: expected %#v, got %#v", i, expected.RunAsUser, v)
74 }
75 if v := a.RunAsGroup(); !reflect.DeepEqual(expected.RunAsGroup, v) {
76 t.Errorf("%d: expected %#v, got %#v", i, expected.RunAsGroup, v)
77 }
78 if v := a.SeccompProfile(); !reflect.DeepEqual(expected.SeccompProfile, v) {
79 t.Errorf("%d: expected %#v, got %#v", i, expected.SeccompProfile, v)
80 }
81 if v := a.SELinuxOptions(); !reflect.DeepEqual(expected.SELinuxOptions, v) {
82 t.Errorf("%d: expected %#v, got %#v", i, expected.SELinuxOptions, v)
83 }
84 if v := a.SupplementalGroups(); !reflect.DeepEqual(expected.SupplementalGroups, v) {
85 t.Errorf("%d: expected %#v, got %#v", i, expected.SupplementalGroups, v)
86 }
87 }
88 }
89
90 func TestPodSecurityContextMutator(t *testing.T) {
91 testcases := map[string]struct {
92 newSC func() *api.PodSecurityContext
93 }{
94 "nil": {
95 newSC: func() *api.PodSecurityContext { return nil },
96 },
97 "zero": {
98 newSC: func() *api.PodSecurityContext { return &api.PodSecurityContext{} },
99 },
100 "populated": {
101 newSC: func() *api.PodSecurityContext {
102 return &api.PodSecurityContext{
103 HostNetwork: true,
104 HostIPC: true,
105 HostPID: true,
106 SELinuxOptions: &api.SELinuxOptions{},
107 RunAsUser: nil,
108 RunAsGroup: nil,
109 RunAsNonRoot: nil,
110 SeccompProfile: nil,
111 SupplementalGroups: nil,
112 FSGroup: nil,
113 }
114 },
115 },
116 }
117
118 nonNilSC := func(sc *api.PodSecurityContext) *api.PodSecurityContext {
119 if sc == nil {
120 return &api.PodSecurityContext{}
121 }
122 return sc
123 }
124
125 for k, tc := range testcases {
126 {
127 sc := tc.newSC()
128 originalSC := tc.newSC()
129 m := NewPodSecurityContextMutator(sc)
130
131
132 m.SetFSGroup(m.FSGroup())
133 m.SetHostNetwork(m.HostNetwork())
134 m.SetHostIPC(m.HostIPC())
135 m.SetHostPID(m.HostPID())
136 m.SetRunAsNonRoot(m.RunAsNonRoot())
137 m.SetRunAsUser(m.RunAsUser())
138 m.SetRunAsGroup(m.RunAsGroup())
139 m.SetSeccompProfile(m.SeccompProfile())
140 m.SetSELinuxOptions(m.SELinuxOptions())
141 m.SetSupplementalGroups(m.SupplementalGroups())
142 if !reflect.DeepEqual(sc, originalSC) {
143 t.Errorf("%s: unexpected mutation: %#v, %#v", k, sc, originalSC)
144 }
145 if !reflect.DeepEqual(m.PodSecurityContext(), originalSC) {
146 t.Errorf("%s: unexpected mutation: %#v, %#v", k, m.PodSecurityContext(), originalSC)
147 }
148 }
149
150
151 {
152 modifiedSC := nonNilSC(tc.newSC())
153 m := NewPodSecurityContextMutator(tc.newSC())
154 i := int64(1123)
155 modifiedSC.FSGroup = &i
156 m.SetFSGroup(&i)
157 if !reflect.DeepEqual(m.PodSecurityContext(), modifiedSC) {
158 t.Errorf("%s: unexpected object:\n%s", k, diff.ObjectGoPrintSideBySide(modifiedSC, m.PodSecurityContext()))
159 continue
160 }
161 }
162
163
164 {
165 modifiedSC := nonNilSC(tc.newSC())
166 m := NewPodSecurityContextMutator(tc.newSC())
167 modifiedSC.HostNetwork = !modifiedSC.HostNetwork
168 m.SetHostNetwork(!m.HostNetwork())
169 if !reflect.DeepEqual(m.PodSecurityContext(), modifiedSC) {
170 t.Errorf("%s: unexpected object:\n%s", k, diff.ObjectGoPrintSideBySide(modifiedSC, m.PodSecurityContext()))
171 continue
172 }
173 }
174
175
176 {
177 modifiedSC := nonNilSC(tc.newSC())
178 m := NewPodSecurityContextMutator(tc.newSC())
179 modifiedSC.HostIPC = !modifiedSC.HostIPC
180 m.SetHostIPC(!m.HostIPC())
181 if !reflect.DeepEqual(m.PodSecurityContext(), modifiedSC) {
182 t.Errorf("%s: unexpected object:\n%s", k, diff.ObjectGoPrintSideBySide(modifiedSC, m.PodSecurityContext()))
183 continue
184 }
185 }
186
187
188 {
189 modifiedSC := nonNilSC(tc.newSC())
190 m := NewPodSecurityContextMutator(tc.newSC())
191 modifiedSC.HostPID = !modifiedSC.HostPID
192 m.SetHostPID(!m.HostPID())
193 if !reflect.DeepEqual(m.PodSecurityContext(), modifiedSC) {
194 t.Errorf("%s: unexpected object:\n%s", k, diff.ObjectGoPrintSideBySide(modifiedSC, m.PodSecurityContext()))
195 continue
196 }
197 }
198
199
200 {
201 modifiedSC := nonNilSC(tc.newSC())
202 m := NewPodSecurityContextMutator(tc.newSC())
203 b := true
204 modifiedSC.RunAsNonRoot = &b
205 m.SetRunAsNonRoot(&b)
206 if !reflect.DeepEqual(m.PodSecurityContext(), modifiedSC) {
207 t.Errorf("%s: unexpected object:\n%s", k, diff.ObjectGoPrintSideBySide(modifiedSC, m.PodSecurityContext()))
208 continue
209 }
210 }
211
212
213 {
214 modifiedSC := nonNilSC(tc.newSC())
215 m := NewPodSecurityContextMutator(tc.newSC())
216 i := int64(1123)
217 modifiedSC.RunAsUser = &i
218 m.SetRunAsUser(&i)
219 if !reflect.DeepEqual(m.PodSecurityContext(), modifiedSC) {
220 t.Errorf("%s: unexpected object:\n%s", k, diff.ObjectGoPrintSideBySide(modifiedSC, m.PodSecurityContext()))
221 continue
222 }
223 }
224
225
226 {
227 modifiedSC := nonNilSC(tc.newSC())
228 m := NewPodSecurityContextMutator(tc.newSC())
229 i := int64(1123)
230 modifiedSC.RunAsGroup = &i
231 m.SetRunAsGroup(&i)
232 if !reflect.DeepEqual(m.PodSecurityContext(), modifiedSC) {
233 t.Errorf("%s: unexpected object:\n%s", k, diff.ObjectGoPrintSideBySide(modifiedSC, m.PodSecurityContext()))
234 continue
235 }
236 }
237
238
239 {
240 modifiedSC := nonNilSC(tc.newSC())
241 m := NewPodSecurityContextMutator(tc.newSC())
242 modifiedSC.SELinuxOptions = &api.SELinuxOptions{User: "bob"}
243 m.SetSELinuxOptions(&api.SELinuxOptions{User: "bob"})
244 if !reflect.DeepEqual(m.PodSecurityContext(), modifiedSC) {
245 t.Errorf("%s: unexpected object:\n%s", k, diff.ObjectGoPrintSideBySide(modifiedSC, m.PodSecurityContext()))
246 continue
247 }
248 }
249
250
251 {
252 modifiedSC := nonNilSC(tc.newSC())
253 m := NewPodSecurityContextMutator(tc.newSC())
254 modifiedSC.SeccompProfile = &api.SeccompProfile{Type: api.SeccompProfileTypeLocalhost, LocalhostProfile: pointer.String("verylocalhostey")}
255 m.SetSeccompProfile(&api.SeccompProfile{Type: api.SeccompProfileTypeLocalhost, LocalhostProfile: pointer.String("verylocalhostey")})
256 if !reflect.DeepEqual(m.PodSecurityContext(), modifiedSC) {
257 t.Errorf("%s: unexpected object:\n%s", k, diff.ObjectGoPrintSideBySide(modifiedSC, m.PodSecurityContext()))
258 continue
259 }
260 }
261
262
263 {
264 modifiedSC := nonNilSC(tc.newSC())
265 m := NewPodSecurityContextMutator(tc.newSC())
266 modifiedSC.SupplementalGroups = []int64{1, 1, 2, 3}
267 m.SetSupplementalGroups([]int64{1, 1, 2, 3})
268 if !reflect.DeepEqual(m.PodSecurityContext(), modifiedSC) {
269 t.Errorf("%s: unexpected object:\n%s", k, diff.ObjectGoPrintSideBySide(modifiedSC, m.PodSecurityContext()))
270 continue
271 }
272 }
273 }
274 }
275
276 func TestContainerSecurityContextAccessor(t *testing.T) {
277 privileged := true
278 runAsUser := int64(1)
279 runAsGroup := int64(1)
280 runAsNonRoot := true
281 readOnlyRootFilesystem := true
282 allowPrivilegeEscalation := true
283
284 testcases := []*api.SecurityContext{
285 nil,
286 {},
287 {Capabilities: &api.Capabilities{Drop: []api.Capability{"test"}}},
288 {Privileged: &privileged},
289 {SELinuxOptions: &api.SELinuxOptions{User: "bob"}},
290 {RunAsUser: &runAsUser},
291 {RunAsGroup: &runAsGroup},
292 {RunAsNonRoot: &runAsNonRoot},
293 {ReadOnlyRootFilesystem: &readOnlyRootFilesystem},
294 {SeccompProfile: &api.SeccompProfile{Type: api.SeccompProfileTypeRuntimeDefault}},
295 {AllowPrivilegeEscalation: &allowPrivilegeEscalation},
296 }
297
298 for i, tc := range testcases {
299 expected := tc
300 if expected == nil {
301 expected = &api.SecurityContext{}
302 }
303
304 a := NewContainerSecurityContextAccessor(tc)
305
306 if v := a.Capabilities(); !reflect.DeepEqual(expected.Capabilities, v) {
307 t.Errorf("%d: expected %#v, got %#v", i, expected.Capabilities, v)
308 }
309 if v := a.Privileged(); !reflect.DeepEqual(expected.Privileged, v) {
310 t.Errorf("%d: expected %#v, got %#v", i, expected.Privileged, v)
311 }
312 if v := a.RunAsNonRoot(); !reflect.DeepEqual(expected.RunAsNonRoot, v) {
313 t.Errorf("%d: expected %#v, got %#v", i, expected.RunAsNonRoot, v)
314 }
315 if v := a.RunAsUser(); !reflect.DeepEqual(expected.RunAsUser, v) {
316 t.Errorf("%d: expected %#v, got %#v", i, expected.RunAsUser, v)
317 }
318 if v := a.RunAsGroup(); !reflect.DeepEqual(expected.RunAsGroup, v) {
319 t.Errorf("%d: expected %#v, got %#v", i, expected.RunAsGroup, v)
320 }
321 if v := a.SELinuxOptions(); !reflect.DeepEqual(expected.SELinuxOptions, v) {
322 t.Errorf("%d: expected %#v, got %#v", i, expected.SELinuxOptions, v)
323 }
324 if v := a.ReadOnlyRootFilesystem(); !reflect.DeepEqual(expected.ReadOnlyRootFilesystem, v) {
325 t.Errorf("%d: expected %#v, got %#v", i, expected.ReadOnlyRootFilesystem, v)
326 }
327 if v := a.SeccompProfile(); !reflect.DeepEqual(expected.SeccompProfile, v) {
328 t.Errorf("%d: expected %#v, got %#v", i, expected.SeccompProfile, v)
329 }
330 if v := a.AllowPrivilegeEscalation(); !reflect.DeepEqual(expected.AllowPrivilegeEscalation, v) {
331 t.Errorf("%d: expected %#v, got %#v", i, expected.AllowPrivilegeEscalation, v)
332 }
333 }
334 }
335
336 func TestContainerSecurityContextMutator(t *testing.T) {
337 testcases := map[string]struct {
338 newSC func() *api.SecurityContext
339 }{
340 "nil": {
341 newSC: func() *api.SecurityContext { return nil },
342 },
343 "zero": {
344 newSC: func() *api.SecurityContext { return &api.SecurityContext{} },
345 },
346 "populated": {
347 newSC: func() *api.SecurityContext {
348 return &api.SecurityContext{
349 Capabilities: &api.Capabilities{Drop: []api.Capability{"test"}},
350 SELinuxOptions: &api.SELinuxOptions{},
351 SeccompProfile: &api.SeccompProfile{},
352 }
353 },
354 },
355 }
356
357 nonNilSC := func(sc *api.SecurityContext) *api.SecurityContext {
358 if sc == nil {
359 return &api.SecurityContext{}
360 }
361 return sc
362 }
363
364 for k, tc := range testcases {
365 {
366 sc := tc.newSC()
367 originalSC := tc.newSC()
368 m := NewContainerSecurityContextMutator(sc)
369
370
371 m.SetAllowPrivilegeEscalation(m.AllowPrivilegeEscalation())
372 m.SetCapabilities(m.Capabilities())
373 m.SetPrivileged(m.Privileged())
374 m.SetReadOnlyRootFilesystem(m.ReadOnlyRootFilesystem())
375 m.SetRunAsNonRoot(m.RunAsNonRoot())
376 m.SetRunAsUser(m.RunAsUser())
377 m.SetRunAsGroup(m.RunAsGroup())
378 m.SetSELinuxOptions(m.SELinuxOptions())
379 if !reflect.DeepEqual(sc, originalSC) {
380 t.Errorf("%s: unexpected mutation: %#v, %#v", k, sc, originalSC)
381 }
382 if !reflect.DeepEqual(m.ContainerSecurityContext(), originalSC) {
383 t.Errorf("%s: unexpected mutation: %#v, %#v", k, m.ContainerSecurityContext(), originalSC)
384 }
385 }
386
387
388 {
389 modifiedSC := nonNilSC(tc.newSC())
390 m := NewContainerSecurityContextMutator(tc.newSC())
391 b := true
392 modifiedSC.AllowPrivilegeEscalation = &b
393 m.SetAllowPrivilegeEscalation(&b)
394 if !reflect.DeepEqual(m.ContainerSecurityContext(), modifiedSC) {
395 t.Errorf("%s: unexpected object:\n%s", k, diff.ObjectGoPrintSideBySide(modifiedSC, m.ContainerSecurityContext()))
396 continue
397 }
398 }
399
400
401 {
402 modifiedSC := nonNilSC(tc.newSC())
403 m := NewContainerSecurityContextMutator(tc.newSC())
404 modifiedSC.Capabilities = &api.Capabilities{Drop: []api.Capability{"test2"}}
405 m.SetCapabilities(&api.Capabilities{Drop: []api.Capability{"test2"}})
406 if !reflect.DeepEqual(m.ContainerSecurityContext(), modifiedSC) {
407 t.Errorf("%s: unexpected object:\n%s", k, diff.ObjectGoPrintSideBySide(modifiedSC, m.ContainerSecurityContext()))
408 continue
409 }
410 }
411
412
413 {
414 modifiedSC := nonNilSC(tc.newSC())
415 m := NewContainerSecurityContextMutator(tc.newSC())
416 b := true
417 modifiedSC.Privileged = &b
418 m.SetPrivileged(&b)
419 if !reflect.DeepEqual(m.ContainerSecurityContext(), modifiedSC) {
420 t.Errorf("%s: unexpected object:\n%s", k, diff.ObjectGoPrintSideBySide(modifiedSC, m.ContainerSecurityContext()))
421 continue
422 }
423 }
424
425
426 {
427 modifiedSC := nonNilSC(tc.newSC())
428 m := NewContainerSecurityContextMutator(tc.newSC())
429 b := true
430 modifiedSC.ReadOnlyRootFilesystem = &b
431 m.SetReadOnlyRootFilesystem(&b)
432 if !reflect.DeepEqual(m.ContainerSecurityContext(), modifiedSC) {
433 t.Errorf("%s: unexpected object:\n%s", k, diff.ObjectGoPrintSideBySide(modifiedSC, m.ContainerSecurityContext()))
434 continue
435 }
436 }
437
438
439 {
440 modifiedSC := nonNilSC(tc.newSC())
441 m := NewContainerSecurityContextMutator(tc.newSC())
442 b := true
443 modifiedSC.RunAsNonRoot = &b
444 m.SetRunAsNonRoot(&b)
445 if !reflect.DeepEqual(m.ContainerSecurityContext(), modifiedSC) {
446 t.Errorf("%s: unexpected object:\n%s", k, diff.ObjectGoPrintSideBySide(modifiedSC, m.ContainerSecurityContext()))
447 continue
448 }
449 }
450
451
452 {
453 modifiedSC := nonNilSC(tc.newSC())
454 m := NewContainerSecurityContextMutator(tc.newSC())
455 i := int64(1123)
456 modifiedSC.RunAsUser = &i
457 m.SetRunAsUser(&i)
458 if !reflect.DeepEqual(m.ContainerSecurityContext(), modifiedSC) {
459 t.Errorf("%s: unexpected object:\n%s", k, diff.ObjectGoPrintSideBySide(modifiedSC, m.ContainerSecurityContext()))
460 continue
461 }
462 }
463
464
465 {
466 modifiedSC := nonNilSC(tc.newSC())
467 m := NewContainerSecurityContextMutator(tc.newSC())
468 i := int64(1123)
469 modifiedSC.RunAsGroup = &i
470 m.SetRunAsGroup(&i)
471 if !reflect.DeepEqual(m.ContainerSecurityContext(), modifiedSC) {
472 t.Errorf("%s: unexpected object:\n%s", k, diff.ObjectGoPrintSideBySide(modifiedSC, m.ContainerSecurityContext()))
473 continue
474 }
475 }
476
477
478 {
479 modifiedSC := nonNilSC(tc.newSC())
480 m := NewContainerSecurityContextMutator(tc.newSC())
481 modifiedSC.SeccompProfile = &api.SeccompProfile{Type: api.SeccompProfileTypeUnconfined}
482 m.SetSeccompProfile(&api.SeccompProfile{Type: api.SeccompProfileTypeUnconfined})
483 if !reflect.DeepEqual(m.ContainerSecurityContext(), modifiedSC) {
484 t.Errorf("%s: unexpected object:\n%s", k, diff.ObjectGoPrintSideBySide(modifiedSC, m.ContainerSecurityContext()))
485 continue
486 }
487 }
488
489
490 {
491 modifiedSC := nonNilSC(tc.newSC())
492 m := NewContainerSecurityContextMutator(tc.newSC())
493 modifiedSC.SELinuxOptions = &api.SELinuxOptions{User: "bob"}
494 m.SetSELinuxOptions(&api.SELinuxOptions{User: "bob"})
495 if !reflect.DeepEqual(m.ContainerSecurityContext(), modifiedSC) {
496 t.Errorf("%s: unexpected object:\n%s", k, diff.ObjectGoPrintSideBySide(modifiedSC, m.ContainerSecurityContext()))
497 continue
498 }
499 }
500 }
501 }
502
503 func TestEffectiveContainerSecurityContextAccessor(t *testing.T) {
504 privileged := true
505 runAsUser := int64(1)
506 runAsUserPod := int64(12)
507 runAsGroup := int64(1)
508 runAsGroupPod := int64(12)
509 runAsNonRoot := true
510 runAsNonRootPod := false
511 readOnlyRootFilesystem := true
512 allowPrivilegeEscalation := true
513
514 testcases := []struct {
515 PodSC *api.PodSecurityContext
516 SC *api.SecurityContext
517 Effective *api.SecurityContext
518 }{
519 {
520 PodSC: nil,
521 SC: nil,
522 Effective: nil,
523 },
524 {
525 PodSC: &api.PodSecurityContext{},
526 SC: &api.SecurityContext{},
527 Effective: &api.SecurityContext{},
528 },
529 {
530 PodSC: &api.PodSecurityContext{
531 SELinuxOptions: &api.SELinuxOptions{User: "bob"},
532 SeccompProfile: &api.SeccompProfile{Type: api.SeccompProfileTypeUnconfined},
533 RunAsUser: &runAsUser,
534 RunAsNonRoot: &runAsNonRoot,
535 },
536 SC: nil,
537 Effective: &api.SecurityContext{
538 SELinuxOptions: &api.SELinuxOptions{User: "bob"},
539 SeccompProfile: &api.SeccompProfile{Type: api.SeccompProfileTypeUnconfined},
540 RunAsUser: &runAsUser,
541 RunAsNonRoot: &runAsNonRoot,
542 },
543 },
544 {
545 PodSC: &api.PodSecurityContext{
546 SELinuxOptions: &api.SELinuxOptions{User: "bob"},
547 SeccompProfile: &api.SeccompProfile{Type: api.SeccompProfileTypeUnconfined},
548 RunAsUser: &runAsUserPod,
549 RunAsNonRoot: &runAsNonRootPod,
550 },
551 SC: &api.SecurityContext{},
552 Effective: &api.SecurityContext{
553 SELinuxOptions: &api.SELinuxOptions{User: "bob"},
554 SeccompProfile: &api.SeccompProfile{Type: api.SeccompProfileTypeUnconfined},
555 RunAsUser: &runAsUserPod,
556 RunAsNonRoot: &runAsNonRootPod,
557 },
558 },
559 {
560 PodSC: &api.PodSecurityContext{
561 SELinuxOptions: &api.SELinuxOptions{User: "bob"},
562 SeccompProfile: &api.SeccompProfile{Type: api.SeccompProfileTypeUnconfined},
563 RunAsUser: &runAsUserPod,
564 RunAsNonRoot: &runAsNonRootPod,
565 },
566 SC: &api.SecurityContext{
567 AllowPrivilegeEscalation: &allowPrivilegeEscalation,
568 Capabilities: &api.Capabilities{Drop: []api.Capability{"test"}},
569 Privileged: &privileged,
570 ReadOnlyRootFilesystem: &readOnlyRootFilesystem,
571 RunAsUser: &runAsUser,
572 RunAsNonRoot: &runAsNonRoot,
573 SELinuxOptions: &api.SELinuxOptions{User: "bob"},
574 SeccompProfile: &api.SeccompProfile{Type: api.SeccompProfileTypeRuntimeDefault},
575 },
576 Effective: &api.SecurityContext{
577 AllowPrivilegeEscalation: &allowPrivilegeEscalation,
578 Capabilities: &api.Capabilities{Drop: []api.Capability{"test"}},
579 Privileged: &privileged,
580 ReadOnlyRootFilesystem: &readOnlyRootFilesystem,
581 RunAsUser: &runAsUser,
582 RunAsNonRoot: &runAsNonRoot,
583 SELinuxOptions: &api.SELinuxOptions{User: "bob"},
584 SeccompProfile: &api.SeccompProfile{Type: api.SeccompProfileTypeRuntimeDefault},
585 },
586 },
587 {
588 PodSC: &api.PodSecurityContext{
589 RunAsGroup: &runAsGroup,
590 },
591 SC: nil,
592 Effective: &api.SecurityContext{
593 RunAsGroup: &runAsGroup,
594 },
595 },
596 {
597 PodSC: &api.PodSecurityContext{
598 RunAsGroup: &runAsGroupPod,
599 },
600 SC: &api.SecurityContext{
601 RunAsGroup: &runAsGroup,
602 },
603 Effective: &api.SecurityContext{
604 RunAsGroup: &runAsGroup,
605 },
606 },
607 }
608
609 for i, tc := range testcases {
610 expected := tc.Effective
611 if expected == nil {
612 expected = &api.SecurityContext{}
613 }
614
615 a := NewEffectiveContainerSecurityContextAccessor(
616 NewPodSecurityContextAccessor(tc.PodSC),
617 NewContainerSecurityContextMutator(tc.SC),
618 )
619
620 if v := a.Capabilities(); !reflect.DeepEqual(expected.Capabilities, v) {
621 t.Errorf("%d: expected %#v, got %#v", i, expected.Capabilities, v)
622 }
623 if v := a.Privileged(); !reflect.DeepEqual(expected.Privileged, v) {
624 t.Errorf("%d: expected %#v, got %#v", i, expected.Privileged, v)
625 }
626 if v := a.RunAsNonRoot(); !reflect.DeepEqual(expected.RunAsNonRoot, v) {
627 t.Errorf("%d: expected %#v, got %#v", i, expected.RunAsNonRoot, v)
628 }
629 if v := a.RunAsUser(); !reflect.DeepEqual(expected.RunAsUser, v) {
630 t.Errorf("%d: expected %#v, got %#v", i, expected.RunAsUser, v)
631 }
632 if v := a.RunAsGroup(); !reflect.DeepEqual(expected.RunAsGroup, v) {
633 t.Errorf("%d: expected %#v, got %#v", i, expected.RunAsGroup, v)
634 }
635 if v := a.SELinuxOptions(); !reflect.DeepEqual(expected.SELinuxOptions, v) {
636 t.Errorf("%d: expected %#v, got %#v", i, expected.SELinuxOptions, v)
637 }
638 if v := a.ReadOnlyRootFilesystem(); !reflect.DeepEqual(expected.ReadOnlyRootFilesystem, v) {
639 t.Errorf("%d: expected %#v, got %#v", i, expected.ReadOnlyRootFilesystem, v)
640 }
641 if v := a.AllowPrivilegeEscalation(); !reflect.DeepEqual(expected.AllowPrivilegeEscalation, v) {
642 t.Errorf("%d: expected %#v, got %#v", i, expected.AllowPrivilegeEscalation, v)
643 }
644 }
645 }
646
647 func TestEffectiveContainerSecurityContextMutator(t *testing.T) {
648 runAsNonRootPod := false
649 runAsUserPod := int64(12)
650
651 testcases := map[string]struct {
652 newPodSC func() *api.PodSecurityContext
653 newSC func() *api.SecurityContext
654 }{
655 "nil": {
656 newPodSC: func() *api.PodSecurityContext { return nil },
657 newSC: func() *api.SecurityContext { return nil },
658 },
659 "zero": {
660 newPodSC: func() *api.PodSecurityContext { return &api.PodSecurityContext{} },
661 newSC: func() *api.SecurityContext { return &api.SecurityContext{} },
662 },
663 "populated pod sc": {
664 newPodSC: func() *api.PodSecurityContext {
665 return &api.PodSecurityContext{
666 SELinuxOptions: &api.SELinuxOptions{User: "poduser"},
667 SeccompProfile: &api.SeccompProfile{},
668 RunAsNonRoot: &runAsNonRootPod,
669 RunAsUser: &runAsUserPod,
670 }
671 },
672 newSC: func() *api.SecurityContext {
673 return &api.SecurityContext{}
674 },
675 },
676 "populated sc": {
677 newPodSC: func() *api.PodSecurityContext { return nil },
678 newSC: func() *api.SecurityContext {
679 return &api.SecurityContext{
680 Capabilities: &api.Capabilities{Drop: []api.Capability{"test"}},
681 SELinuxOptions: &api.SELinuxOptions{},
682 SeccompProfile: &api.SeccompProfile{},
683 }
684 },
685 },
686 }
687
688 nonNilSC := func(sc *api.SecurityContext) *api.SecurityContext {
689 if sc == nil {
690 return &api.SecurityContext{}
691 }
692 return sc
693 }
694
695 for k, tc := range testcases {
696 {
697 podSC := tc.newPodSC()
698 sc := tc.newSC()
699 originalPodSC := tc.newPodSC()
700 originalSC := tc.newSC()
701 m := NewEffectiveContainerSecurityContextMutator(
702 NewPodSecurityContextAccessor(podSC),
703 NewContainerSecurityContextMutator(sc),
704 )
705
706
707 m.SetAllowPrivilegeEscalation(m.AllowPrivilegeEscalation())
708 m.SetCapabilities(m.Capabilities())
709 m.SetPrivileged(m.Privileged())
710 m.SetReadOnlyRootFilesystem(m.ReadOnlyRootFilesystem())
711 m.SetRunAsNonRoot(m.RunAsNonRoot())
712 m.SetRunAsUser(m.RunAsUser())
713 m.SetRunAsGroup(m.RunAsGroup())
714 m.SetSELinuxOptions(m.SELinuxOptions())
715 m.SetSeccompProfile(m.SeccompProfile())
716 if !reflect.DeepEqual(podSC, originalPodSC) {
717 t.Errorf("%s: unexpected mutation: %#v, %#v", k, podSC, originalPodSC)
718 }
719 if !reflect.DeepEqual(sc, originalSC) {
720 t.Errorf("%s: unexpected mutation: %#v, %#v", k, sc, originalSC)
721 }
722 if !reflect.DeepEqual(m.ContainerSecurityContext(), originalSC) {
723 t.Errorf("%s: unexpected mutation: %#v, %#v", k, m.ContainerSecurityContext(), originalSC)
724 }
725 }
726
727
728 {
729 modifiedSC := nonNilSC(tc.newSC())
730 m := NewEffectiveContainerSecurityContextMutator(
731 NewPodSecurityContextAccessor(tc.newPodSC()),
732 NewContainerSecurityContextMutator(tc.newSC()),
733 )
734 b := true
735 modifiedSC.AllowPrivilegeEscalation = &b
736 m.SetAllowPrivilegeEscalation(&b)
737 if !reflect.DeepEqual(m.ContainerSecurityContext(), modifiedSC) {
738 t.Errorf("%s: unexpected object:\n%s", k, diff.ObjectGoPrintSideBySide(modifiedSC, m.ContainerSecurityContext()))
739 continue
740 }
741 }
742
743
744 {
745 modifiedSC := nonNilSC(tc.newSC())
746 m := NewEffectiveContainerSecurityContextMutator(
747 NewPodSecurityContextAccessor(tc.newPodSC()),
748 NewContainerSecurityContextMutator(tc.newSC()),
749 )
750 modifiedSC.Capabilities = &api.Capabilities{Drop: []api.Capability{"test2"}}
751 m.SetCapabilities(&api.Capabilities{Drop: []api.Capability{"test2"}})
752 if !reflect.DeepEqual(m.ContainerSecurityContext(), modifiedSC) {
753 t.Errorf("%s: unexpected object:\n%s", k, diff.ObjectGoPrintSideBySide(modifiedSC, m.ContainerSecurityContext()))
754 continue
755 }
756 }
757
758
759 {
760 modifiedSC := nonNilSC(tc.newSC())
761 m := NewEffectiveContainerSecurityContextMutator(
762 NewPodSecurityContextAccessor(tc.newPodSC()),
763 NewContainerSecurityContextMutator(tc.newSC()),
764 )
765 b := true
766 modifiedSC.Privileged = &b
767 m.SetPrivileged(&b)
768 if !reflect.DeepEqual(m.ContainerSecurityContext(), modifiedSC) {
769 t.Errorf("%s: unexpected object:\n%s", k, diff.ObjectGoPrintSideBySide(modifiedSC, m.ContainerSecurityContext()))
770 continue
771 }
772 }
773
774
775 {
776 modifiedSC := nonNilSC(tc.newSC())
777 m := NewEffectiveContainerSecurityContextMutator(
778 NewPodSecurityContextAccessor(tc.newPodSC()),
779 NewContainerSecurityContextMutator(tc.newSC()),
780 )
781 b := true
782 modifiedSC.ReadOnlyRootFilesystem = &b
783 m.SetReadOnlyRootFilesystem(&b)
784 if !reflect.DeepEqual(m.ContainerSecurityContext(), modifiedSC) {
785 t.Errorf("%s: unexpected object:\n%s", k, diff.ObjectGoPrintSideBySide(modifiedSC, m.ContainerSecurityContext()))
786 continue
787 }
788 }
789
790
791 {
792 modifiedSC := nonNilSC(tc.newSC())
793 m := NewEffectiveContainerSecurityContextMutator(
794 NewPodSecurityContextAccessor(tc.newPodSC()),
795 NewContainerSecurityContextMutator(tc.newSC()),
796 )
797 b := true
798 modifiedSC.RunAsNonRoot = &b
799 m.SetRunAsNonRoot(&b)
800 if !reflect.DeepEqual(m.ContainerSecurityContext(), modifiedSC) {
801 t.Errorf("%s: unexpected object:\n%s", k, diff.ObjectGoPrintSideBySide(modifiedSC, m.ContainerSecurityContext()))
802 continue
803 }
804 }
805
806
807 {
808 modifiedSC := nonNilSC(tc.newSC())
809 m := NewEffectiveContainerSecurityContextMutator(
810 NewPodSecurityContextAccessor(tc.newPodSC()),
811 NewContainerSecurityContextMutator(tc.newSC()),
812 )
813 i := int64(1123)
814 modifiedSC.RunAsUser = &i
815 m.SetRunAsUser(&i)
816 if !reflect.DeepEqual(m.ContainerSecurityContext(), modifiedSC) {
817 t.Errorf("%s: unexpected object:\n%s", k, diff.ObjectGoPrintSideBySide(modifiedSC, m.ContainerSecurityContext()))
818 continue
819 }
820 }
821
822
823 {
824 modifiedSC := nonNilSC(tc.newSC())
825 m := NewEffectiveContainerSecurityContextMutator(
826 NewPodSecurityContextAccessor(tc.newPodSC()),
827 NewContainerSecurityContextMutator(tc.newSC()),
828 )
829 i := int64(1123)
830 modifiedSC.RunAsGroup = &i
831 m.SetRunAsGroup(&i)
832 if !reflect.DeepEqual(m.ContainerSecurityContext(), modifiedSC) {
833 t.Errorf("%s: unexpected object:\n%s", k, diff.ObjectGoPrintSideBySide(modifiedSC, m.ContainerSecurityContext()))
834 continue
835 }
836 }
837
838
839 {
840 modifiedSC := nonNilSC(tc.newSC())
841 m := NewContainerSecurityContextMutator(tc.newSC())
842 modifiedSC.SeccompProfile = &api.SeccompProfile{Type: api.SeccompProfileTypeUnconfined}
843 m.SetSeccompProfile(&api.SeccompProfile{Type: api.SeccompProfileTypeUnconfined})
844 if !reflect.DeepEqual(m.ContainerSecurityContext(), modifiedSC) {
845 t.Errorf("%s: unexpected object:\n%s", k, diff.ObjectGoPrintSideBySide(modifiedSC, m.ContainerSecurityContext()))
846 continue
847 }
848 }
849
850
851 {
852 modifiedSC := nonNilSC(tc.newSC())
853 m := NewEffectiveContainerSecurityContextMutator(
854 NewPodSecurityContextAccessor(tc.newPodSC()),
855 NewContainerSecurityContextMutator(tc.newSC()),
856 )
857 modifiedSC.SELinuxOptions = &api.SELinuxOptions{User: "bob"}
858 m.SetSELinuxOptions(&api.SELinuxOptions{User: "bob"})
859 if !reflect.DeepEqual(m.ContainerSecurityContext(), modifiedSC) {
860 t.Errorf("%s: unexpected object:\n%s", k, diff.ObjectGoPrintSideBySide(modifiedSC, m.ContainerSecurityContext()))
861 continue
862 }
863 }
864 }
865 }
866
View as plain text