From ba6b4c5a18c455867f11036a7208962e84012a86 Mon Sep 17 00:00:00 2001 From: Jordan Liggitt Date: Wed, 30 Jun 2021 11:25:13 -0400 Subject: [PATCH] PodSecurity: test GA-only cases and alpha/beta fields separately --- .../featuregate/feature_gate.go | 11 ++++ test/integration/auth/podsecurity_test.go | 54 +++++++++++++++---- 2 files changed, 54 insertions(+), 11 deletions(-) diff --git a/staging/src/k8s.io/component-base/featuregate/feature_gate.go b/staging/src/k8s.io/component-base/featuregate/feature_gate.go index c805ffb01b5..c7166d80b84 100644 --- a/staging/src/k8s.io/component-base/featuregate/feature_gate.go +++ b/staging/src/k8s.io/component-base/featuregate/feature_gate.go @@ -109,6 +109,8 @@ type MutableFeatureGate interface { SetFromMap(m map[string]bool) error // Add adds features to the featureGate. Add(features map[Feature]FeatureSpec) error + // GetAll returns a copy of the map of known feature names to feature specs. + GetAll() map[Feature]FeatureSpec } // featureGate implements FeatureGate as well as pflag.Value for flag parsing. @@ -290,6 +292,15 @@ func (f *featureGate) Add(features map[Feature]FeatureSpec) error { return nil } +// GetAll returns a copy of the map of known feature names to feature specs. +func (f *featureGate) GetAll() map[Feature]FeatureSpec { + retval := map[Feature]FeatureSpec{} + for k, v := range f.known.Load().(map[Feature]FeatureSpec) { + retval[k] = v + } + return retval +} + // Enabled returns true if the key is enabled. If the key is not known, this call will panic. func (f *featureGate) Enabled(key Feature) bool { if v, ok := f.enabled.Load().(map[Feature]bool)[key]; ok { diff --git a/test/integration/auth/podsecurity_test.go b/test/integration/auth/podsecurity_test.go index bea7e700067..baea7c03a63 100644 --- a/test/integration/auth/podsecurity_test.go +++ b/test/integration/auth/podsecurity_test.go @@ -20,6 +20,7 @@ import ( "testing" utilfeature "k8s.io/apiserver/pkg/util/feature" + "k8s.io/component-base/featuregate" featuregatetesting "k8s.io/component-base/featuregate/testing" kubeapiservertesting "k8s.io/kubernetes/cmd/kube-apiserver/app/testing" "k8s.io/kubernetes/pkg/capabilities" @@ -29,21 +30,17 @@ import ( ) func TestPodSecurity(t *testing.T) { + // Enable all feature gates needed to allow all fields to be exercised + defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ProcMountType, true)() + // Ensure the PodSecurity feature is enabled defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.PodSecurity, true)() - server := kubeapiservertesting.StartTestServerOrDie(t, kubeapiservertesting.NewDefaultTestServerOptions(), []string{ - "--anonymous-auth=false", - "--enable-admission-plugins=PodSecurity", - "--allow-privileged=true", - // TODO: "--admission-control-config-file=" + admissionConfigFile.Name(), - }, framework.SharedEtcd()) - defer server.TearDownFn() - - // ensure the global is set to allow privileged containers - capabilities.SetForTests(capabilities.Capabilities{AllowPrivileged: true}) - + // Start server + server := startPodSecurityServer(t) opts := podsecuritytest.Options{ ClientConfig: server.ClientConfig, + // Don't pass in feature-gate info, so all testcases run + // TODO ExemptClient: nil, ExemptNamespaces: []string{}, @@ -51,3 +48,38 @@ func TestPodSecurity(t *testing.T) { } podsecuritytest.Run(t, opts) } + +// TestPodSecurityGAOnly ensures policies pass with only GA features enabled +func TestPodSecurityGAOnly(t *testing.T) { + // Disable all alpha and beta features + for k, v := range utilfeature.DefaultFeatureGate.DeepCopy().GetAll() { + if v.PreRelease == featuregate.Alpha || v.PreRelease == featuregate.Beta { + defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, k, false)() + } + } + // Ensure PodSecurity feature is enabled + defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.PodSecurity, true)() + // Start server + server := startPodSecurityServer(t) + + opts := podsecuritytest.Options{ + ClientConfig: server.ClientConfig, + // Pass in feature gate info so negative test cases depending on alpha or beta features can be skipped + Features: utilfeature.DefaultFeatureGate, + } + podsecuritytest.Run(t, opts) +} + +func startPodSecurityServer(t *testing.T) *kubeapiservertesting.TestServer { + // ensure the global is set to allow privileged containers + capabilities.SetForTests(capabilities.Capabilities{AllowPrivileged: true}) + + server := kubeapiservertesting.StartTestServerOrDie(t, kubeapiservertesting.NewDefaultTestServerOptions(), []string{ + "--anonymous-auth=false", + "--enable-admission-plugins=PodSecurity", + "--allow-privileged=true", + // TODO: "--admission-control-config-file=" + admissionConfigFile.Name(), + }, framework.SharedEtcd()) + t.Cleanup(server.TearDownFn) + return server +}