mirror of
https://github.com/ceph/ceph-csi.git
synced 2025-06-13 10:33:35 +00:00
vendor files
This commit is contained in:
50
vendor/k8s.io/kubernetes/pkg/securitycontext/BUILD
generated
vendored
Normal file
50
vendor/k8s.io/kubernetes/pkg/securitycontext/BUILD
generated
vendored
Normal file
@ -0,0 +1,50 @@
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_library",
|
||||
"go_test",
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"accessors.go",
|
||||
"doc.go",
|
||||
"fake.go",
|
||||
"util.go",
|
||||
],
|
||||
importpath = "k8s.io/kubernetes/pkg/securitycontext",
|
||||
deps = [
|
||||
"//pkg/apis/core:go_default_library",
|
||||
"//vendor/k8s.io/api/core/v1:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = [
|
||||
"accessors_test.go",
|
||||
"util_test.go",
|
||||
],
|
||||
importpath = "k8s.io/kubernetes/pkg/securitycontext",
|
||||
library = ":go_default_library",
|
||||
deps = [
|
||||
"//pkg/apis/core:go_default_library",
|
||||
"//vendor/k8s.io/api/core/v1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/diff:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
)
|
407
vendor/k8s.io/kubernetes/pkg/securitycontext/accessors.go
generated
vendored
Normal file
407
vendor/k8s.io/kubernetes/pkg/securitycontext/accessors.go
generated
vendored
Normal file
@ -0,0 +1,407 @@
|
||||
/*
|
||||
Copyright 2017 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package securitycontext
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
|
||||
api "k8s.io/kubernetes/pkg/apis/core"
|
||||
)
|
||||
|
||||
// PodSecurityContextAccessor allows reading the values of a PodSecurityContext object
|
||||
type PodSecurityContextAccessor interface {
|
||||
HostNetwork() bool
|
||||
HostPID() bool
|
||||
HostIPC() bool
|
||||
SELinuxOptions() *api.SELinuxOptions
|
||||
RunAsUser() *int64
|
||||
RunAsNonRoot() *bool
|
||||
SupplementalGroups() []int64
|
||||
FSGroup() *int64
|
||||
}
|
||||
|
||||
// PodSecurityContextMutator allows reading and writing the values of a PodSecurityContext object
|
||||
type PodSecurityContextMutator interface {
|
||||
PodSecurityContextAccessor
|
||||
|
||||
SetHostNetwork(bool)
|
||||
SetHostPID(bool)
|
||||
SetHostIPC(bool)
|
||||
SetSELinuxOptions(*api.SELinuxOptions)
|
||||
SetRunAsUser(*int64)
|
||||
SetRunAsNonRoot(*bool)
|
||||
SetSupplementalGroups([]int64)
|
||||
SetFSGroup(*int64)
|
||||
|
||||
// PodSecurityContext returns the current PodSecurityContext object
|
||||
PodSecurityContext() *api.PodSecurityContext
|
||||
}
|
||||
|
||||
// NewPodSecurityContextAccessor returns an accessor for the given pod security context.
|
||||
// May be initialized with a nil PodSecurityContext.
|
||||
func NewPodSecurityContextAccessor(podSC *api.PodSecurityContext) PodSecurityContextAccessor {
|
||||
return &podSecurityContextWrapper{podSC: podSC}
|
||||
}
|
||||
|
||||
// NewPodSecurityContextMutator returns a mutator for the given pod security context.
|
||||
// May be initialized with a nil PodSecurityContext.
|
||||
func NewPodSecurityContextMutator(podSC *api.PodSecurityContext) PodSecurityContextMutator {
|
||||
return &podSecurityContextWrapper{podSC: podSC}
|
||||
}
|
||||
|
||||
type podSecurityContextWrapper struct {
|
||||
podSC *api.PodSecurityContext
|
||||
}
|
||||
|
||||
func (w *podSecurityContextWrapper) PodSecurityContext() *api.PodSecurityContext {
|
||||
return w.podSC
|
||||
}
|
||||
|
||||
func (w *podSecurityContextWrapper) ensurePodSC() {
|
||||
if w.podSC == nil {
|
||||
w.podSC = &api.PodSecurityContext{}
|
||||
}
|
||||
}
|
||||
|
||||
func (w *podSecurityContextWrapper) HostNetwork() bool {
|
||||
if w.podSC == nil {
|
||||
return false
|
||||
}
|
||||
return w.podSC.HostNetwork
|
||||
}
|
||||
func (w *podSecurityContextWrapper) SetHostNetwork(v bool) {
|
||||
if w.podSC == nil && v == false {
|
||||
return
|
||||
}
|
||||
w.ensurePodSC()
|
||||
w.podSC.HostNetwork = v
|
||||
}
|
||||
func (w *podSecurityContextWrapper) HostPID() bool {
|
||||
if w.podSC == nil {
|
||||
return false
|
||||
}
|
||||
return w.podSC.HostPID
|
||||
}
|
||||
func (w *podSecurityContextWrapper) SetHostPID(v bool) {
|
||||
if w.podSC == nil && v == false {
|
||||
return
|
||||
}
|
||||
w.ensurePodSC()
|
||||
w.podSC.HostPID = v
|
||||
}
|
||||
func (w *podSecurityContextWrapper) HostIPC() bool {
|
||||
if w.podSC == nil {
|
||||
return false
|
||||
}
|
||||
return w.podSC.HostIPC
|
||||
}
|
||||
func (w *podSecurityContextWrapper) SetHostIPC(v bool) {
|
||||
if w.podSC == nil && v == false {
|
||||
return
|
||||
}
|
||||
w.ensurePodSC()
|
||||
w.podSC.HostIPC = v
|
||||
}
|
||||
func (w *podSecurityContextWrapper) SELinuxOptions() *api.SELinuxOptions {
|
||||
if w.podSC == nil {
|
||||
return nil
|
||||
}
|
||||
return w.podSC.SELinuxOptions
|
||||
}
|
||||
func (w *podSecurityContextWrapper) SetSELinuxOptions(v *api.SELinuxOptions) {
|
||||
if w.podSC == nil && v == nil {
|
||||
return
|
||||
}
|
||||
w.ensurePodSC()
|
||||
w.podSC.SELinuxOptions = v
|
||||
}
|
||||
func (w *podSecurityContextWrapper) RunAsUser() *int64 {
|
||||
if w.podSC == nil {
|
||||
return nil
|
||||
}
|
||||
return w.podSC.RunAsUser
|
||||
}
|
||||
func (w *podSecurityContextWrapper) SetRunAsUser(v *int64) {
|
||||
if w.podSC == nil && v == nil {
|
||||
return
|
||||
}
|
||||
w.ensurePodSC()
|
||||
w.podSC.RunAsUser = v
|
||||
}
|
||||
func (w *podSecurityContextWrapper) RunAsNonRoot() *bool {
|
||||
if w.podSC == nil {
|
||||
return nil
|
||||
}
|
||||
return w.podSC.RunAsNonRoot
|
||||
}
|
||||
func (w *podSecurityContextWrapper) SetRunAsNonRoot(v *bool) {
|
||||
if w.podSC == nil && v == nil {
|
||||
return
|
||||
}
|
||||
w.ensurePodSC()
|
||||
w.podSC.RunAsNonRoot = v
|
||||
}
|
||||
func (w *podSecurityContextWrapper) SupplementalGroups() []int64 {
|
||||
if w.podSC == nil {
|
||||
return nil
|
||||
}
|
||||
return w.podSC.SupplementalGroups
|
||||
}
|
||||
func (w *podSecurityContextWrapper) SetSupplementalGroups(v []int64) {
|
||||
if w.podSC == nil && len(v) == 0 {
|
||||
return
|
||||
}
|
||||
w.ensurePodSC()
|
||||
if len(v) == 0 && len(w.podSC.SupplementalGroups) == 0 {
|
||||
return
|
||||
}
|
||||
w.podSC.SupplementalGroups = v
|
||||
}
|
||||
func (w *podSecurityContextWrapper) FSGroup() *int64 {
|
||||
if w.podSC == nil {
|
||||
return nil
|
||||
}
|
||||
return w.podSC.FSGroup
|
||||
}
|
||||
func (w *podSecurityContextWrapper) SetFSGroup(v *int64) {
|
||||
if w.podSC == nil && v == nil {
|
||||
return
|
||||
}
|
||||
w.ensurePodSC()
|
||||
w.podSC.FSGroup = v
|
||||
}
|
||||
|
||||
type ContainerSecurityContextAccessor interface {
|
||||
Capabilities() *api.Capabilities
|
||||
Privileged() *bool
|
||||
SELinuxOptions() *api.SELinuxOptions
|
||||
RunAsUser() *int64
|
||||
RunAsNonRoot() *bool
|
||||
ReadOnlyRootFilesystem() *bool
|
||||
AllowPrivilegeEscalation() *bool
|
||||
}
|
||||
|
||||
type ContainerSecurityContextMutator interface {
|
||||
ContainerSecurityContextAccessor
|
||||
|
||||
ContainerSecurityContext() *api.SecurityContext
|
||||
|
||||
SetCapabilities(*api.Capabilities)
|
||||
SetPrivileged(*bool)
|
||||
SetSELinuxOptions(*api.SELinuxOptions)
|
||||
SetRunAsUser(*int64)
|
||||
SetRunAsNonRoot(*bool)
|
||||
SetReadOnlyRootFilesystem(*bool)
|
||||
SetAllowPrivilegeEscalation(*bool)
|
||||
}
|
||||
|
||||
func NewContainerSecurityContextAccessor(containerSC *api.SecurityContext) ContainerSecurityContextAccessor {
|
||||
return &containerSecurityContextWrapper{containerSC: containerSC}
|
||||
}
|
||||
|
||||
func NewContainerSecurityContextMutator(containerSC *api.SecurityContext) ContainerSecurityContextMutator {
|
||||
return &containerSecurityContextWrapper{containerSC: containerSC}
|
||||
}
|
||||
|
||||
type containerSecurityContextWrapper struct {
|
||||
containerSC *api.SecurityContext
|
||||
}
|
||||
|
||||
func (w *containerSecurityContextWrapper) ContainerSecurityContext() *api.SecurityContext {
|
||||
return w.containerSC
|
||||
}
|
||||
|
||||
func (w *containerSecurityContextWrapper) ensureContainerSC() {
|
||||
if w.containerSC == nil {
|
||||
w.containerSC = &api.SecurityContext{}
|
||||
}
|
||||
}
|
||||
|
||||
func (w *containerSecurityContextWrapper) Capabilities() *api.Capabilities {
|
||||
if w.containerSC == nil {
|
||||
return nil
|
||||
}
|
||||
return w.containerSC.Capabilities
|
||||
}
|
||||
func (w *containerSecurityContextWrapper) SetCapabilities(v *api.Capabilities) {
|
||||
if w.containerSC == nil && v == nil {
|
||||
return
|
||||
}
|
||||
w.ensureContainerSC()
|
||||
w.containerSC.Capabilities = v
|
||||
}
|
||||
func (w *containerSecurityContextWrapper) Privileged() *bool {
|
||||
if w.containerSC == nil {
|
||||
return nil
|
||||
}
|
||||
return w.containerSC.Privileged
|
||||
}
|
||||
func (w *containerSecurityContextWrapper) SetPrivileged(v *bool) {
|
||||
if w.containerSC == nil && v == nil {
|
||||
return
|
||||
}
|
||||
w.ensureContainerSC()
|
||||
w.containerSC.Privileged = v
|
||||
}
|
||||
func (w *containerSecurityContextWrapper) SELinuxOptions() *api.SELinuxOptions {
|
||||
if w.containerSC == nil {
|
||||
return nil
|
||||
}
|
||||
return w.containerSC.SELinuxOptions
|
||||
}
|
||||
func (w *containerSecurityContextWrapper) SetSELinuxOptions(v *api.SELinuxOptions) {
|
||||
if w.containerSC == nil && v == nil {
|
||||
return
|
||||
}
|
||||
w.ensureContainerSC()
|
||||
w.containerSC.SELinuxOptions = v
|
||||
}
|
||||
func (w *containerSecurityContextWrapper) RunAsUser() *int64 {
|
||||
if w.containerSC == nil {
|
||||
return nil
|
||||
}
|
||||
return w.containerSC.RunAsUser
|
||||
}
|
||||
func (w *containerSecurityContextWrapper) SetRunAsUser(v *int64) {
|
||||
if w.containerSC == nil && v == nil {
|
||||
return
|
||||
}
|
||||
w.ensureContainerSC()
|
||||
w.containerSC.RunAsUser = v
|
||||
}
|
||||
func (w *containerSecurityContextWrapper) RunAsNonRoot() *bool {
|
||||
if w.containerSC == nil {
|
||||
return nil
|
||||
}
|
||||
return w.containerSC.RunAsNonRoot
|
||||
}
|
||||
func (w *containerSecurityContextWrapper) SetRunAsNonRoot(v *bool) {
|
||||
if w.containerSC == nil && v == nil {
|
||||
return
|
||||
}
|
||||
w.ensureContainerSC()
|
||||
w.containerSC.RunAsNonRoot = v
|
||||
}
|
||||
func (w *containerSecurityContextWrapper) ReadOnlyRootFilesystem() *bool {
|
||||
if w.containerSC == nil {
|
||||
return nil
|
||||
}
|
||||
return w.containerSC.ReadOnlyRootFilesystem
|
||||
}
|
||||
func (w *containerSecurityContextWrapper) SetReadOnlyRootFilesystem(v *bool) {
|
||||
if w.containerSC == nil && v == nil {
|
||||
return
|
||||
}
|
||||
w.ensureContainerSC()
|
||||
w.containerSC.ReadOnlyRootFilesystem = v
|
||||
}
|
||||
func (w *containerSecurityContextWrapper) AllowPrivilegeEscalation() *bool {
|
||||
if w.containerSC == nil {
|
||||
return nil
|
||||
}
|
||||
return w.containerSC.AllowPrivilegeEscalation
|
||||
}
|
||||
func (w *containerSecurityContextWrapper) SetAllowPrivilegeEscalation(v *bool) {
|
||||
if w.containerSC == nil && v == nil {
|
||||
return
|
||||
}
|
||||
w.ensureContainerSC()
|
||||
w.containerSC.AllowPrivilegeEscalation = v
|
||||
}
|
||||
|
||||
func NewEffectiveContainerSecurityContextAccessor(podSC PodSecurityContextAccessor, containerSC ContainerSecurityContextMutator) ContainerSecurityContextAccessor {
|
||||
return &effectiveContainerSecurityContextWrapper{podSC: podSC, containerSC: containerSC}
|
||||
}
|
||||
|
||||
func NewEffectiveContainerSecurityContextMutator(podSC PodSecurityContextAccessor, containerSC ContainerSecurityContextMutator) ContainerSecurityContextMutator {
|
||||
return &effectiveContainerSecurityContextWrapper{podSC: podSC, containerSC: containerSC}
|
||||
}
|
||||
|
||||
type effectiveContainerSecurityContextWrapper struct {
|
||||
podSC PodSecurityContextAccessor
|
||||
containerSC ContainerSecurityContextMutator
|
||||
}
|
||||
|
||||
func (w *effectiveContainerSecurityContextWrapper) ContainerSecurityContext() *api.SecurityContext {
|
||||
return w.containerSC.ContainerSecurityContext()
|
||||
}
|
||||
|
||||
func (w *effectiveContainerSecurityContextWrapper) Capabilities() *api.Capabilities {
|
||||
return w.containerSC.Capabilities()
|
||||
}
|
||||
func (w *effectiveContainerSecurityContextWrapper) SetCapabilities(v *api.Capabilities) {
|
||||
if !reflect.DeepEqual(w.Capabilities(), v) {
|
||||
w.containerSC.SetCapabilities(v)
|
||||
}
|
||||
}
|
||||
func (w *effectiveContainerSecurityContextWrapper) Privileged() *bool {
|
||||
return w.containerSC.Privileged()
|
||||
}
|
||||
func (w *effectiveContainerSecurityContextWrapper) SetPrivileged(v *bool) {
|
||||
if !reflect.DeepEqual(w.Privileged(), v) {
|
||||
w.containerSC.SetPrivileged(v)
|
||||
}
|
||||
}
|
||||
func (w *effectiveContainerSecurityContextWrapper) SELinuxOptions() *api.SELinuxOptions {
|
||||
if v := w.containerSC.SELinuxOptions(); v != nil {
|
||||
return v
|
||||
}
|
||||
return w.podSC.SELinuxOptions()
|
||||
}
|
||||
func (w *effectiveContainerSecurityContextWrapper) SetSELinuxOptions(v *api.SELinuxOptions) {
|
||||
if !reflect.DeepEqual(w.SELinuxOptions(), v) {
|
||||
w.containerSC.SetSELinuxOptions(v)
|
||||
}
|
||||
}
|
||||
func (w *effectiveContainerSecurityContextWrapper) RunAsUser() *int64 {
|
||||
if v := w.containerSC.RunAsUser(); v != nil {
|
||||
return v
|
||||
}
|
||||
return w.podSC.RunAsUser()
|
||||
}
|
||||
func (w *effectiveContainerSecurityContextWrapper) SetRunAsUser(v *int64) {
|
||||
if !reflect.DeepEqual(w.RunAsUser(), v) {
|
||||
w.containerSC.SetRunAsUser(v)
|
||||
}
|
||||
}
|
||||
func (w *effectiveContainerSecurityContextWrapper) RunAsNonRoot() *bool {
|
||||
if v := w.containerSC.RunAsNonRoot(); v != nil {
|
||||
return v
|
||||
}
|
||||
return w.podSC.RunAsNonRoot()
|
||||
}
|
||||
func (w *effectiveContainerSecurityContextWrapper) SetRunAsNonRoot(v *bool) {
|
||||
if !reflect.DeepEqual(w.RunAsNonRoot(), v) {
|
||||
w.containerSC.SetRunAsNonRoot(v)
|
||||
}
|
||||
}
|
||||
func (w *effectiveContainerSecurityContextWrapper) ReadOnlyRootFilesystem() *bool {
|
||||
return w.containerSC.ReadOnlyRootFilesystem()
|
||||
}
|
||||
func (w *effectiveContainerSecurityContextWrapper) SetReadOnlyRootFilesystem(v *bool) {
|
||||
if !reflect.DeepEqual(w.ReadOnlyRootFilesystem(), v) {
|
||||
w.containerSC.SetReadOnlyRootFilesystem(v)
|
||||
}
|
||||
}
|
||||
func (w *effectiveContainerSecurityContextWrapper) AllowPrivilegeEscalation() *bool {
|
||||
return w.containerSC.AllowPrivilegeEscalation()
|
||||
}
|
||||
func (w *effectiveContainerSecurityContextWrapper) SetAllowPrivilegeEscalation(v *bool) {
|
||||
if !reflect.DeepEqual(w.AllowPrivilegeEscalation(), v) {
|
||||
w.containerSC.SetAllowPrivilegeEscalation(v)
|
||||
}
|
||||
}
|
726
vendor/k8s.io/kubernetes/pkg/securitycontext/accessors_test.go
generated
vendored
Normal file
726
vendor/k8s.io/kubernetes/pkg/securitycontext/accessors_test.go
generated
vendored
Normal file
@ -0,0 +1,726 @@
|
||||
/*
|
||||
Copyright 2017 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package securitycontext
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"k8s.io/apimachinery/pkg/util/diff"
|
||||
api "k8s.io/kubernetes/pkg/apis/core"
|
||||
)
|
||||
|
||||
func TestPodSecurityContextAccessor(t *testing.T) {
|
||||
fsGroup := int64(2)
|
||||
runAsUser := int64(1)
|
||||
runAsNonRoot := true
|
||||
|
||||
testcases := []*api.PodSecurityContext{
|
||||
nil,
|
||||
{},
|
||||
{FSGroup: &fsGroup},
|
||||
{HostIPC: true},
|
||||
{HostNetwork: true},
|
||||
{HostPID: true},
|
||||
{RunAsNonRoot: &runAsNonRoot},
|
||||
{RunAsUser: &runAsUser},
|
||||
{SELinuxOptions: &api.SELinuxOptions{User: "bob"}},
|
||||
{SupplementalGroups: []int64{1, 2, 3}},
|
||||
}
|
||||
|
||||
for i, tc := range testcases {
|
||||
expected := tc
|
||||
if expected == nil {
|
||||
expected = &api.PodSecurityContext{}
|
||||
}
|
||||
|
||||
a := NewPodSecurityContextAccessor(tc)
|
||||
|
||||
if v := a.FSGroup(); !reflect.DeepEqual(expected.FSGroup, v) {
|
||||
t.Errorf("%d: expected %#v, got %#v", i, expected.FSGroup, v)
|
||||
}
|
||||
if v := a.HostIPC(); !reflect.DeepEqual(expected.HostIPC, v) {
|
||||
t.Errorf("%d: expected %#v, got %#v", i, expected.HostIPC, v)
|
||||
}
|
||||
if v := a.HostNetwork(); !reflect.DeepEqual(expected.HostNetwork, v) {
|
||||
t.Errorf("%d: expected %#v, got %#v", i, expected.HostNetwork, v)
|
||||
}
|
||||
if v := a.HostPID(); !reflect.DeepEqual(expected.HostPID, v) {
|
||||
t.Errorf("%d: expected %#v, got %#v", i, expected.HostPID, v)
|
||||
}
|
||||
if v := a.RunAsNonRoot(); !reflect.DeepEqual(expected.RunAsNonRoot, v) {
|
||||
t.Errorf("%d: expected %#v, got %#v", i, expected.RunAsNonRoot, v)
|
||||
}
|
||||
if v := a.RunAsUser(); !reflect.DeepEqual(expected.RunAsUser, v) {
|
||||
t.Errorf("%d: expected %#v, got %#v", i, expected.RunAsUser, v)
|
||||
}
|
||||
if v := a.SELinuxOptions(); !reflect.DeepEqual(expected.SELinuxOptions, v) {
|
||||
t.Errorf("%d: expected %#v, got %#v", i, expected.SELinuxOptions, v)
|
||||
}
|
||||
if v := a.SupplementalGroups(); !reflect.DeepEqual(expected.SupplementalGroups, v) {
|
||||
t.Errorf("%d: expected %#v, got %#v", i, expected.SupplementalGroups, v)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestPodSecurityContextMutator(t *testing.T) {
|
||||
testcases := map[string]struct {
|
||||
newSC func() *api.PodSecurityContext
|
||||
}{
|
||||
"nil": {
|
||||
newSC: func() *api.PodSecurityContext { return nil },
|
||||
},
|
||||
"zero": {
|
||||
newSC: func() *api.PodSecurityContext { return &api.PodSecurityContext{} },
|
||||
},
|
||||
"populated": {
|
||||
newSC: func() *api.PodSecurityContext {
|
||||
return &api.PodSecurityContext{
|
||||
HostNetwork: true,
|
||||
HostIPC: true,
|
||||
HostPID: true,
|
||||
SELinuxOptions: &api.SELinuxOptions{},
|
||||
RunAsUser: nil,
|
||||
RunAsNonRoot: nil,
|
||||
SupplementalGroups: nil,
|
||||
FSGroup: nil,
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
nonNilSC := func(sc *api.PodSecurityContext) *api.PodSecurityContext {
|
||||
if sc == nil {
|
||||
return &api.PodSecurityContext{}
|
||||
}
|
||||
return sc
|
||||
}
|
||||
|
||||
for k, tc := range testcases {
|
||||
{
|
||||
sc := tc.newSC()
|
||||
originalSC := tc.newSC()
|
||||
m := NewPodSecurityContextMutator(sc)
|
||||
|
||||
// no-op sets should not modify the object
|
||||
m.SetFSGroup(m.FSGroup())
|
||||
m.SetHostNetwork(m.HostNetwork())
|
||||
m.SetHostIPC(m.HostIPC())
|
||||
m.SetHostPID(m.HostPID())
|
||||
m.SetRunAsNonRoot(m.RunAsNonRoot())
|
||||
m.SetRunAsUser(m.RunAsUser())
|
||||
m.SetSELinuxOptions(m.SELinuxOptions())
|
||||
m.SetSupplementalGroups(m.SupplementalGroups())
|
||||
if !reflect.DeepEqual(sc, originalSC) {
|
||||
t.Errorf("%s: unexpected mutation: %#v, %#v", k, sc, originalSC)
|
||||
}
|
||||
if !reflect.DeepEqual(m.PodSecurityContext(), originalSC) {
|
||||
t.Errorf("%s: unexpected mutation: %#v, %#v", k, m.PodSecurityContext(), originalSC)
|
||||
}
|
||||
}
|
||||
|
||||
// FSGroup
|
||||
{
|
||||
modifiedSC := nonNilSC(tc.newSC())
|
||||
m := NewPodSecurityContextMutator(tc.newSC())
|
||||
i := int64(1123)
|
||||
modifiedSC.FSGroup = &i
|
||||
m.SetFSGroup(&i)
|
||||
if !reflect.DeepEqual(m.PodSecurityContext(), modifiedSC) {
|
||||
t.Errorf("%s: unexpected object:\n%s", k, diff.ObjectGoPrintSideBySide(modifiedSC, m.PodSecurityContext()))
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
// HostNetwork
|
||||
{
|
||||
modifiedSC := nonNilSC(tc.newSC())
|
||||
m := NewPodSecurityContextMutator(tc.newSC())
|
||||
modifiedSC.HostNetwork = !modifiedSC.HostNetwork
|
||||
m.SetHostNetwork(!m.HostNetwork())
|
||||
if !reflect.DeepEqual(m.PodSecurityContext(), modifiedSC) {
|
||||
t.Errorf("%s: unexpected object:\n%s", k, diff.ObjectGoPrintSideBySide(modifiedSC, m.PodSecurityContext()))
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
// HostIPC
|
||||
{
|
||||
modifiedSC := nonNilSC(tc.newSC())
|
||||
m := NewPodSecurityContextMutator(tc.newSC())
|
||||
modifiedSC.HostIPC = !modifiedSC.HostIPC
|
||||
m.SetHostIPC(!m.HostIPC())
|
||||
if !reflect.DeepEqual(m.PodSecurityContext(), modifiedSC) {
|
||||
t.Errorf("%s: unexpected object:\n%s", k, diff.ObjectGoPrintSideBySide(modifiedSC, m.PodSecurityContext()))
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
// HostPID
|
||||
{
|
||||
modifiedSC := nonNilSC(tc.newSC())
|
||||
m := NewPodSecurityContextMutator(tc.newSC())
|
||||
modifiedSC.HostPID = !modifiedSC.HostPID
|
||||
m.SetHostPID(!m.HostPID())
|
||||
if !reflect.DeepEqual(m.PodSecurityContext(), modifiedSC) {
|
||||
t.Errorf("%s: unexpected object:\n%s", k, diff.ObjectGoPrintSideBySide(modifiedSC, m.PodSecurityContext()))
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
// RunAsNonRoot
|
||||
{
|
||||
modifiedSC := nonNilSC(tc.newSC())
|
||||
m := NewPodSecurityContextMutator(tc.newSC())
|
||||
b := true
|
||||
modifiedSC.RunAsNonRoot = &b
|
||||
m.SetRunAsNonRoot(&b)
|
||||
if !reflect.DeepEqual(m.PodSecurityContext(), modifiedSC) {
|
||||
t.Errorf("%s: unexpected object:\n%s", k, diff.ObjectGoPrintSideBySide(modifiedSC, m.PodSecurityContext()))
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
// RunAsUser
|
||||
{
|
||||
modifiedSC := nonNilSC(tc.newSC())
|
||||
m := NewPodSecurityContextMutator(tc.newSC())
|
||||
i := int64(1123)
|
||||
modifiedSC.RunAsUser = &i
|
||||
m.SetRunAsUser(&i)
|
||||
if !reflect.DeepEqual(m.PodSecurityContext(), modifiedSC) {
|
||||
t.Errorf("%s: unexpected object:\n%s", k, diff.ObjectGoPrintSideBySide(modifiedSC, m.PodSecurityContext()))
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
// SELinuxOptions
|
||||
{
|
||||
modifiedSC := nonNilSC(tc.newSC())
|
||||
m := NewPodSecurityContextMutator(tc.newSC())
|
||||
modifiedSC.SELinuxOptions = &api.SELinuxOptions{User: "bob"}
|
||||
m.SetSELinuxOptions(&api.SELinuxOptions{User: "bob"})
|
||||
if !reflect.DeepEqual(m.PodSecurityContext(), modifiedSC) {
|
||||
t.Errorf("%s: unexpected object:\n%s", k, diff.ObjectGoPrintSideBySide(modifiedSC, m.PodSecurityContext()))
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
// SupplementalGroups
|
||||
{
|
||||
modifiedSC := nonNilSC(tc.newSC())
|
||||
m := NewPodSecurityContextMutator(tc.newSC())
|
||||
modifiedSC.SupplementalGroups = []int64{1, 1, 2, 3}
|
||||
m.SetSupplementalGroups([]int64{1, 1, 2, 3})
|
||||
if !reflect.DeepEqual(m.PodSecurityContext(), modifiedSC) {
|
||||
t.Errorf("%s: unexpected object:\n%s", k, diff.ObjectGoPrintSideBySide(modifiedSC, m.PodSecurityContext()))
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestContainerSecurityContextAccessor(t *testing.T) {
|
||||
privileged := true
|
||||
runAsUser := int64(1)
|
||||
runAsNonRoot := true
|
||||
readOnlyRootFilesystem := true
|
||||
allowPrivilegeEscalation := true
|
||||
|
||||
testcases := []*api.SecurityContext{
|
||||
nil,
|
||||
{},
|
||||
{Capabilities: &api.Capabilities{Drop: []api.Capability{"test"}}},
|
||||
{Privileged: &privileged},
|
||||
{SELinuxOptions: &api.SELinuxOptions{User: "bob"}},
|
||||
{RunAsUser: &runAsUser},
|
||||
{RunAsNonRoot: &runAsNonRoot},
|
||||
{ReadOnlyRootFilesystem: &readOnlyRootFilesystem},
|
||||
{AllowPrivilegeEscalation: &allowPrivilegeEscalation},
|
||||
}
|
||||
|
||||
for i, tc := range testcases {
|
||||
expected := tc
|
||||
if expected == nil {
|
||||
expected = &api.SecurityContext{}
|
||||
}
|
||||
|
||||
a := NewContainerSecurityContextAccessor(tc)
|
||||
|
||||
if v := a.Capabilities(); !reflect.DeepEqual(expected.Capabilities, v) {
|
||||
t.Errorf("%d: expected %#v, got %#v", i, expected.Capabilities, v)
|
||||
}
|
||||
if v := a.Privileged(); !reflect.DeepEqual(expected.Privileged, v) {
|
||||
t.Errorf("%d: expected %#v, got %#v", i, expected.Privileged, v)
|
||||
}
|
||||
if v := a.RunAsNonRoot(); !reflect.DeepEqual(expected.RunAsNonRoot, v) {
|
||||
t.Errorf("%d: expected %#v, got %#v", i, expected.RunAsNonRoot, v)
|
||||
}
|
||||
if v := a.RunAsUser(); !reflect.DeepEqual(expected.RunAsUser, v) {
|
||||
t.Errorf("%d: expected %#v, got %#v", i, expected.RunAsUser, v)
|
||||
}
|
||||
if v := a.SELinuxOptions(); !reflect.DeepEqual(expected.SELinuxOptions, v) {
|
||||
t.Errorf("%d: expected %#v, got %#v", i, expected.SELinuxOptions, v)
|
||||
}
|
||||
if v := a.ReadOnlyRootFilesystem(); !reflect.DeepEqual(expected.ReadOnlyRootFilesystem, v) {
|
||||
t.Errorf("%d: expected %#v, got %#v", i, expected.ReadOnlyRootFilesystem, v)
|
||||
}
|
||||
if v := a.AllowPrivilegeEscalation(); !reflect.DeepEqual(expected.AllowPrivilegeEscalation, v) {
|
||||
t.Errorf("%d: expected %#v, got %#v", i, expected.AllowPrivilegeEscalation, v)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestContainerSecurityContextMutator(t *testing.T) {
|
||||
testcases := map[string]struct {
|
||||
newSC func() *api.SecurityContext
|
||||
}{
|
||||
"nil": {
|
||||
newSC: func() *api.SecurityContext { return nil },
|
||||
},
|
||||
"zero": {
|
||||
newSC: func() *api.SecurityContext { return &api.SecurityContext{} },
|
||||
},
|
||||
"populated": {
|
||||
newSC: func() *api.SecurityContext {
|
||||
return &api.SecurityContext{
|
||||
Capabilities: &api.Capabilities{Drop: []api.Capability{"test"}},
|
||||
SELinuxOptions: &api.SELinuxOptions{},
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
nonNilSC := func(sc *api.SecurityContext) *api.SecurityContext {
|
||||
if sc == nil {
|
||||
return &api.SecurityContext{}
|
||||
}
|
||||
return sc
|
||||
}
|
||||
|
||||
for k, tc := range testcases {
|
||||
{
|
||||
sc := tc.newSC()
|
||||
originalSC := tc.newSC()
|
||||
m := NewContainerSecurityContextMutator(sc)
|
||||
|
||||
// no-op sets should not modify the object
|
||||
m.SetAllowPrivilegeEscalation(m.AllowPrivilegeEscalation())
|
||||
m.SetCapabilities(m.Capabilities())
|
||||
m.SetPrivileged(m.Privileged())
|
||||
m.SetReadOnlyRootFilesystem(m.ReadOnlyRootFilesystem())
|
||||
m.SetRunAsNonRoot(m.RunAsNonRoot())
|
||||
m.SetRunAsUser(m.RunAsUser())
|
||||
m.SetSELinuxOptions(m.SELinuxOptions())
|
||||
if !reflect.DeepEqual(sc, originalSC) {
|
||||
t.Errorf("%s: unexpected mutation: %#v, %#v", k, sc, originalSC)
|
||||
}
|
||||
if !reflect.DeepEqual(m.ContainerSecurityContext(), originalSC) {
|
||||
t.Errorf("%s: unexpected mutation: %#v, %#v", k, m.ContainerSecurityContext(), originalSC)
|
||||
}
|
||||
}
|
||||
|
||||
// AllowPrivilegeEscalation
|
||||
{
|
||||
modifiedSC := nonNilSC(tc.newSC())
|
||||
m := NewContainerSecurityContextMutator(tc.newSC())
|
||||
b := true
|
||||
modifiedSC.AllowPrivilegeEscalation = &b
|
||||
m.SetAllowPrivilegeEscalation(&b)
|
||||
if !reflect.DeepEqual(m.ContainerSecurityContext(), modifiedSC) {
|
||||
t.Errorf("%s: unexpected object:\n%s", k, diff.ObjectGoPrintSideBySide(modifiedSC, m.ContainerSecurityContext()))
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
// Capabilities
|
||||
{
|
||||
modifiedSC := nonNilSC(tc.newSC())
|
||||
m := NewContainerSecurityContextMutator(tc.newSC())
|
||||
modifiedSC.Capabilities = &api.Capabilities{Drop: []api.Capability{"test2"}}
|
||||
m.SetCapabilities(&api.Capabilities{Drop: []api.Capability{"test2"}})
|
||||
if !reflect.DeepEqual(m.ContainerSecurityContext(), modifiedSC) {
|
||||
t.Errorf("%s: unexpected object:\n%s", k, diff.ObjectGoPrintSideBySide(modifiedSC, m.ContainerSecurityContext()))
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
// Privileged
|
||||
{
|
||||
modifiedSC := nonNilSC(tc.newSC())
|
||||
m := NewContainerSecurityContextMutator(tc.newSC())
|
||||
b := true
|
||||
modifiedSC.Privileged = &b
|
||||
m.SetPrivileged(&b)
|
||||
if !reflect.DeepEqual(m.ContainerSecurityContext(), modifiedSC) {
|
||||
t.Errorf("%s: unexpected object:\n%s", k, diff.ObjectGoPrintSideBySide(modifiedSC, m.ContainerSecurityContext()))
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
// ReadOnlyRootFilesystem
|
||||
{
|
||||
modifiedSC := nonNilSC(tc.newSC())
|
||||
m := NewContainerSecurityContextMutator(tc.newSC())
|
||||
b := true
|
||||
modifiedSC.ReadOnlyRootFilesystem = &b
|
||||
m.SetReadOnlyRootFilesystem(&b)
|
||||
if !reflect.DeepEqual(m.ContainerSecurityContext(), modifiedSC) {
|
||||
t.Errorf("%s: unexpected object:\n%s", k, diff.ObjectGoPrintSideBySide(modifiedSC, m.ContainerSecurityContext()))
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
// RunAsNonRoot
|
||||
{
|
||||
modifiedSC := nonNilSC(tc.newSC())
|
||||
m := NewContainerSecurityContextMutator(tc.newSC())
|
||||
b := true
|
||||
modifiedSC.RunAsNonRoot = &b
|
||||
m.SetRunAsNonRoot(&b)
|
||||
if !reflect.DeepEqual(m.ContainerSecurityContext(), modifiedSC) {
|
||||
t.Errorf("%s: unexpected object:\n%s", k, diff.ObjectGoPrintSideBySide(modifiedSC, m.ContainerSecurityContext()))
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
// RunAsUser
|
||||
{
|
||||
modifiedSC := nonNilSC(tc.newSC())
|
||||
m := NewContainerSecurityContextMutator(tc.newSC())
|
||||
i := int64(1123)
|
||||
modifiedSC.RunAsUser = &i
|
||||
m.SetRunAsUser(&i)
|
||||
if !reflect.DeepEqual(m.ContainerSecurityContext(), modifiedSC) {
|
||||
t.Errorf("%s: unexpected object:\n%s", k, diff.ObjectGoPrintSideBySide(modifiedSC, m.ContainerSecurityContext()))
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
// SELinuxOptions
|
||||
{
|
||||
modifiedSC := nonNilSC(tc.newSC())
|
||||
m := NewContainerSecurityContextMutator(tc.newSC())
|
||||
modifiedSC.SELinuxOptions = &api.SELinuxOptions{User: "bob"}
|
||||
m.SetSELinuxOptions(&api.SELinuxOptions{User: "bob"})
|
||||
if !reflect.DeepEqual(m.ContainerSecurityContext(), modifiedSC) {
|
||||
t.Errorf("%s: unexpected object:\n%s", k, diff.ObjectGoPrintSideBySide(modifiedSC, m.ContainerSecurityContext()))
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestEffectiveContainerSecurityContextAccessor(t *testing.T) {
|
||||
privileged := true
|
||||
runAsUser := int64(1)
|
||||
runAsUserPod := int64(12)
|
||||
runAsNonRoot := true
|
||||
runAsNonRootPod := false
|
||||
readOnlyRootFilesystem := true
|
||||
allowPrivilegeEscalation := true
|
||||
|
||||
testcases := []struct {
|
||||
PodSC *api.PodSecurityContext
|
||||
SC *api.SecurityContext
|
||||
Effective *api.SecurityContext
|
||||
}{
|
||||
{
|
||||
PodSC: nil,
|
||||
SC: nil,
|
||||
Effective: nil,
|
||||
},
|
||||
{
|
||||
PodSC: &api.PodSecurityContext{},
|
||||
SC: &api.SecurityContext{},
|
||||
Effective: &api.SecurityContext{},
|
||||
},
|
||||
{
|
||||
PodSC: &api.PodSecurityContext{
|
||||
SELinuxOptions: &api.SELinuxOptions{User: "bob"},
|
||||
RunAsUser: &runAsUser,
|
||||
RunAsNonRoot: &runAsNonRoot,
|
||||
},
|
||||
SC: nil,
|
||||
Effective: &api.SecurityContext{
|
||||
SELinuxOptions: &api.SELinuxOptions{User: "bob"},
|
||||
RunAsUser: &runAsUser,
|
||||
RunAsNonRoot: &runAsNonRoot,
|
||||
},
|
||||
},
|
||||
{
|
||||
PodSC: &api.PodSecurityContext{
|
||||
SELinuxOptions: &api.SELinuxOptions{User: "bob"},
|
||||
RunAsUser: &runAsUserPod,
|
||||
RunAsNonRoot: &runAsNonRootPod,
|
||||
},
|
||||
SC: &api.SecurityContext{},
|
||||
Effective: &api.SecurityContext{
|
||||
SELinuxOptions: &api.SELinuxOptions{User: "bob"},
|
||||
RunAsUser: &runAsUserPod,
|
||||
RunAsNonRoot: &runAsNonRootPod,
|
||||
},
|
||||
},
|
||||
{
|
||||
PodSC: &api.PodSecurityContext{
|
||||
SELinuxOptions: &api.SELinuxOptions{User: "bob"},
|
||||
RunAsUser: &runAsUserPod,
|
||||
RunAsNonRoot: &runAsNonRootPod,
|
||||
},
|
||||
SC: &api.SecurityContext{
|
||||
AllowPrivilegeEscalation: &allowPrivilegeEscalation,
|
||||
Capabilities: &api.Capabilities{Drop: []api.Capability{"test"}},
|
||||
Privileged: &privileged,
|
||||
ReadOnlyRootFilesystem: &readOnlyRootFilesystem,
|
||||
RunAsUser: &runAsUser,
|
||||
RunAsNonRoot: &runAsNonRoot,
|
||||
SELinuxOptions: &api.SELinuxOptions{User: "bob"},
|
||||
},
|
||||
Effective: &api.SecurityContext{
|
||||
AllowPrivilegeEscalation: &allowPrivilegeEscalation,
|
||||
Capabilities: &api.Capabilities{Drop: []api.Capability{"test"}},
|
||||
Privileged: &privileged,
|
||||
ReadOnlyRootFilesystem: &readOnlyRootFilesystem,
|
||||
RunAsUser: &runAsUser,
|
||||
RunAsNonRoot: &runAsNonRoot,
|
||||
SELinuxOptions: &api.SELinuxOptions{User: "bob"},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for i, tc := range testcases {
|
||||
expected := tc.Effective
|
||||
if expected == nil {
|
||||
expected = &api.SecurityContext{}
|
||||
}
|
||||
|
||||
a := NewEffectiveContainerSecurityContextAccessor(
|
||||
NewPodSecurityContextAccessor(tc.PodSC),
|
||||
NewContainerSecurityContextMutator(tc.SC),
|
||||
)
|
||||
|
||||
if v := a.Capabilities(); !reflect.DeepEqual(expected.Capabilities, v) {
|
||||
t.Errorf("%d: expected %#v, got %#v", i, expected.Capabilities, v)
|
||||
}
|
||||
if v := a.Privileged(); !reflect.DeepEqual(expected.Privileged, v) {
|
||||
t.Errorf("%d: expected %#v, got %#v", i, expected.Privileged, v)
|
||||
}
|
||||
if v := a.RunAsNonRoot(); !reflect.DeepEqual(expected.RunAsNonRoot, v) {
|
||||
t.Errorf("%d: expected %#v, got %#v", i, expected.RunAsNonRoot, v)
|
||||
}
|
||||
if v := a.RunAsUser(); !reflect.DeepEqual(expected.RunAsUser, v) {
|
||||
t.Errorf("%d: expected %#v, got %#v", i, expected.RunAsUser, v)
|
||||
}
|
||||
if v := a.SELinuxOptions(); !reflect.DeepEqual(expected.SELinuxOptions, v) {
|
||||
t.Errorf("%d: expected %#v, got %#v", i, expected.SELinuxOptions, v)
|
||||
}
|
||||
if v := a.ReadOnlyRootFilesystem(); !reflect.DeepEqual(expected.ReadOnlyRootFilesystem, v) {
|
||||
t.Errorf("%d: expected %#v, got %#v", i, expected.ReadOnlyRootFilesystem, v)
|
||||
}
|
||||
if v := a.AllowPrivilegeEscalation(); !reflect.DeepEqual(expected.AllowPrivilegeEscalation, v) {
|
||||
t.Errorf("%d: expected %#v, got %#v", i, expected.AllowPrivilegeEscalation, v)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestEffectiveContainerSecurityContextMutator(t *testing.T) {
|
||||
runAsNonRootPod := false
|
||||
runAsUserPod := int64(12)
|
||||
|
||||
testcases := map[string]struct {
|
||||
newPodSC func() *api.PodSecurityContext
|
||||
newSC func() *api.SecurityContext
|
||||
}{
|
||||
"nil": {
|
||||
newPodSC: func() *api.PodSecurityContext { return nil },
|
||||
newSC: func() *api.SecurityContext { return nil },
|
||||
},
|
||||
"zero": {
|
||||
newPodSC: func() *api.PodSecurityContext { return &api.PodSecurityContext{} },
|
||||
newSC: func() *api.SecurityContext { return &api.SecurityContext{} },
|
||||
},
|
||||
"populated pod sc": {
|
||||
newPodSC: func() *api.PodSecurityContext {
|
||||
return &api.PodSecurityContext{
|
||||
SELinuxOptions: &api.SELinuxOptions{User: "poduser"},
|
||||
RunAsNonRoot: &runAsNonRootPod,
|
||||
RunAsUser: &runAsUserPod,
|
||||
}
|
||||
},
|
||||
newSC: func() *api.SecurityContext {
|
||||
return &api.SecurityContext{}
|
||||
},
|
||||
},
|
||||
"populated sc": {
|
||||
newPodSC: func() *api.PodSecurityContext { return nil },
|
||||
newSC: func() *api.SecurityContext {
|
||||
return &api.SecurityContext{
|
||||
Capabilities: &api.Capabilities{Drop: []api.Capability{"test"}},
|
||||
SELinuxOptions: &api.SELinuxOptions{},
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
nonNilSC := func(sc *api.SecurityContext) *api.SecurityContext {
|
||||
if sc == nil {
|
||||
return &api.SecurityContext{}
|
||||
}
|
||||
return sc
|
||||
}
|
||||
|
||||
for k, tc := range testcases {
|
||||
{
|
||||
podSC := tc.newPodSC()
|
||||
sc := tc.newSC()
|
||||
originalPodSC := tc.newPodSC()
|
||||
originalSC := tc.newSC()
|
||||
m := NewEffectiveContainerSecurityContextMutator(
|
||||
NewPodSecurityContextAccessor(podSC),
|
||||
NewContainerSecurityContextMutator(sc),
|
||||
)
|
||||
|
||||
// no-op sets should not modify the object
|
||||
m.SetAllowPrivilegeEscalation(m.AllowPrivilegeEscalation())
|
||||
m.SetCapabilities(m.Capabilities())
|
||||
m.SetPrivileged(m.Privileged())
|
||||
m.SetReadOnlyRootFilesystem(m.ReadOnlyRootFilesystem())
|
||||
m.SetRunAsNonRoot(m.RunAsNonRoot())
|
||||
m.SetRunAsUser(m.RunAsUser())
|
||||
m.SetSELinuxOptions(m.SELinuxOptions())
|
||||
if !reflect.DeepEqual(podSC, originalPodSC) {
|
||||
t.Errorf("%s: unexpected mutation: %#v, %#v", k, podSC, originalPodSC)
|
||||
}
|
||||
if !reflect.DeepEqual(sc, originalSC) {
|
||||
t.Errorf("%s: unexpected mutation: %#v, %#v", k, sc, originalSC)
|
||||
}
|
||||
if !reflect.DeepEqual(m.ContainerSecurityContext(), originalSC) {
|
||||
t.Errorf("%s: unexpected mutation: %#v, %#v", k, m.ContainerSecurityContext(), originalSC)
|
||||
}
|
||||
}
|
||||
|
||||
// AllowPrivilegeEscalation
|
||||
{
|
||||
modifiedSC := nonNilSC(tc.newSC())
|
||||
m := NewEffectiveContainerSecurityContextMutator(
|
||||
NewPodSecurityContextAccessor(tc.newPodSC()),
|
||||
NewContainerSecurityContextMutator(tc.newSC()),
|
||||
)
|
||||
b := true
|
||||
modifiedSC.AllowPrivilegeEscalation = &b
|
||||
m.SetAllowPrivilegeEscalation(&b)
|
||||
if !reflect.DeepEqual(m.ContainerSecurityContext(), modifiedSC) {
|
||||
t.Errorf("%s: unexpected object:\n%s", k, diff.ObjectGoPrintSideBySide(modifiedSC, m.ContainerSecurityContext()))
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
// Capabilities
|
||||
{
|
||||
modifiedSC := nonNilSC(tc.newSC())
|
||||
m := NewEffectiveContainerSecurityContextMutator(
|
||||
NewPodSecurityContextAccessor(tc.newPodSC()),
|
||||
NewContainerSecurityContextMutator(tc.newSC()),
|
||||
)
|
||||
modifiedSC.Capabilities = &api.Capabilities{Drop: []api.Capability{"test2"}}
|
||||
m.SetCapabilities(&api.Capabilities{Drop: []api.Capability{"test2"}})
|
||||
if !reflect.DeepEqual(m.ContainerSecurityContext(), modifiedSC) {
|
||||
t.Errorf("%s: unexpected object:\n%s", k, diff.ObjectGoPrintSideBySide(modifiedSC, m.ContainerSecurityContext()))
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
// Privileged
|
||||
{
|
||||
modifiedSC := nonNilSC(tc.newSC())
|
||||
m := NewEffectiveContainerSecurityContextMutator(
|
||||
NewPodSecurityContextAccessor(tc.newPodSC()),
|
||||
NewContainerSecurityContextMutator(tc.newSC()),
|
||||
)
|
||||
b := true
|
||||
modifiedSC.Privileged = &b
|
||||
m.SetPrivileged(&b)
|
||||
if !reflect.DeepEqual(m.ContainerSecurityContext(), modifiedSC) {
|
||||
t.Errorf("%s: unexpected object:\n%s", k, diff.ObjectGoPrintSideBySide(modifiedSC, m.ContainerSecurityContext()))
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
// ReadOnlyRootFilesystem
|
||||
{
|
||||
modifiedSC := nonNilSC(tc.newSC())
|
||||
m := NewEffectiveContainerSecurityContextMutator(
|
||||
NewPodSecurityContextAccessor(tc.newPodSC()),
|
||||
NewContainerSecurityContextMutator(tc.newSC()),
|
||||
)
|
||||
b := true
|
||||
modifiedSC.ReadOnlyRootFilesystem = &b
|
||||
m.SetReadOnlyRootFilesystem(&b)
|
||||
if !reflect.DeepEqual(m.ContainerSecurityContext(), modifiedSC) {
|
||||
t.Errorf("%s: unexpected object:\n%s", k, diff.ObjectGoPrintSideBySide(modifiedSC, m.ContainerSecurityContext()))
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
// RunAsNonRoot
|
||||
{
|
||||
modifiedSC := nonNilSC(tc.newSC())
|
||||
m := NewEffectiveContainerSecurityContextMutator(
|
||||
NewPodSecurityContextAccessor(tc.newPodSC()),
|
||||
NewContainerSecurityContextMutator(tc.newSC()),
|
||||
)
|
||||
b := true
|
||||
modifiedSC.RunAsNonRoot = &b
|
||||
m.SetRunAsNonRoot(&b)
|
||||
if !reflect.DeepEqual(m.ContainerSecurityContext(), modifiedSC) {
|
||||
t.Errorf("%s: unexpected object:\n%s", k, diff.ObjectGoPrintSideBySide(modifiedSC, m.ContainerSecurityContext()))
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
// RunAsUser
|
||||
{
|
||||
modifiedSC := nonNilSC(tc.newSC())
|
||||
m := NewEffectiveContainerSecurityContextMutator(
|
||||
NewPodSecurityContextAccessor(tc.newPodSC()),
|
||||
NewContainerSecurityContextMutator(tc.newSC()),
|
||||
)
|
||||
i := int64(1123)
|
||||
modifiedSC.RunAsUser = &i
|
||||
m.SetRunAsUser(&i)
|
||||
if !reflect.DeepEqual(m.ContainerSecurityContext(), modifiedSC) {
|
||||
t.Errorf("%s: unexpected object:\n%s", k, diff.ObjectGoPrintSideBySide(modifiedSC, m.ContainerSecurityContext()))
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
// SELinuxOptions
|
||||
{
|
||||
modifiedSC := nonNilSC(tc.newSC())
|
||||
m := NewEffectiveContainerSecurityContextMutator(
|
||||
NewPodSecurityContextAccessor(tc.newPodSC()),
|
||||
NewContainerSecurityContextMutator(tc.newSC()),
|
||||
)
|
||||
modifiedSC.SELinuxOptions = &api.SELinuxOptions{User: "bob"}
|
||||
m.SetSELinuxOptions(&api.SELinuxOptions{User: "bob"})
|
||||
if !reflect.DeepEqual(m.ContainerSecurityContext(), modifiedSC) {
|
||||
t.Errorf("%s: unexpected object:\n%s", k, diff.ObjectGoPrintSideBySide(modifiedSC, m.ContainerSecurityContext()))
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
18
vendor/k8s.io/kubernetes/pkg/securitycontext/doc.go
generated
vendored
Normal file
18
vendor/k8s.io/kubernetes/pkg/securitycontext/doc.go
generated
vendored
Normal file
@ -0,0 +1,18 @@
|
||||
/*
|
||||
Copyright 2014 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Package securitycontext contains security context api implementations
|
||||
package securitycontext // import "k8s.io/kubernetes/pkg/securitycontext"
|
42
vendor/k8s.io/kubernetes/pkg/securitycontext/fake.go
generated
vendored
Normal file
42
vendor/k8s.io/kubernetes/pkg/securitycontext/fake.go
generated
vendored
Normal file
@ -0,0 +1,42 @@
|
||||
/*
|
||||
Copyright 2014 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package securitycontext
|
||||
|
||||
import (
|
||||
"k8s.io/api/core/v1"
|
||||
api "k8s.io/kubernetes/pkg/apis/core"
|
||||
)
|
||||
|
||||
// ValidSecurityContextWithContainerDefaults creates a valid security context provider based on
|
||||
// empty container defaults. Used for testing.
|
||||
func ValidSecurityContextWithContainerDefaults() *v1.SecurityContext {
|
||||
priv := false
|
||||
return &v1.SecurityContext{
|
||||
Capabilities: &v1.Capabilities{},
|
||||
Privileged: &priv,
|
||||
}
|
||||
}
|
||||
|
||||
// ValidInternalSecurityContextWithContainerDefaults creates a valid security context provider based on
|
||||
// empty container defaults. Used for testing.
|
||||
func ValidInternalSecurityContextWithContainerDefaults() *api.SecurityContext {
|
||||
priv := false
|
||||
return &api.SecurityContext{
|
||||
Capabilities: &api.Capabilities{},
|
||||
Privileged: &priv,
|
||||
}
|
||||
}
|
258
vendor/k8s.io/kubernetes/pkg/securitycontext/util.go
generated
vendored
Normal file
258
vendor/k8s.io/kubernetes/pkg/securitycontext/util.go
generated
vendored
Normal file
@ -0,0 +1,258 @@
|
||||
/*
|
||||
Copyright 2014 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package securitycontext
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"k8s.io/api/core/v1"
|
||||
api "k8s.io/kubernetes/pkg/apis/core"
|
||||
)
|
||||
|
||||
// HasPrivilegedRequest returns the value of SecurityContext.Privileged, taking into account
|
||||
// the possibility of nils
|
||||
func HasPrivilegedRequest(container *v1.Container) bool {
|
||||
if container.SecurityContext == nil {
|
||||
return false
|
||||
}
|
||||
if container.SecurityContext.Privileged == nil {
|
||||
return false
|
||||
}
|
||||
return *container.SecurityContext.Privileged
|
||||
}
|
||||
|
||||
// HasCapabilitiesRequest returns true if Adds or Drops are defined in the security context
|
||||
// capabilities, taking into account nils
|
||||
func HasCapabilitiesRequest(container *v1.Container) bool {
|
||||
if container.SecurityContext == nil {
|
||||
return false
|
||||
}
|
||||
if container.SecurityContext.Capabilities == nil {
|
||||
return false
|
||||
}
|
||||
return len(container.SecurityContext.Capabilities.Add) > 0 || len(container.SecurityContext.Capabilities.Drop) > 0
|
||||
}
|
||||
|
||||
const expectedSELinuxFields = 4
|
||||
|
||||
// ParseSELinuxOptions parses a string containing a full SELinux context
|
||||
// (user, role, type, and level) into an SELinuxOptions object. If the
|
||||
// context is malformed, an error is returned.
|
||||
func ParseSELinuxOptions(context string) (*v1.SELinuxOptions, error) {
|
||||
fields := strings.SplitN(context, ":", expectedSELinuxFields)
|
||||
|
||||
if len(fields) != expectedSELinuxFields {
|
||||
return nil, fmt.Errorf("expected %v fields in selinux; got %v (context: %v)", expectedSELinuxFields, len(fields), context)
|
||||
}
|
||||
|
||||
return &v1.SELinuxOptions{
|
||||
User: fields[0],
|
||||
Role: fields[1],
|
||||
Type: fields[2],
|
||||
Level: fields[3],
|
||||
}, nil
|
||||
}
|
||||
|
||||
// HasNonRootUID returns true if the runAsUser is set and is greater than 0.
|
||||
func HasRootUID(container *v1.Container) bool {
|
||||
if container.SecurityContext == nil {
|
||||
return false
|
||||
}
|
||||
if container.SecurityContext.RunAsUser == nil {
|
||||
return false
|
||||
}
|
||||
return *container.SecurityContext.RunAsUser == 0
|
||||
}
|
||||
|
||||
// HasRunAsUser determines if the sc's runAsUser field is set.
|
||||
func HasRunAsUser(container *v1.Container) bool {
|
||||
return container.SecurityContext != nil && container.SecurityContext.RunAsUser != nil
|
||||
}
|
||||
|
||||
// HasRootRunAsUser returns true if the run as user is set and it is set to 0.
|
||||
func HasRootRunAsUser(container *v1.Container) bool {
|
||||
return HasRunAsUser(container) && HasRootUID(container)
|
||||
}
|
||||
|
||||
func DetermineEffectiveSecurityContext(pod *v1.Pod, container *v1.Container) *v1.SecurityContext {
|
||||
effectiveSc := securityContextFromPodSecurityContext(pod)
|
||||
containerSc := container.SecurityContext
|
||||
|
||||
if effectiveSc == nil && containerSc == nil {
|
||||
return nil
|
||||
}
|
||||
if effectiveSc != nil && containerSc == nil {
|
||||
return effectiveSc
|
||||
}
|
||||
if effectiveSc == nil && containerSc != nil {
|
||||
return containerSc
|
||||
}
|
||||
|
||||
if containerSc.SELinuxOptions != nil {
|
||||
effectiveSc.SELinuxOptions = new(v1.SELinuxOptions)
|
||||
*effectiveSc.SELinuxOptions = *containerSc.SELinuxOptions
|
||||
}
|
||||
|
||||
if containerSc.Capabilities != nil {
|
||||
effectiveSc.Capabilities = new(v1.Capabilities)
|
||||
*effectiveSc.Capabilities = *containerSc.Capabilities
|
||||
}
|
||||
|
||||
if containerSc.Privileged != nil {
|
||||
effectiveSc.Privileged = new(bool)
|
||||
*effectiveSc.Privileged = *containerSc.Privileged
|
||||
}
|
||||
|
||||
if containerSc.RunAsUser != nil {
|
||||
effectiveSc.RunAsUser = new(int64)
|
||||
*effectiveSc.RunAsUser = *containerSc.RunAsUser
|
||||
}
|
||||
|
||||
if containerSc.RunAsNonRoot != nil {
|
||||
effectiveSc.RunAsNonRoot = new(bool)
|
||||
*effectiveSc.RunAsNonRoot = *containerSc.RunAsNonRoot
|
||||
}
|
||||
|
||||
if containerSc.ReadOnlyRootFilesystem != nil {
|
||||
effectiveSc.ReadOnlyRootFilesystem = new(bool)
|
||||
*effectiveSc.ReadOnlyRootFilesystem = *containerSc.ReadOnlyRootFilesystem
|
||||
}
|
||||
|
||||
if containerSc.AllowPrivilegeEscalation != nil {
|
||||
effectiveSc.AllowPrivilegeEscalation = new(bool)
|
||||
*effectiveSc.AllowPrivilegeEscalation = *containerSc.AllowPrivilegeEscalation
|
||||
}
|
||||
|
||||
return effectiveSc
|
||||
}
|
||||
|
||||
func securityContextFromPodSecurityContext(pod *v1.Pod) *v1.SecurityContext {
|
||||
if pod.Spec.SecurityContext == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
synthesized := &v1.SecurityContext{}
|
||||
|
||||
if pod.Spec.SecurityContext.SELinuxOptions != nil {
|
||||
synthesized.SELinuxOptions = &v1.SELinuxOptions{}
|
||||
*synthesized.SELinuxOptions = *pod.Spec.SecurityContext.SELinuxOptions
|
||||
}
|
||||
if pod.Spec.SecurityContext.RunAsUser != nil {
|
||||
synthesized.RunAsUser = new(int64)
|
||||
*synthesized.RunAsUser = *pod.Spec.SecurityContext.RunAsUser
|
||||
}
|
||||
|
||||
if pod.Spec.SecurityContext.RunAsNonRoot != nil {
|
||||
synthesized.RunAsNonRoot = new(bool)
|
||||
*synthesized.RunAsNonRoot = *pod.Spec.SecurityContext.RunAsNonRoot
|
||||
}
|
||||
|
||||
return synthesized
|
||||
}
|
||||
|
||||
// TODO: remove the duplicate code
|
||||
func InternalDetermineEffectiveSecurityContext(pod *api.Pod, container *api.Container) *api.SecurityContext {
|
||||
effectiveSc := internalSecurityContextFromPodSecurityContext(pod)
|
||||
containerSc := container.SecurityContext
|
||||
|
||||
if effectiveSc == nil && containerSc == nil {
|
||||
return nil
|
||||
}
|
||||
if effectiveSc != nil && containerSc == nil {
|
||||
return effectiveSc
|
||||
}
|
||||
if effectiveSc == nil && containerSc != nil {
|
||||
return containerSc
|
||||
}
|
||||
|
||||
if containerSc.SELinuxOptions != nil {
|
||||
effectiveSc.SELinuxOptions = new(api.SELinuxOptions)
|
||||
*effectiveSc.SELinuxOptions = *containerSc.SELinuxOptions
|
||||
}
|
||||
|
||||
if containerSc.Capabilities != nil {
|
||||
effectiveSc.Capabilities = new(api.Capabilities)
|
||||
*effectiveSc.Capabilities = *containerSc.Capabilities
|
||||
}
|
||||
|
||||
if containerSc.Privileged != nil {
|
||||
effectiveSc.Privileged = new(bool)
|
||||
*effectiveSc.Privileged = *containerSc.Privileged
|
||||
}
|
||||
|
||||
if containerSc.RunAsUser != nil {
|
||||
effectiveSc.RunAsUser = new(int64)
|
||||
*effectiveSc.RunAsUser = *containerSc.RunAsUser
|
||||
}
|
||||
|
||||
if containerSc.RunAsNonRoot != nil {
|
||||
effectiveSc.RunAsNonRoot = new(bool)
|
||||
*effectiveSc.RunAsNonRoot = *containerSc.RunAsNonRoot
|
||||
}
|
||||
|
||||
if containerSc.ReadOnlyRootFilesystem != nil {
|
||||
effectiveSc.ReadOnlyRootFilesystem = new(bool)
|
||||
*effectiveSc.ReadOnlyRootFilesystem = *containerSc.ReadOnlyRootFilesystem
|
||||
}
|
||||
|
||||
if containerSc.AllowPrivilegeEscalation != nil {
|
||||
effectiveSc.AllowPrivilegeEscalation = new(bool)
|
||||
*effectiveSc.AllowPrivilegeEscalation = *containerSc.AllowPrivilegeEscalation
|
||||
}
|
||||
|
||||
return effectiveSc
|
||||
}
|
||||
|
||||
func internalSecurityContextFromPodSecurityContext(pod *api.Pod) *api.SecurityContext {
|
||||
if pod.Spec.SecurityContext == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
synthesized := &api.SecurityContext{}
|
||||
|
||||
if pod.Spec.SecurityContext.SELinuxOptions != nil {
|
||||
synthesized.SELinuxOptions = &api.SELinuxOptions{}
|
||||
*synthesized.SELinuxOptions = *pod.Spec.SecurityContext.SELinuxOptions
|
||||
}
|
||||
if pod.Spec.SecurityContext.RunAsUser != nil {
|
||||
synthesized.RunAsUser = new(int64)
|
||||
*synthesized.RunAsUser = *pod.Spec.SecurityContext.RunAsUser
|
||||
}
|
||||
|
||||
if pod.Spec.SecurityContext.RunAsNonRoot != nil {
|
||||
synthesized.RunAsNonRoot = new(bool)
|
||||
*synthesized.RunAsNonRoot = *pod.Spec.SecurityContext.RunAsNonRoot
|
||||
}
|
||||
|
||||
return synthesized
|
||||
}
|
||||
|
||||
// AddNoNewPrivileges returns if we should add the no_new_privs option.
|
||||
func AddNoNewPrivileges(sc *v1.SecurityContext) bool {
|
||||
if sc == nil {
|
||||
return false
|
||||
}
|
||||
|
||||
// handle the case where the user did not set the default and did not explicitly set allowPrivilegeEscalation
|
||||
if sc.AllowPrivilegeEscalation == nil {
|
||||
return false
|
||||
}
|
||||
|
||||
// handle the case where defaultAllowPrivilegeEscalation is false or the user explicitly set allowPrivilegeEscalation to true/false
|
||||
return !*sc.AllowPrivilegeEscalation
|
||||
}
|
235
vendor/k8s.io/kubernetes/pkg/securitycontext/util_test.go
generated
vendored
Normal file
235
vendor/k8s.io/kubernetes/pkg/securitycontext/util_test.go
generated
vendored
Normal file
@ -0,0 +1,235 @@
|
||||
/*
|
||||
Copyright 2014 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package securitycontext
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"k8s.io/api/core/v1"
|
||||
)
|
||||
|
||||
func TestParseSELinuxOptions(t *testing.T) {
|
||||
cases := []struct {
|
||||
name string
|
||||
input string
|
||||
expected *v1.SELinuxOptions
|
||||
}{
|
||||
{
|
||||
name: "simple",
|
||||
input: "user_t:role_t:type_t:s0",
|
||||
expected: &v1.SELinuxOptions{
|
||||
User: "user_t",
|
||||
Role: "role_t",
|
||||
Type: "type_t",
|
||||
Level: "s0",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "simple + categories",
|
||||
input: "user_t:role_t:type_t:s0:c0",
|
||||
expected: &v1.SELinuxOptions{
|
||||
User: "user_t",
|
||||
Role: "role_t",
|
||||
Type: "type_t",
|
||||
Level: "s0:c0",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "not enough fields",
|
||||
input: "type_t:s0:c0",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range cases {
|
||||
result, err := ParseSELinuxOptions(tc.input)
|
||||
|
||||
if err != nil {
|
||||
if tc.expected == nil {
|
||||
continue
|
||||
} else {
|
||||
t.Errorf("%v: unexpected error: %v", tc.name, err)
|
||||
}
|
||||
}
|
||||
|
||||
compareContexts(tc.name, tc.expected, result, t)
|
||||
}
|
||||
}
|
||||
|
||||
func compareContexts(name string, ex, ac *v1.SELinuxOptions, t *testing.T) {
|
||||
if e, a := ex.User, ac.User; e != a {
|
||||
t.Errorf("%v: expected user: %v, got: %v", name, e, a)
|
||||
}
|
||||
if e, a := ex.Role, ac.Role; e != a {
|
||||
t.Errorf("%v: expected role: %v, got: %v", name, e, a)
|
||||
}
|
||||
if e, a := ex.Type, ac.Type; e != a {
|
||||
t.Errorf("%v: expected type: %v, got: %v", name, e, a)
|
||||
}
|
||||
if e, a := ex.Level, ac.Level; e != a {
|
||||
t.Errorf("%v: expected level: %v, got: %v", name, e, a)
|
||||
}
|
||||
}
|
||||
|
||||
func containerWithUser(ptr *int64) *v1.Container {
|
||||
return &v1.Container{SecurityContext: &v1.SecurityContext{RunAsUser: ptr}}
|
||||
}
|
||||
|
||||
func TestHaRootUID(t *testing.T) {
|
||||
nonRoot := int64(1)
|
||||
root := int64(0)
|
||||
|
||||
tests := map[string]struct {
|
||||
container *v1.Container
|
||||
expect bool
|
||||
}{
|
||||
"nil sc": {
|
||||
container: &v1.Container{SecurityContext: nil},
|
||||
},
|
||||
"nil runAsuser": {
|
||||
container: containerWithUser(nil),
|
||||
},
|
||||
"runAsUser non-root": {
|
||||
container: containerWithUser(&nonRoot),
|
||||
},
|
||||
"runAsUser root": {
|
||||
container: containerWithUser(&root),
|
||||
expect: true,
|
||||
},
|
||||
}
|
||||
|
||||
for k, v := range tests {
|
||||
actual := HasRootUID(v.container)
|
||||
if actual != v.expect {
|
||||
t.Errorf("%s failed, expected %t but received %t", k, v.expect, actual)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestHasRunAsUser(t *testing.T) {
|
||||
runAsUser := int64(0)
|
||||
|
||||
tests := map[string]struct {
|
||||
container *v1.Container
|
||||
expect bool
|
||||
}{
|
||||
"nil sc": {
|
||||
container: &v1.Container{SecurityContext: nil},
|
||||
},
|
||||
"nil runAsUser": {
|
||||
container: containerWithUser(nil),
|
||||
},
|
||||
"valid runAsUser": {
|
||||
container: containerWithUser(&runAsUser),
|
||||
expect: true,
|
||||
},
|
||||
}
|
||||
|
||||
for k, v := range tests {
|
||||
actual := HasRunAsUser(v.container)
|
||||
if actual != v.expect {
|
||||
t.Errorf("%s failed, expected %t but received %t", k, v.expect, actual)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestHasRootRunAsUser(t *testing.T) {
|
||||
nonRoot := int64(1)
|
||||
root := int64(0)
|
||||
|
||||
tests := map[string]struct {
|
||||
container *v1.Container
|
||||
expect bool
|
||||
}{
|
||||
"nil sc": {
|
||||
container: &v1.Container{SecurityContext: nil},
|
||||
},
|
||||
"nil runAsuser": {
|
||||
container: containerWithUser(nil),
|
||||
},
|
||||
"runAsUser non-root": {
|
||||
container: containerWithUser(&nonRoot),
|
||||
},
|
||||
"runAsUser root": {
|
||||
container: containerWithUser(&root),
|
||||
expect: true,
|
||||
},
|
||||
}
|
||||
|
||||
for k, v := range tests {
|
||||
actual := HasRootRunAsUser(v.container)
|
||||
if actual != v.expect {
|
||||
t.Errorf("%s failed, expected %t but received %t", k, v.expect, actual)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestAddNoNewPrivileges(t *testing.T) {
|
||||
var nonRoot int64 = 1000
|
||||
var root int64 = 0
|
||||
pfalse := false
|
||||
ptrue := true
|
||||
|
||||
tests := map[string]struct {
|
||||
sc v1.SecurityContext
|
||||
expect bool
|
||||
}{
|
||||
"allowPrivilegeEscalation nil security context nil": {},
|
||||
"allowPrivilegeEscalation nil nonRoot": {
|
||||
sc: v1.SecurityContext{
|
||||
RunAsUser: &nonRoot,
|
||||
},
|
||||
},
|
||||
"allowPrivilegeEscalation nil root": {
|
||||
sc: v1.SecurityContext{
|
||||
RunAsUser: &root,
|
||||
},
|
||||
},
|
||||
"allowPrivilegeEscalation false nonRoot": {
|
||||
sc: v1.SecurityContext{
|
||||
RunAsUser: &nonRoot,
|
||||
AllowPrivilegeEscalation: &pfalse,
|
||||
},
|
||||
expect: true,
|
||||
},
|
||||
"allowPrivilegeEscalation false root": {
|
||||
sc: v1.SecurityContext{
|
||||
RunAsUser: &root,
|
||||
AllowPrivilegeEscalation: &pfalse,
|
||||
},
|
||||
expect: true,
|
||||
},
|
||||
"allowPrivilegeEscalation true nonRoot": {
|
||||
sc: v1.SecurityContext{
|
||||
RunAsUser: &nonRoot,
|
||||
AllowPrivilegeEscalation: &ptrue,
|
||||
},
|
||||
},
|
||||
"allowPrivilegeEscalation true root": {
|
||||
sc: v1.SecurityContext{
|
||||
RunAsUser: &root,
|
||||
AllowPrivilegeEscalation: &ptrue,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for k, v := range tests {
|
||||
actual := AddNoNewPrivileges(&v.sc)
|
||||
if actual != v.expect {
|
||||
t.Errorf("%s failed, expected %t but received %t", k, v.expect, actual)
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user