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
Kubernetes Submit Queue 2018-08-31 19:25:39 -07:00 committed by GitHub
commit 924121cc35
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 59 additions and 100 deletions

View File

@ -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",
],
)

View File

@ -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")
}
})
}
}