From 0e062981d11d40cc555019b95e05f768a010e444 Mon Sep 17 00:00:00 2001 From: Jordan Liggitt Date: Wed, 3 Jun 2020 13:07:20 -0400 Subject: [PATCH] Detect PSP enablement more accurately --- .../security/podsecuritypolicy/admission.go | 10 +++--- test/e2e/framework/psp.go | 36 +++++++++++++++---- 2 files changed, 34 insertions(+), 12 deletions(-) diff --git a/plugin/pkg/admission/security/podsecuritypolicy/admission.go b/plugin/pkg/admission/security/podsecuritypolicy/admission.go index 47aa6797220..e1edb1159a2 100644 --- a/plugin/pkg/admission/security/podsecuritypolicy/admission.go +++ b/plugin/pkg/admission/security/podsecuritypolicy/admission.go @@ -127,7 +127,7 @@ func (p *Plugin) Admit(ctx context.Context, a admission.Attributes, o admission. // compute the context. Mutation is allowed. ValidatedPSPAnnotation is not taken into account. allowedPod, pspName, validationErrs, err := p.computeSecurityContext(ctx, a, pod, true, "") if err != nil { - return admission.NewForbidden(a, err) + return admission.NewForbidden(a, fmt.Errorf("PodSecurityPolicy: %w", err)) } if allowedPod != nil { *pod = *allowedPod @@ -145,8 +145,8 @@ func (p *Plugin) Admit(ctx context.Context, a admission.Attributes, o admission. } // we didn't validate against any provider, reject the pod and give the errors for each attempt - klog.V(4).Infof("unable to validate pod %s (generate: %s) in namespace %s against any pod security policy: %v", pod.Name, pod.GenerateName, a.GetNamespace(), validationErrs) - return admission.NewForbidden(a, fmt.Errorf("unable to validate against any pod security policy: %v", validationErrs)) + klog.V(4).Infof("unable to admit pod %s (generate: %s) in namespace %s against any pod security policy: %v", pod.Name, pod.GenerateName, a.GetNamespace(), validationErrs) + return admission.NewForbidden(a, fmt.Errorf("PodSecurityPolicy: unable to admit pod: %v", validationErrs)) } // Validate verifies attributes against the PodSecurityPolicy @@ -162,7 +162,7 @@ func (p *Plugin) Validate(ctx context.Context, a admission.Attributes, o admissi // compute the context. Mutation is not allowed. ValidatedPSPAnnotation is used as a hint to gain same speed-up. allowedPod, pspName, validationErrs, err := p.computeSecurityContext(ctx, a, pod, false, pod.ObjectMeta.Annotations[psputil.ValidatedPSPAnnotation]) if err != nil { - return admission.NewForbidden(a, err) + return admission.NewForbidden(a, fmt.Errorf("PodSecurityPolicy: %w", err)) } if apiequality.Semantic.DeepEqual(pod, allowedPod) { key := auditKeyPrefix + "/" + "validate-policy" @@ -174,7 +174,7 @@ func (p *Plugin) Validate(ctx context.Context, a admission.Attributes, o admissi // we didn't validate against any provider, reject the pod and give the errors for each attempt klog.V(4).Infof("unable to validate pod %s (generate: %s) in namespace %s against any pod security policy: %v", pod.Name, pod.GenerateName, a.GetNamespace(), validationErrs) - return admission.NewForbidden(a, fmt.Errorf("unable to validate against any pod security policy: %v", validationErrs)) + return admission.NewForbidden(a, fmt.Errorf("PodSecurityPolicy: unable to validate pod: %v", validationErrs)) } func shouldIgnore(a admission.Attributes) (bool, error) { diff --git a/test/e2e/framework/psp.go b/test/e2e/framework/psp.go index 1f2a9b7326d..c0d5f92f33b 100644 --- a/test/e2e/framework/psp.go +++ b/test/e2e/framework/psp.go @@ -19,6 +19,7 @@ package framework import ( "context" "fmt" + "strings" "sync" v1 "k8s.io/api/core/v1" @@ -29,6 +30,7 @@ import ( "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apiserver/pkg/authentication/serviceaccount" clientset "k8s.io/client-go/kubernetes" + imageutils "k8s.io/kubernetes/test/utils/image" "github.com/onsi/ginkgo" @@ -92,14 +94,34 @@ func IsPodSecurityPolicyEnabled(kubeClient clientset.Interface) bool { psps, err := kubeClient.PolicyV1beta1().PodSecurityPolicies().List(context.TODO(), metav1.ListOptions{}) if err != nil { Logf("Error listing PodSecurityPolicies; assuming PodSecurityPolicy is disabled: %v", err) - isPSPEnabled = false - } else if psps == nil || len(psps.Items) == 0 { - Logf("No PodSecurityPolicies found; assuming PodSecurityPolicy is disabled.") - isPSPEnabled = false - } else { - Logf("Found PodSecurityPolicies; assuming PodSecurityPolicy is enabled.") - isPSPEnabled = true + return } + if psps == nil || len(psps.Items) == 0 { + Logf("No PodSecurityPolicies found; assuming PodSecurityPolicy is disabled.") + return + } + Logf("Found PodSecurityPolicies; testing pod creation to see if PodSecurityPolicy is enabled") + testPod := &v1.Pod{ + ObjectMeta: metav1.ObjectMeta{GenerateName: "psp-test-pod-"}, + Spec: v1.PodSpec{Containers: []v1.Container{{Name: "test", Image: imageutils.GetPauseImageName()}}}, + } + dryRunPod, err := kubeClient.CoreV1().Pods("kube-system").Create(context.TODO(), testPod, metav1.CreateOptions{DryRun: []string{metav1.DryRunAll}}) + if err != nil { + if strings.Contains(err.Error(), "PodSecurityPolicy") { + Logf("PodSecurityPolicy error creating dryrun pod; assuming PodSecurityPolicy is enabled: %v", err) + isPSPEnabled = true + } else { + Logf("Error creating dryrun pod; assuming PodSecurityPolicy is disabled: %v", err) + } + return + } + pspAnnotation, pspAnnotationExists := dryRunPod.Annotations["kubernetes.io/psp"] + if !pspAnnotationExists { + Logf("No PSP annotation exists on dry run pod; assuming PodSecurityPolicy is disabled") + return + } + Logf("PSP annotation exists on dry run pod: %q; assuming PodSecurityPolicy is enabled", pspAnnotation) + isPSPEnabled = true }) return isPSPEnabled }