PodSecurity: add ability to skip failure cases if relevant features are disabled

This commit is contained in:
Jordan Liggitt
2021-06-30 11:24:31 -04:00
parent c206af0367
commit e87016cf94
4 changed files with 34 additions and 0 deletions

View File

@@ -271,4 +271,5 @@
- k8s.io/client-go
- k8s.io/klog
- k8s.io/pod-security-admission
- k8s.io/component-base/featuregate
- k8s.io/utils

View File

@@ -11,6 +11,7 @@ require (
k8s.io/apimachinery v0.0.0
k8s.io/apiserver v0.0.0
k8s.io/client-go v0.0.0
k8s.io/component-base v0.0.0
k8s.io/klog/v2 v2.9.0
k8s.io/utils v0.0.0-20210521133846-da695404a2bc
sigs.k8s.io/yaml v1.2.0

View File

@@ -20,6 +20,7 @@ import (
"fmt"
corev1 "k8s.io/api/core/v1"
"k8s.io/component-base/featuregate"
"k8s.io/pod-security-admission/api"
"k8s.io/pod-security-admission/policy"
"k8s.io/utils/pointer"
@@ -90,6 +91,13 @@ type fixtureGenerator struct {
// expectErrorSubstring is a substring to expect in the error message for failed pods.
// if empty, the check ID is used.
expectErrorSubstring string
// failRequiresFeatures lists feature gates that must all be enabled for failure cases to fail properly.
// This allows failure cases depending on rejecting data populated in alpha or beta fields to be skipped when those features are not enabled.
// If empty, failure test cases are always run.
// Pass cases are not allowed to be feature-gated (pass cases must only depend on data existing in GA fields).
failRequiresFeatures []featuregate.Feature
// generatePass transforms a minimum valid pod into one or more valid pods.
// pods do not need to populate metadata.name.
generatePass func(*corev1.Pod) []*corev1.Pod
@@ -102,6 +110,12 @@ type fixtureGenerator struct {
type fixtureData struct {
expectErrorSubstring string
// failRequiresFeatures lists feature gates that must all be enabled for failure cases to fail properly.
// This allows failure cases depending on rejecting data populated in alpha or beta fields to be skipped when those features are not enabled.
// If empty, failure test cases are always run.
// Pass cases are not allowed to be feature-gated (pass cases must only depend on data existing in GA fields).
failRequiresFeatures []featuregate.Feature
pass []*corev1.Pod
fail []*corev1.Pod
}
@@ -148,6 +162,7 @@ func getFixtures(key fixtureKey) (fixtureData, error) {
if generator, exists := fixtureGenerators[key]; exists {
data := fixtureData{
expectErrorSubstring: generator.expectErrorSubstring,
failRequiresFeatures: generator.failRequiresFeatures,
pass: generator.generatePass(validPodForLevel.DeepCopy()),
fail: generator.generateFail(validPodForLevel.DeepCopy()),

View File

@@ -30,6 +30,7 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/rest"
"k8s.io/component-base/featuregate"
"k8s.io/pod-security-admission/api"
"k8s.io/pod-security-admission/policy"
)
@@ -41,6 +42,11 @@ type Options struct {
// Required.
ClientConfig *rest.Config
// Features optionally provides information about which feature gates are enabled.
// This is used to skip failure cases for negative tests of data in alpha/beta fields.
// If unset, all testcases are run.
Features featuregate.FeatureGate
// CreateNamespace is an optional stub for creating a namespace with the given name and labels.
// Returning an error fails the test.
// If nil, DefaultCreateNamespace is used.
@@ -278,7 +284,18 @@ func Run(t *testing.T, opts Options) {
createController(t, i, pod, true, "")
}
})
// see if any features required for failure cases are disabled
var disabledRequiredFeatures []featuregate.Feature
for _, f := range checkData.failRequiresFeatures {
if opts.Features != nil && !opts.Features.Enabled(f) {
disabledRequiredFeatures = append(disabledRequiredFeatures, f)
}
}
t.Run(ns+"_fail_"+checkID, func(t *testing.T) {
if len(disabledRequiredFeatures) > 0 {
t.Skipf("features required for failure cases are disabled: %v", disabledRequiredFeatures)
}
for i, pod := range checkData.fail {
createPod(t, i, pod, false, checkData.expectErrorSubstring)
createController(t, i, pod, false, checkData.expectErrorSubstring)