mirror of https://github.com/k3s-io/k3s
Merge pull request #68105 from tallclair/psp-test
Automatic merge from submit-queue (batch tested with PRs 65251, 67255, 67224, 67297, 68105). If you want to cherry-pick this change to another branch, please follow the instructions here: https://github.com/kubernetes/community/blob/master/contributors/devel/cherry-picks.md. Cleanup PodSecurityPolicy AllowPrivEsc tests **What this PR does / why we need it**: Old tests were confusing and missing a lot of combinations. The new test is a simple table-driven test with all valid combinations. **Which issue(s) this PR fixes** *(optional, in `fixes #<issue number>(, fixes #<issue_number>, ...)` format, will close the issue(s) when PR gets merged)*: Fixes ##67387 **Special notes for your reviewer**: Alternative to https://github.com/kubernetes/kubernetes/pull/67388 **Release note**: ```release-note NONE ```pull/8/head
commit
924121cc35
|
@ -48,6 +48,8 @@ go_test(
|
|||
"//staging/src/k8s.io/apimachinery/pkg/util/diff:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/util/validation/field:go_default_library",
|
||||
"//vendor/github.com/davecgh/go-spew/spew:go_default_library",
|
||||
"//vendor/github.com/stretchr/testify/assert:go_default_library",
|
||||
"//vendor/github.com/stretchr/testify/require:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
|
|
|
@ -19,10 +19,13 @@ package podsecuritypolicy
|
|||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/davecgh/go-spew/spew"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
@ -1232,110 +1235,64 @@ func TestValidateAllowedVolumes(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
// TestValidateAllowPrivilegeEscalation will test that when the podSecurityPolicy
|
||||
// AllowPrivilegeEscalation is false we cannot set a container's securityContext
|
||||
// to allowPrivilegeEscalation, but when it is true we can.
|
||||
func TestValidateAllowPrivilegeEscalation(t *testing.T) {
|
||||
pod := defaultPod()
|
||||
pe := true
|
||||
pod.Spec.Containers[0].SecurityContext.AllowPrivilegeEscalation = &pe
|
||||
|
||||
// create a PSP that does not allow privilege escalation
|
||||
psp := defaultPSP()
|
||||
psp.Spec.AllowPrivilegeEscalation = false
|
||||
|
||||
provider, err := NewSimpleProvider(psp, "namespace", NewSimpleStrategyFactory())
|
||||
if err != nil {
|
||||
t.Errorf("error creating provider: %v", err.Error())
|
||||
func TestAllowPrivilegeEscalation(t *testing.T) {
|
||||
ptr := func(b bool) *bool { return &b }
|
||||
tests := []struct {
|
||||
pspAPE bool // PSP AllowPrivilegeEscalation
|
||||
pspDAPE *bool // PSP DefaultAllowPrivilegeEscalation
|
||||
podAPE *bool // Pod AllowPrivilegeEscalation
|
||||
expectErr bool
|
||||
expectAPE *bool // Expected value of pod APE (if no error)
|
||||
}{
|
||||
// Test all valid combinations of PSP AllowPrivilegeEscalation,
|
||||
// DefaultAllowPrivilegeEscalation, and Pod AllowPrivilegeEscalation.
|
||||
{true, nil, nil, false, nil},
|
||||
{true, nil, ptr(false), false, ptr(false)},
|
||||
{true, nil, ptr(true), false, ptr(true)},
|
||||
{true, ptr(false), nil, false, ptr(false)},
|
||||
{true, ptr(false), ptr(false), false, ptr(false)},
|
||||
{true, ptr(false), ptr(true), false, ptr(true)},
|
||||
{true, ptr(true), nil, false, ptr(true)},
|
||||
{true, ptr(true), ptr(false), false, ptr(false)},
|
||||
{true, ptr(true), ptr(true), false, ptr(true)},
|
||||
{false, nil, nil, false, ptr(false)},
|
||||
{false, nil, ptr(false), false, ptr(false)},
|
||||
{false, nil, ptr(true), true, nil},
|
||||
{false, ptr(false), nil, false, ptr(false)},
|
||||
{false, ptr(false), ptr(false), false, ptr(false)},
|
||||
{false, ptr(false), ptr(true), true, nil},
|
||||
// Invalid cases: pspAPE=false, pspDAPE=true
|
||||
}
|
||||
|
||||
// expect a denial for this PSP and test the error message to ensure it's related to allowPrivilegeEscalation
|
||||
errs := provider.ValidateContainer(pod, &pod.Spec.Containers[0], field.NewPath(""))
|
||||
if len(errs) != 1 {
|
||||
t.Errorf("expected exactly 1 error but got %v", errs)
|
||||
} else {
|
||||
if !strings.Contains(errs.ToAggregate().Error(), "Allowing privilege escalation for containers is not allowed") {
|
||||
t.Errorf("did not find the expected error, received: %v", errs)
|
||||
fmtPtr := func(b *bool) string {
|
||||
if b == nil {
|
||||
return "nil"
|
||||
}
|
||||
return strconv.FormatBool(*b)
|
||||
}
|
||||
for _, test := range tests {
|
||||
t.Run(fmt.Sprintf("pspAPE:%t_pspDAPE:%s_podAPE:%s", test.pspAPE, fmtPtr(test.pspDAPE), fmtPtr(test.podAPE)), func(t *testing.T) {
|
||||
pod := defaultPod()
|
||||
pod.Spec.Containers[0].SecurityContext.AllowPrivilegeEscalation = test.podAPE
|
||||
|
||||
// now add allowPrivilegeEscalation to the podSecurityPolicy
|
||||
psp.Spec.AllowPrivilegeEscalation = true
|
||||
errs = provider.ValidateContainer(pod, &pod.Spec.Containers[0], field.NewPath(""))
|
||||
if len(errs) != 0 {
|
||||
t.Errorf("directly allowing privilege escalation expected no errors but got %v", errs)
|
||||
}
|
||||
}
|
||||
|
||||
// TestValidateDefaultAllowPrivilegeEscalation will test that when the podSecurityPolicy
|
||||
// DefaultAllowPrivilegeEscalation is false we cannot set a container's
|
||||
// securityContext to allowPrivilegeEscalation but when it is true we can.
|
||||
func TestValidateDefaultAllowPrivilegeEscalation(t *testing.T) {
|
||||
pod := defaultPod()
|
||||
pe := true
|
||||
pod.Spec.Containers[0].SecurityContext.AllowPrivilegeEscalation = &pe
|
||||
|
||||
// create a PSP that does not allow privilege escalation
|
||||
psp := defaultPSP()
|
||||
dpe := false
|
||||
psp.Spec.DefaultAllowPrivilegeEscalation = &dpe
|
||||
psp.Spec.AllowPrivilegeEscalation = false
|
||||
|
||||
provider, err := NewSimpleProvider(psp, "namespace", NewSimpleStrategyFactory())
|
||||
if err != nil {
|
||||
t.Errorf("error creating provider: %v", err.Error())
|
||||
}
|
||||
|
||||
// expect a denial for this PSP and test the error message to ensure it's related to allowPrivilegeEscalation
|
||||
errs := provider.ValidateContainer(pod, &pod.Spec.Containers[0], field.NewPath(""))
|
||||
if len(errs) != 1 {
|
||||
t.Errorf("expected exactly 1 error but got %v", errs)
|
||||
} else {
|
||||
if !strings.Contains(errs.ToAggregate().Error(), "Allowing privilege escalation for containers is not allowed") {
|
||||
t.Errorf("did not find the expected error, received: %v", errs)
|
||||
}
|
||||
}
|
||||
|
||||
// now add DefaultAllowPrivilegeEscalation to the podSecurityPolicy
|
||||
dpe = true
|
||||
psp.Spec.DefaultAllowPrivilegeEscalation = &dpe
|
||||
psp.Spec.AllowPrivilegeEscalation = false
|
||||
|
||||
// expect a denial for this PSP because we did not allowPrivilege Escalation via the PodSecurityPolicy
|
||||
// and test the error message to ensure it's related to allowPrivilegeEscalation
|
||||
errs = provider.ValidateContainer(pod, &pod.Spec.Containers[0], field.NewPath(""))
|
||||
if len(errs) != 1 {
|
||||
t.Errorf("expected exactly 1 error but got %v", errs)
|
||||
} else {
|
||||
if !strings.Contains(errs.ToAggregate().Error(), "Allowing privilege escalation for containers is not allowed") {
|
||||
t.Errorf("did not find the expected error, received: %v", errs)
|
||||
}
|
||||
}
|
||||
|
||||
// Now set AllowPrivilegeEscalation
|
||||
psp.Spec.AllowPrivilegeEscalation = true
|
||||
errs = provider.ValidateContainer(pod, &pod.Spec.Containers[0], field.NewPath(""))
|
||||
if len(errs) != 0 {
|
||||
t.Errorf("directly allowing privilege escalation expected no errors but got %v", errs)
|
||||
}
|
||||
|
||||
// Now set the psp spec to false and reset AllowPrivilegeEscalation
|
||||
psp.Spec.AllowPrivilegeEscalation = false
|
||||
pod.Spec.Containers[0].SecurityContext.AllowPrivilegeEscalation = nil
|
||||
errs = provider.ValidateContainer(pod, &pod.Spec.Containers[0], field.NewPath(""))
|
||||
if len(errs) != 1 {
|
||||
t.Errorf("expected exactly 1 error but got %v", errs)
|
||||
} else {
|
||||
if !strings.Contains(errs.ToAggregate().Error(), "Allowing privilege escalation for containers is not allowed") {
|
||||
t.Errorf("did not find the expected error, received: %v", errs)
|
||||
}
|
||||
}
|
||||
|
||||
// Now unset both AllowPrivilegeEscalation
|
||||
psp.Spec.AllowPrivilegeEscalation = true
|
||||
pod.Spec.Containers[0].SecurityContext.AllowPrivilegeEscalation = nil
|
||||
errs = provider.ValidateContainer(pod, &pod.Spec.Containers[0], field.NewPath(""))
|
||||
if len(errs) != 0 {
|
||||
t.Errorf("resetting allowing privilege escalation expected no errors but got %v", errs)
|
||||
psp := defaultPSP()
|
||||
psp.Spec.AllowPrivilegeEscalation = test.pspAPE
|
||||
psp.Spec.DefaultAllowPrivilegeEscalation = test.pspDAPE
|
||||
|
||||
provider, err := NewSimpleProvider(psp, "namespace", NewSimpleStrategyFactory())
|
||||
require.NoError(t, err)
|
||||
|
||||
err = provider.DefaultContainerSecurityContext(pod, &pod.Spec.Containers[0])
|
||||
require.NoError(t, err)
|
||||
|
||||
errs := provider.ValidateContainer(pod, &pod.Spec.Containers[0], field.NewPath(""))
|
||||
if test.expectErr {
|
||||
assert.NotEmpty(t, errs, "expected validation error")
|
||||
} else {
|
||||
assert.Empty(t, errs, "expected no validation errors")
|
||||
ape := pod.Spec.Containers[0].SecurityContext.AllowPrivilegeEscalation
|
||||
assert.Equal(t, test.expectAPE, ape, "expected pod AllowPrivilegeEscalation")
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue