Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,13 @@ import (
"fmt"
"io"

openshiftfeatures "github.com/openshift/api/features"
corev1 "k8s.io/api/core/v1"
"k8s.io/apiserver/pkg/admission"
"k8s.io/apiserver/pkg/admission/initializer"
"k8s.io/apiserver/pkg/audit"
"k8s.io/apiserver/pkg/warning"
"k8s.io/client-go/informers"
corev1listers "k8s.io/client-go/listers/core/v1"
"k8s.io/component-base/featuregate"
"k8s.io/klog/v2"
kapi "k8s.io/kubernetes/pkg/apis/core"
)
Expand All @@ -29,7 +27,6 @@ const (
var (
_ = initializer.WantsExternalKubeInformerFactory(&performantSecurityPolicy{})
_ = admission.MutationInterface(&performantSecurityPolicy{})
_ = initializer.WantsFeatures(&performantSecurityPolicy{})

fsGroupPolicyPodAuditLabel = fmt.Sprintf("%s-pod", fsGroupChangePolicyLabel)
selinuxPolicyPodAuditLabel = fmt.Sprintf("%s-pod", selinuxChangePolicyLabel)
Expand All @@ -48,8 +45,7 @@ func Register(plugins *admission.Plugins) {
// should be applied to the pod.
type performantSecurityPolicy struct {
*admission.Handler
storagePerformantSecurityPolicyFeatureEnabled bool
nsLister corev1listers.NamespaceLister
nsLister corev1listers.NamespaceLister
}

// SetExternalKubeInformerFactory registers an informer
Expand All @@ -60,10 +56,6 @@ func (c *performantSecurityPolicy) SetExternalKubeInformerFactory(kubeInformers
})
}

func (c *performantSecurityPolicy) InspectFeatureGates(featureGates featuregate.FeatureGate) {
c.storagePerformantSecurityPolicyFeatureEnabled = featureGates.Enabled(featuregate.Feature(openshiftfeatures.FeatureGateStoragePerformantSecurityPolicy))
}

func (c *performantSecurityPolicy) ValidateInitialization() error {
if c.nsLister == nil {
return fmt.Errorf("%s plugin needs a namespace lister", PluginName)
Expand All @@ -72,10 +64,6 @@ func (c *performantSecurityPolicy) ValidateInitialization() error {
}

func (c *performantSecurityPolicy) Admit(ctx context.Context, attributes admission.Attributes, _ admission.ObjectInterfaces) error {
if !c.storagePerformantSecurityPolicyFeatureEnabled {
return nil
}

if !c.WaitForReady() {
return admission.NewForbidden(attributes, fmt.Errorf("not yet ready to handle request"))
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,28 +4,23 @@ import (
"context"
"testing"

openshiftfeatures "github.com/openshift/api/features"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apiserver/pkg/admission"
utilfeature "k8s.io/apiserver/pkg/util/feature"
corev1listers "k8s.io/client-go/listers/core/v1"
"k8s.io/client-go/tools/cache"
"k8s.io/component-base/featuregate"
featuregatetesting "k8s.io/component-base/featuregate/testing"
kapi "k8s.io/kubernetes/pkg/apis/core"
_ "k8s.io/kubernetes/pkg/features"
)

func TestAdmit(t *testing.T) {
type testCase struct {
name string
pod *kapi.Pod
ns *corev1.Namespace
expectedPod *kapi.Pod
expectError bool
featureGateEnabled bool
name string
pod *kapi.Pod
ns *corev1.Namespace
expectedPod *kapi.Pod
expectError bool
}

onRootMismatchPolicy := kapi.FSGroupChangeOnRootMismatch
Expand All @@ -35,103 +30,84 @@ func TestAdmit(t *testing.T) {

testCases := []testCase{
{
name: "when feature gate is disabled, no changes are made",
featureGateEnabled: false,
pod: getPod(nil, nil),
expectedPod: getPod(nil, nil),

ns: getNamespace(map[string]string{
fsGroupChangePolicyLabel: "OnRootMismatch",
}),
},
{
name: "when feature gate is enabled, FSGroupChangePolicy is set to OnRootMismatch",
featureGateEnabled: true,
pod: getPod(nil, nil),
expectedPod: getPod(&onRootMismatchPolicy, nil),
expectError: false,
name: "when feature gate is enabled, FSGroupChangePolicy is set to OnRootMismatch",
pod: getPod(nil, nil),
expectedPod: getPod(&onRootMismatchPolicy, nil),
expectError: false,
ns: getNamespace(map[string]string{
fsGroupChangePolicyLabel: "OnRootMismatch",
}),
},
{
name: "when feature is enabled, but namespace label for fsgroupchangepolicy has invalid value, no changes are made",
pod: getPod(nil, nil),
featureGateEnabled: true,
expectedPod: getPod(nil, nil),
expectError: false,
name: "when feature is enabled, but namespace label for fsgroupchangepolicy has invalid value, no changes are made",
pod: getPod(nil, nil),
expectedPod: getPod(nil, nil),
expectError: false,
ns: getNamespace(map[string]string{
fsGroupChangePolicyLabel: "InvalidValue",
}),
},
{
name: "when feature is enabled, but pod already specifies different fsgroupchangepolicy",
pod: getPod(&alwaysFSGroupChangePolicy, nil),
featureGateEnabled: true,
expectedPod: getPod(&alwaysFSGroupChangePolicy, nil),
expectError: false,
name: "when feature is enabled, but pod already specifies different fsgroupchangepolicy",
pod: getPod(&alwaysFSGroupChangePolicy, nil),
expectedPod: getPod(&alwaysFSGroupChangePolicy, nil),
expectError: false,
ns: getNamespace(map[string]string{
fsGroupChangePolicyLabel: "OnRootMismatch",
}),
},
{
name: "when feature is enabled and selinuxchangepolicy is set to Recursive",
featureGateEnabled: true,
pod: getPod(nil, nil),
expectedPod: getPod(nil, &selinuxRecursive),
expectError: false,
name: "when feature is enabled and selinuxchangepolicy is set to Recursive",
pod: getPod(nil, nil),
expectedPod: getPod(nil, &selinuxRecursive),
expectError: false,
ns: getNamespace(map[string]string{
selinuxChangePolicyLabel: "Recursive",
}),
},
{
name: "when feature is enabled and selinuxchangepolicy is set to MountOption",
featureGateEnabled: true,
pod: getPod(nil, nil),
expectedPod: getPod(nil, &selinuxMountOption),
expectError: false,
name: "when feature is enabled and selinuxchangepolicy is set to MountOption",
pod: getPod(nil, nil),
expectedPod: getPod(nil, &selinuxMountOption),
expectError: false,
ns: getNamespace(map[string]string{
selinuxChangePolicyLabel: "MountOption",
}),
},
{
name: "when feature is enabled, but pod already specifies different selinuxchangepolicy",
pod: getPod(nil, &selinuxRecursive),
featureGateEnabled: true,
expectedPod: getPod(nil, &selinuxRecursive),
expectError: false,
name: "when feature is enabled, but pod already specifies different selinuxchangepolicy",
pod: getPod(nil, &selinuxRecursive),
expectedPod: getPod(nil, &selinuxRecursive),
expectError: false,
ns: getNamespace(map[string]string{
selinuxChangePolicyLabel: "MountOption",
}),
},
{
name: "when feature is enabled and both fsgroupchangepolicy and selinuxchangepolicy are set",
featureGateEnabled: true,
pod: getPod(nil, nil),
expectedPod: getPod(&onRootMismatchPolicy, &selinuxMountOption),
expectError: false,
name: "when feature is enabled and both fsgroupchangepolicy and selinuxchangepolicy are set",
pod: getPod(nil, nil),
expectedPod: getPod(&onRootMismatchPolicy, &selinuxMountOption),
expectError: false,
ns: getNamespace(map[string]string{
fsGroupChangePolicyLabel: "OnRootMismatch",
selinuxChangePolicyLabel: "MountOption",
}),
},
{
name: "when feature is enabled and both fsgroupchangepolicy and selinuxchangepolicy are set, but pod already specifies different policies",
pod: getPod(&alwaysFSGroupChangePolicy, &selinuxRecursive),
featureGateEnabled: true,
expectedPod: getPod(&alwaysFSGroupChangePolicy, &selinuxRecursive),
expectError: false,
name: "when feature is enabled and both fsgroupchangepolicy and selinuxchangepolicy are set, but pod already specifies different policies",
pod: getPod(&alwaysFSGroupChangePolicy, &selinuxRecursive),
expectedPod: getPod(&alwaysFSGroupChangePolicy, &selinuxRecursive),
expectError: false,
ns: getNamespace(map[string]string{
fsGroupChangePolicyLabel: "OnRootMismatch",
selinuxChangePolicyLabel: "MountOption",
}),
},
{
name: "when feature is enabled and both fsgroupchangepolicy and selinuxchangepolicy are set, but selinux lable has invalid value",
pod: getPod(nil, nil),
featureGateEnabled: true,
expectedPod: getPod(&onRootMismatchPolicy, nil),
expectError: false,
name: "when feature is enabled and both fsgroupchangepolicy and selinuxchangepolicy are set, but selinux lable has invalid value",
pod: getPod(nil, nil),
expectedPod: getPod(&onRootMismatchPolicy, nil),
expectError: false,
ns: getNamespace(map[string]string{
fsGroupChangePolicyLabel: "OnRootMismatch",
selinuxChangePolicyLabel: "InvalidValue",
Expand All @@ -141,14 +117,10 @@ func TestAdmit(t *testing.T) {

for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, featuregate.Feature(openshiftfeatures.FeatureGateStoragePerformantSecurityPolicy), tc.featureGateEnabled)

psp := &performantSecurityPolicy{}
psp.nsLister = fakeNamespaceLister(tc.ns)
psp.Handler = admission.NewHandler(admission.Create)

psp.InspectFeatureGates(utilfeature.DefaultFeatureGate)

if err := psp.ValidateInitialization(); err != nil {
t.Fatalf("failed to validate initialization: %v", err)
}
Expand Down
4 changes: 0 additions & 4 deletions pkg/features/openshift_features.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,4 @@ func registerOpenshiftFeatures() {
defaultVersionedKubernetesFeatureGates[MinimumKubeletVersion] = featuregate.VersionedSpecs{
{Version: version.MustParse("1.32"), Default: false, PreRelease: featuregate.Alpha},
}
// Introduced in 4.20
defaultVersionedKubernetesFeatureGates[StoragePerformantSecurityPolicy] = featuregate.VersionedSpecs{
{Version: version.MustParse("1.33"), Default: false, PreRelease: featuregate.Alpha},
}
}