Add "MayRunAs" value among other GroupStrategies

Adds "MayRunAs" value among other group strategies. This strategy allows to define a certain range of GIDs for FSGroupStrategy and SupplementalGroupStrategy in a PSP. This new strategy works similarly to the "MustRunAs" one, except that when no GID is specified in a pod/container security context then no GID is generated for the respective containers. Resolves #56173
parent e3dbad32
...@@ -48,12 +48,14 @@ var Funcs = func(codecs runtimeserializer.CodecFactory) []interface{} { ...@@ -48,12 +48,14 @@ var Funcs = func(codecs runtimeserializer.CodecFactory) []interface{} {
supplementalGroupsRules := []policy.SupplementalGroupsStrategyType{ supplementalGroupsRules := []policy.SupplementalGroupsStrategyType{
policy.SupplementalGroupsStrategyRunAsAny, policy.SupplementalGroupsStrategyRunAsAny,
policy.SupplementalGroupsStrategyMayRunAs,
policy.SupplementalGroupsStrategyMustRunAs, policy.SupplementalGroupsStrategyMustRunAs,
} }
psp.SupplementalGroups.Rule = supplementalGroupsRules[c.Rand.Intn(len(supplementalGroupsRules))] psp.SupplementalGroups.Rule = supplementalGroupsRules[c.Rand.Intn(len(supplementalGroupsRules))]
fsGroupRules := []policy.FSGroupStrategyType{ fsGroupRules := []policy.FSGroupStrategyType{
policy.FSGroupStrategyMustRunAs, policy.FSGroupStrategyMustRunAs,
policy.FSGroupStrategyMayRunAs,
policy.FSGroupStrategyRunAsAny, policy.FSGroupStrategyRunAsAny,
} }
psp.FSGroup.Rule = fsGroupRules[c.Rand.Intn(len(fsGroupRules))] psp.FSGroup.Rule = fsGroupRules[c.Rand.Intn(len(fsGroupRules))]
......
...@@ -372,6 +372,9 @@ type FSGroupStrategyOptions struct { ...@@ -372,6 +372,9 @@ type FSGroupStrategyOptions struct {
type FSGroupStrategyType string type FSGroupStrategyType string
const ( const (
// FSGroupStrategyMayRunAs means that container does not need to have FSGroup of X applied.
// However, when FSGroups are specified, they have to fall in the defined range.
FSGroupStrategyMayRunAs FSGroupStrategyType = "MayRunAs"
// FSGroupStrategyMustRunAs means that container must have FSGroup of X applied. // FSGroupStrategyMustRunAs means that container must have FSGroup of X applied.
FSGroupStrategyMustRunAs FSGroupStrategyType = "MustRunAs" FSGroupStrategyMustRunAs FSGroupStrategyType = "MustRunAs"
// FSGroupStrategyRunAsAny means that container may make requests for any FSGroup labels. // FSGroupStrategyRunAsAny means that container may make requests for any FSGroup labels.
...@@ -394,6 +397,9 @@ type SupplementalGroupsStrategyOptions struct { ...@@ -394,6 +397,9 @@ type SupplementalGroupsStrategyOptions struct {
type SupplementalGroupsStrategyType string type SupplementalGroupsStrategyType string
const ( const (
// SupplementalGroupsStrategyMayRunAs means that container does not need to run with a particular gid.
// However, when gids are specified, they have to fall in the defined range.
SupplementalGroupsStrategyMayRunAs SupplementalGroupsStrategyType = "MayRunAs"
// SupplementalGroupsStrategyMustRunAs means that container must run as a particular gid. // SupplementalGroupsStrategyMustRunAs means that container must run as a particular gid.
SupplementalGroupsStrategyMustRunAs SupplementalGroupsStrategyType = "MustRunAs" SupplementalGroupsStrategyMustRunAs SupplementalGroupsStrategyType = "MustRunAs"
// SupplementalGroupsStrategyRunAsAny means that container may make requests for any gid. // SupplementalGroupsStrategyRunAsAny means that container may make requests for any gid.
......
...@@ -239,6 +239,7 @@ func validatePSPFSGroup(fldPath *field.Path, groupOptions *policy.FSGroupStrateg ...@@ -239,6 +239,7 @@ func validatePSPFSGroup(fldPath *field.Path, groupOptions *policy.FSGroupStrateg
supportedRules := sets.NewString( supportedRules := sets.NewString(
string(policy.FSGroupStrategyMustRunAs), string(policy.FSGroupStrategyMustRunAs),
string(policy.FSGroupStrategyMayRunAs),
string(policy.FSGroupStrategyRunAsAny), string(policy.FSGroupStrategyRunAsAny),
) )
if !supportedRules.Has(string(groupOptions.Rule)) { if !supportedRules.Has(string(groupOptions.Rule)) {
...@@ -257,6 +258,7 @@ func validatePSPSupplementalGroup(fldPath *field.Path, groupOptions *policy.Supp ...@@ -257,6 +258,7 @@ func validatePSPSupplementalGroup(fldPath *field.Path, groupOptions *policy.Supp
supportedRules := sets.NewString( supportedRules := sets.NewString(
string(policy.SupplementalGroupsStrategyRunAsAny), string(policy.SupplementalGroupsStrategyRunAsAny),
string(policy.SupplementalGroupsStrategyMayRunAs),
string(policy.SupplementalGroupsStrategyMustRunAs), string(policy.SupplementalGroupsStrategyMustRunAs),
) )
if !supportedRules.Has(string(groupOptions.Rule)) { if !supportedRules.Has(string(groupOptions.Rule)) {
......
...@@ -390,12 +390,12 @@ func TestValidatePodSecurityPolicy(t *testing.T) { ...@@ -390,12 +390,12 @@ func TestValidatePodSecurityPolicy(t *testing.T) {
"no fsgroup options": { "no fsgroup options": {
psp: noFSGroupOptions, psp: noFSGroupOptions,
errorType: field.ErrorTypeNotSupported, errorType: field.ErrorTypeNotSupported,
errorDetail: `supported values: "MustRunAs", "RunAsAny"`, errorDetail: `supported values: "MayRunAs", "MustRunAs", "RunAsAny"`,
}, },
"no sup group options": { "no sup group options": {
psp: noSupplementalGroupsOptions, psp: noSupplementalGroupsOptions,
errorType: field.ErrorTypeNotSupported, errorType: field.ErrorTypeNotSupported,
errorDetail: `supported values: "MustRunAs", "RunAsAny"`, errorDetail: `supported values: "MayRunAs", "MustRunAs", "RunAsAny"`,
}, },
"invalid user strategy type": { "invalid user strategy type": {
psp: invalidUserStratType, psp: invalidUserStratType,
...@@ -410,12 +410,12 @@ func TestValidatePodSecurityPolicy(t *testing.T) { ...@@ -410,12 +410,12 @@ func TestValidatePodSecurityPolicy(t *testing.T) {
"invalid sup group strategy type": { "invalid sup group strategy type": {
psp: invalidSupGroupStratType, psp: invalidSupGroupStratType,
errorType: field.ErrorTypeNotSupported, errorType: field.ErrorTypeNotSupported,
errorDetail: `supported values: "MustRunAs", "RunAsAny"`, errorDetail: `supported values: "MayRunAs", "MustRunAs", "RunAsAny"`,
}, },
"invalid fs group strategy type": { "invalid fs group strategy type": {
psp: invalidFSGroupStratType, psp: invalidFSGroupStratType,
errorType: field.ErrorTypeNotSupported, errorType: field.ErrorTypeNotSupported,
errorDetail: `supported values: "MustRunAs", "RunAsAny"`, errorDetail: `supported values: "MayRunAs", "MustRunAs", "RunAsAny"`,
}, },
"invalid uid": { "invalid uid": {
psp: invalidUIDPSP, psp: invalidUIDPSP,
......
...@@ -138,6 +138,8 @@ func createFSGroupStrategy(opts *policy.FSGroupStrategyOptions) (group.GroupStra ...@@ -138,6 +138,8 @@ func createFSGroupStrategy(opts *policy.FSGroupStrategyOptions) (group.GroupStra
switch opts.Rule { switch opts.Rule {
case policy.FSGroupStrategyRunAsAny: case policy.FSGroupStrategyRunAsAny:
return group.NewRunAsAny() return group.NewRunAsAny()
case policy.FSGroupStrategyMayRunAs:
return group.NewMayRunAs(opts.Ranges)
case policy.FSGroupStrategyMustRunAs: case policy.FSGroupStrategyMustRunAs:
return group.NewMustRunAs(opts.Ranges) return group.NewMustRunAs(opts.Ranges)
default: default:
...@@ -150,6 +152,8 @@ func createSupplementalGroupStrategy(opts *policy.SupplementalGroupsStrategyOpti ...@@ -150,6 +152,8 @@ func createSupplementalGroupStrategy(opts *policy.SupplementalGroupsStrategyOpti
switch opts.Rule { switch opts.Rule {
case policy.SupplementalGroupsStrategyRunAsAny: case policy.SupplementalGroupsStrategyRunAsAny:
return group.NewRunAsAny() return group.NewRunAsAny()
case policy.SupplementalGroupsStrategyMayRunAs:
return group.NewMayRunAs(opts.Ranges)
case policy.SupplementalGroupsStrategyMustRunAs: case policy.SupplementalGroupsStrategyMustRunAs:
return group.NewMustRunAs(opts.Ranges) return group.NewMustRunAs(opts.Ranges)
default: default:
......
...@@ -10,6 +10,8 @@ go_library( ...@@ -10,6 +10,8 @@ go_library(
name = "go_default_library", name = "go_default_library",
srcs = [ srcs = [
"doc.go", "doc.go",
"helpers.go",
"mayrunas.go",
"mustrunas.go", "mustrunas.go",
"runasany.go", "runasany.go",
"types.go", "types.go",
...@@ -26,6 +28,7 @@ go_library( ...@@ -26,6 +28,7 @@ go_library(
go_test( go_test(
name = "go_default_test", name = "go_default_test",
srcs = [ srcs = [
"mayrunas_test.go",
"mustrunas_test.go", "mustrunas_test.go",
"runasany_test.go", "runasany_test.go",
], ],
......
/*
Copyright 2018 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 group
import (
"fmt"
"k8s.io/apimachinery/pkg/util/validation/field"
"k8s.io/kubernetes/pkg/apis/policy"
psputil "k8s.io/kubernetes/pkg/security/podsecuritypolicy/util"
)
func ValidateGroupsInRanges(fldPath *field.Path, ranges []policy.IDRange, groups []int64) field.ErrorList {
allErrs := field.ErrorList{}
for _, group := range groups {
if !isGroupInRanges(group, ranges) {
detail := fmt.Sprintf("group %d must be in the ranges: %v", group, ranges)
allErrs = append(allErrs, field.Invalid(fldPath, groups, detail))
}
}
return allErrs
}
func isGroupInRanges(group int64, ranges []policy.IDRange) bool {
for _, rng := range ranges {
if psputil.GroupFallsInRange(group, rng) {
return true
}
}
return false
}
/*
Copyright 2018 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 group
import (
"fmt"
"k8s.io/apimachinery/pkg/util/validation/field"
api "k8s.io/kubernetes/pkg/apis/core"
"k8s.io/kubernetes/pkg/apis/policy"
)
// mayRunAs implements the GroupStrategy interface.
type mayRunAs struct {
ranges []policy.IDRange
}
var _ GroupStrategy = &mayRunAs{}
// NewMayRunAs provides a new MayRunAs strategy.
func NewMayRunAs(ranges []policy.IDRange) (GroupStrategy, error) {
if len(ranges) == 0 {
return nil, fmt.Errorf("ranges must be supplied for MayRunAs")
}
return &mayRunAs{
ranges: ranges,
}, nil
}
// Generate creates the group based on policy rules. This strategy returns an empty slice.
func (s *mayRunAs) Generate(_ *api.Pod) ([]int64, error) {
return nil, nil
}
// Generate a single value to be applied. This is used for FSGroup. This strategy returns nil.
func (s *mayRunAs) GenerateSingle(_ *api.Pod) (*int64, error) {
return nil, nil
}
// Validate ensures that the specified values fall within the range of the strategy.
// Groups are passed in here to allow this strategy to support multiple group fields (fsgroup and
// supplemental groups).
func (s *mayRunAs) Validate(fldPath *field.Path, _ *api.Pod, groups []int64) field.ErrorList {
return ValidateGroupsInRanges(fldPath, s.ranges, groups)
}
/*
Copyright 2018 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 group
import (
"fmt"
"strings"
"testing"
"k8s.io/apimachinery/pkg/util/validation/field"
"k8s.io/kubernetes/pkg/apis/policy"
)
func TestMayRunAsOptions(t *testing.T) {
tests := map[string]struct {
ranges []policy.IDRange
pass bool
}{
"empty": {
ranges: []policy.IDRange{},
},
"ranges": {
ranges: []policy.IDRange{
{Min: 1, Max: 1},
},
pass: true,
},
}
for k, v := range tests {
_, err := NewMayRunAs(v.ranges)
if v.pass && err != nil {
t.Errorf("error creating strategy for %s: %v", k, err)
}
if !v.pass && err == nil {
t.Errorf("expected error for %s but got none", k)
}
}
}
func TestMayRunAsValidate(t *testing.T) {
tests := map[string]struct {
ranges []policy.IDRange
groups []int64
expectedErrors []string
}{
"empty groups": {
ranges: []policy.IDRange{
{Min: 1, Max: 3},
},
},
"not in range": {
groups: []int64{5},
ranges: []policy.IDRange{
{Min: 1, Max: 3},
{Min: 4, Max: 4},
},
expectedErrors: []string{"group 5 must be in the ranges: [{1 3} {4 4}]"},
},
"not in ranges - multiple groups": {
groups: []int64{5, 10, 2020},
ranges: []policy.IDRange{
{Min: 1, Max: 3},
{Min: 15, Max: 70},
},
expectedErrors: []string{
"group 5 must be in the ranges: [{1 3} {15 70}]",
"group 10 must be in the ranges: [{1 3} {15 70}]",
"group 2020 must be in the ranges: [{1 3} {15 70}]",
},
},
"not in ranges - one of multiple groups does not match": {
groups: []int64{5, 10, 2020},
ranges: []policy.IDRange{
{Min: 1, Max: 5},
{Min: 8, Max: 12},
{Min: 15, Max: 70},
},
expectedErrors: []string{
"group 2020 must be in the ranges: [{1 5} {8 12} {15 70}]",
},
},
"in range 1": {
groups: []int64{2},
ranges: []policy.IDRange{
{Min: 1, Max: 3},
},
},
"in range boundary min": {
groups: []int64{1},
ranges: []policy.IDRange{
{Min: 1, Max: 3},
},
},
"in range boundary max": {
groups: []int64{3},
ranges: []policy.IDRange{
{Min: 1, Max: 3},
},
},
"singular range": {
groups: []int64{4},
ranges: []policy.IDRange{
{Min: 4, Max: 4},
},
},
"in one of multiple ranges": {
groups: []int64{4},
ranges: []policy.IDRange{
{Min: 1, Max: 4},
{Min: 10, Max: 15},
},
},
"multiple groups matches one range": {
groups: []int64{4, 8, 12},
ranges: []policy.IDRange{
{Min: 1, Max: 20},
},
},
"multiple groups match multiple ranges": {
groups: []int64{4, 8, 12},
ranges: []policy.IDRange{
{Min: 1, Max: 4},
{Min: 200, Max: 2000},
{Min: 7, Max: 11},
{Min: 5, Max: 7},
{Min: 17, Max: 53},
{Min: 12, Max: 71},
},
},
}
for k, v := range tests {
s, err := NewMayRunAs(v.ranges)
if err != nil {
t.Errorf("error creating strategy for %s: %v", k, err)
}
errs := s.Validate(field.NewPath(""), nil, v.groups)
if len(v.expectedErrors) != len(errs) {
// number of expected errors is different from actual, includes cases when we expected errors and they appeared or vice versa
t.Errorf("number of expected errors for '%s' does not match with errors received:\n"+
"expected:\n%s\nbut got:\n%s",
k, concatenateStrings(v.expectedErrors), concatenateErrors(errs))
} else if len(v.expectedErrors) > 0 {
// check that the errors received match the expectations
for i, s := range v.expectedErrors {
if !strings.Contains(errs[i].Error(), s) {
t.Errorf("expected errors in particular order for '%s':\n%s\nbut got:\n%s",
k, concatenateStrings(v.expectedErrors), concatenateErrors(errs))
break
}
}
}
}
}
func concatenateErrors(errs field.ErrorList) string {
var errStrings []string
for _, e := range errs {
errStrings = append(errStrings, e.Error())
}
return concatenateStrings(errStrings)
}
func concatenateStrings(ss []string) string {
var ret string
for i, v := range ss {
ret += fmt.Sprintf("%d: %s\n", i+1, v)
}
return ret
}
...@@ -22,7 +22,6 @@ import ( ...@@ -22,7 +22,6 @@ import (
"k8s.io/apimachinery/pkg/util/validation/field" "k8s.io/apimachinery/pkg/util/validation/field"
api "k8s.io/kubernetes/pkg/apis/core" api "k8s.io/kubernetes/pkg/apis/core"
"k8s.io/kubernetes/pkg/apis/policy" "k8s.io/kubernetes/pkg/apis/policy"
psputil "k8s.io/kubernetes/pkg/security/podsecuritypolicy/util"
) )
// mustRunAs implements the GroupStrategy interface // mustRunAs implements the GroupStrategy interface
...@@ -66,21 +65,7 @@ func (s *mustRunAs) Validate(fldPath *field.Path, _ *api.Pod, groups []int64) fi ...@@ -66,21 +65,7 @@ func (s *mustRunAs) Validate(fldPath *field.Path, _ *api.Pod, groups []int64) fi
allErrs = append(allErrs, field.Invalid(fldPath, groups, "unable to validate empty groups against required ranges")) allErrs = append(allErrs, field.Invalid(fldPath, groups, "unable to validate empty groups against required ranges"))
} }
for _, group := range groups { allErrs = append(allErrs, ValidateGroupsInRanges(fldPath, s.ranges, groups)...)
if !s.isGroupValid(group) {
detail := fmt.Sprintf("group %d must be in the ranges: %v", group, s.ranges)
allErrs = append(allErrs, field.Invalid(fldPath, groups, detail))
}
}
return allErrs return allErrs
} }
func (s *mustRunAs) isGroupValid(group int64) bool {
for _, rng := range s.ranges {
if psputil.GroupFallsInRange(group, rng) {
return true
}
}
return false
}
...@@ -186,24 +186,41 @@ func TestValidatePodSecurityContextFailures(t *testing.T) { ...@@ -186,24 +186,41 @@ func TestValidatePodSecurityContextFailures(t *testing.T) {
failSupplementalGroupPod := defaultPod() failSupplementalGroupPod := defaultPod()
failSupplementalGroupPod.Spec.SecurityContext.SupplementalGroups = []int64{999} failSupplementalGroupPod.Spec.SecurityContext.SupplementalGroups = []int64{999}
failSupplementalGroupPSP := defaultPSP() failSupplementalGroupMustPSP := defaultPSP()
failSupplementalGroupPSP.Spec.SupplementalGroups = policy.SupplementalGroupsStrategyOptions{ failSupplementalGroupMustPSP.Spec.SupplementalGroups = policy.SupplementalGroupsStrategyOptions{
Rule: policy.SupplementalGroupsStrategyMustRunAs, Rule: policy.SupplementalGroupsStrategyMustRunAs,
Ranges: []policy.IDRange{ Ranges: []policy.IDRange{
{Min: 1, Max: 1}, {Min: 1, Max: 1},
}, },
} }
failSupplementalGroupMayPSP := defaultPSP()
failSupplementalGroupMayPSP.Spec.SupplementalGroups = policy.SupplementalGroupsStrategyOptions{
Rule: policy.SupplementalGroupsStrategyMayRunAs,
Ranges: []policy.IDRange{
{Min: 50, Max: 50},
{Min: 55, Max: 998},
{Min: 1000, Max: 1000},
},
}
failFSGroupPod := defaultPod() failFSGroupPod := defaultPod()
fsGroup := int64(999) fsGroup := int64(999)
failFSGroupPod.Spec.SecurityContext.FSGroup = &fsGroup failFSGroupPod.Spec.SecurityContext.FSGroup = &fsGroup
failFSGroupPSP := defaultPSP() failFSGroupMustPSP := defaultPSP()
failFSGroupPSP.Spec.FSGroup = policy.FSGroupStrategyOptions{ failFSGroupMustPSP.Spec.FSGroup = policy.FSGroupStrategyOptions{
Rule: policy.FSGroupStrategyMustRunAs, Rule: policy.FSGroupStrategyMustRunAs,
Ranges: []policy.IDRange{ Ranges: []policy.IDRange{
{Min: 1, Max: 1}, {Min: 1, Max: 1},
}, },
} }
failFSGroupMayPSP := defaultPSP()
failFSGroupMayPSP.Spec.FSGroup = policy.FSGroupStrategyOptions{
Rule: policy.FSGroupStrategyMayRunAs,
Ranges: []policy.IDRange{
{Min: 10, Max: 20},
{Min: 1000, Max: 1001},
},
}
failNilSELinuxPod := defaultPod() failNilSELinuxPod := defaultPod()
failSELinuxPSP := defaultPSP() failSELinuxPSP := defaultPSP()
...@@ -334,24 +351,34 @@ func TestValidatePodSecurityContextFailures(t *testing.T) { ...@@ -334,24 +351,34 @@ func TestValidatePodSecurityContextFailures(t *testing.T) {
psp: defaultPSP(), psp: defaultPSP(),
expectedError: "Host IPC is not allowed to be used", expectedError: "Host IPC is not allowed to be used",
}, },
"failSupplementalGroupOutOfRange": { "failSupplementalGroupOutOfMustRange": {
pod: failSupplementalGroupPod, pod: failSupplementalGroupPod,
psp: failSupplementalGroupPSP, psp: failSupplementalGroupMustPSP,
expectedError: "group 999 must be in the ranges: [{1 1}]", expectedError: "group 999 must be in the ranges: [{1 1}]",
}, },
"failSupplementalGroupEmpty": { "failSupplementalGroupOutOfMayRange": {
pod: failSupplementalGroupPod,
psp: failSupplementalGroupMayPSP,
expectedError: "group 999 must be in the ranges: [{50 50} {55 998} {1000 1000}]",
},
"failSupplementalGroupMustEmpty": {
pod: defaultPod(), pod: defaultPod(),
psp: failSupplementalGroupPSP, psp: failSupplementalGroupMustPSP,
expectedError: "unable to validate empty groups against required ranges", expectedError: "unable to validate empty groups against required ranges",
}, },
"failFSGroupOutOfRange": { "failFSGroupOutOfMustRange": {
pod: failFSGroupPod, pod: failFSGroupPod,
psp: failFSGroupPSP, psp: failFSGroupMustPSP,
expectedError: "group 999 must be in the ranges: [{1 1}]", expectedError: "group 999 must be in the ranges: [{1 1}]",
}, },
"failFSGroupEmpty": { "failFSGroupOutOfMayRange": {
pod: failFSGroupPod,
psp: failFSGroupMayPSP,
expectedError: "group 999 must be in the ranges: [{10 20} {1000 1001}]",
},
"failFSGroupMustEmpty": {
pod: defaultPod(), pod: defaultPod(),
psp: failFSGroupPSP, psp: failFSGroupMustPSP,
expectedError: "unable to validate empty groups against required ranges", expectedError: "unable to validate empty groups against required ranges",
}, },
"failNilSELinux": { "failNilSELinux": {
...@@ -616,23 +643,37 @@ func TestValidatePodSecurityContextSuccess(t *testing.T) { ...@@ -616,23 +643,37 @@ func TestValidatePodSecurityContextSuccess(t *testing.T) {
hostIPCPod := defaultPod() hostIPCPod := defaultPod()
hostIPCPod.Spec.SecurityContext.HostIPC = true hostIPCPod.Spec.SecurityContext.HostIPC = true
supGroupPSP := defaultPSP() supGroupMustPSP := defaultPSP()
supGroupPSP.Spec.SupplementalGroups = policy.SupplementalGroupsStrategyOptions{ supGroupMustPSP.Spec.SupplementalGroups = policy.SupplementalGroupsStrategyOptions{
Rule: policy.SupplementalGroupsStrategyMustRunAs, Rule: policy.SupplementalGroupsStrategyMustRunAs,
Ranges: []policy.IDRange{ Ranges: []policy.IDRange{
{Min: 1, Max: 5}, {Min: 1, Max: 5},
}, },
} }
supGroupMayPSP := defaultPSP()
supGroupMayPSP.Spec.SupplementalGroups = policy.SupplementalGroupsStrategyOptions{
Rule: policy.SupplementalGroupsStrategyMayRunAs,
Ranges: []policy.IDRange{
{Min: 1, Max: 5},
},
}
supGroupPod := defaultPod() supGroupPod := defaultPod()
supGroupPod.Spec.SecurityContext.SupplementalGroups = []int64{3} supGroupPod.Spec.SecurityContext.SupplementalGroups = []int64{3}
fsGroupPSP := defaultPSP() fsGroupMustPSP := defaultPSP()
fsGroupPSP.Spec.FSGroup = policy.FSGroupStrategyOptions{ fsGroupMustPSP.Spec.FSGroup = policy.FSGroupStrategyOptions{
Rule: policy.FSGroupStrategyMustRunAs, Rule: policy.FSGroupStrategyMustRunAs,
Ranges: []policy.IDRange{ Ranges: []policy.IDRange{
{Min: 1, Max: 5}, {Min: 1, Max: 5},
}, },
} }
fsGroupMayPSP := defaultPSP()
fsGroupMayPSP.Spec.FSGroup = policy.FSGroupStrategyOptions{
Rule: policy.FSGroupStrategyMayRunAs,
Ranges: []policy.IDRange{
{Min: 1, Max: 5},
},
}
fsGroupPod := defaultPod() fsGroupPod := defaultPod()
fsGroup := int64(3) fsGroup := int64(3)
fsGroupPod.Spec.SecurityContext.FSGroup = &fsGroup fsGroupPod.Spec.SecurityContext.FSGroup = &fsGroup
...@@ -793,13 +834,29 @@ func TestValidatePodSecurityContextSuccess(t *testing.T) { ...@@ -793,13 +834,29 @@ func TestValidatePodSecurityContextSuccess(t *testing.T) {
pod: hostIPCPod, pod: hostIPCPod,
psp: hostIPCPSP, psp: hostIPCPSP,
}, },
"pass supplemental group validating PSP": { "pass required supplemental group validating PSP": {
pod: supGroupPod,
psp: supGroupMustPSP,
},
"pass optional supplemental group validation PSP": {
pod: supGroupPod, pod: supGroupPod,
psp: supGroupPSP, psp: supGroupMayPSP,
}, },
"pass fs group validating PSP": { "pass optional supplemental group validation PSP - no pod group specified": {
pod: defaultPod(),
psp: supGroupMayPSP,
},
"pass required fs group validating PSP": {
pod: fsGroupPod,
psp: fsGroupMustPSP,
},
"pass optional fs group validating PSP": {
pod: fsGroupPod, pod: fsGroupPod,
psp: fsGroupPSP, psp: fsGroupMayPSP,
},
"pass optional fs group validating PSP - no pod group specified": {
pod: defaultPod(),
psp: fsGroupMayPSP,
}, },
"pass selinux validating PSP": { "pass selinux validating PSP": {
pod: seLinuxPod, pod: seLinuxPod,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment