diff --git a/staging/src/k8s.io/pod-security-admission/admission/admission.go b/staging/src/k8s.io/pod-security-admission/admission/admission.go index d6450a429f4..fc36f0530c7 100644 --- a/staging/src/k8s.io/pod-security-admission/admission/admission.go +++ b/staging/src/k8s.io/pod-security-admission/admission/admission.go @@ -21,6 +21,7 @@ import ( "fmt" "reflect" "sort" + "strings" "time" "k8s.io/klog/v2" @@ -250,7 +251,7 @@ func (a *Admission) ValidateNamespace(ctx context.Context, attrs api.Attributes) return invalidResponse(attrs, newErrs) } if a.exemptNamespace(attrs.GetNamespace()) { - if warning := a.exemptNamespaceWarning(namespace.Name, newPolicy); warning != "" { + if warning := a.exemptNamespaceWarning(namespace.Name, newPolicy, namespace.Labels); warning != "" { response := allowedResponse() response.Warnings = append(response.Warnings, warning) return response @@ -293,7 +294,7 @@ func (a *Admission) ValidateNamespace(ctx context.Context, attrs api.Attributes) return sharedAllowedResponse } if a.exemptNamespace(attrs.GetNamespace()) { - if warning := a.exemptNamespaceWarning(namespace.Name, newPolicy); warning != "" { + if warning := a.exemptNamespaceWarning(namespace.Name, newPolicy, namespace.Labels); warning != "" { response := allowedResponse() response.Warnings = append(response.Warnings, warning) return response @@ -736,11 +737,39 @@ func containsString(needle string, haystack []string) bool { // exemptNamespaceWarning returns a non-empty warning message if the exempt namespace has a // non-privileged policy and sets pod security labels. -func (a *Admission) exemptNamespaceWarning(exemptNamespace string, policy api.Policy) string { +func (a *Admission) exemptNamespaceWarning(exemptNamespace string, policy api.Policy, nsLabels map[string]string) string { if policy.FullyPrivileged() || policy.Equivalent(&a.defaultPolicy) { return "" } + // Build a compact representation of the policy, only printing non-privileged modes that have + // been explicitly set. + sb := strings.Builder{} + _, hasEnforceLevel := nsLabels[api.EnforceLevelLabel] + _, hasEnforceVersion := nsLabels[api.EnforceVersionLabel] + if policy.Enforce.Level != api.LevelPrivileged && (hasEnforceLevel || hasEnforceVersion) { + sb.WriteString("enforce=") + sb.WriteString(policy.Enforce.String()) + } + _, hasAuditLevel := nsLabels[api.AuditLevelLabel] + _, hasAuditVersion := nsLabels[api.AuditVersionLabel] + if policy.Audit.Level != api.LevelPrivileged && (hasAuditLevel || hasAuditVersion) { + if sb.Len() > 0 { + sb.WriteString(", ") + } + sb.WriteString("audit=") + sb.WriteString(policy.Audit.String()) + } + _, hasWarnLevel := nsLabels[api.WarnLevelLabel] + _, hasWarnVersion := nsLabels[api.WarnVersionLabel] + if policy.Warn.Level != api.LevelPrivileged && (hasWarnLevel || hasWarnVersion) { + if sb.Len() > 0 { + sb.WriteString(", ") + } + sb.WriteString("warn=") + sb.WriteString(policy.Warn.String()) + } + return fmt.Sprintf("namespace %q is exempt from Pod Security, and the policy (%s) will be ignored", - exemptNamespace, policy.CompactString()) + exemptNamespace, sb.String()) } diff --git a/staging/src/k8s.io/pod-security-admission/admission/admission_test.go b/staging/src/k8s.io/pod-security-admission/admission/admission_test.go index c0412b6d930..26bf4f3ab01 100644 --- a/staging/src/k8s.io/pod-security-admission/admission/admission_test.go +++ b/staging/src/k8s.io/pod-security-admission/admission/admission_test.go @@ -278,7 +278,7 @@ func TestValidateNamespace(t *testing.T) { expectAllowed: true, expectListPods: false, expectWarnings: []string{ - `namespace "test" is exempt from Pod Security, and the policy (enforce=restricted:latest, warn=restricted:latest) will be ignored`, + `namespace "test" is exempt from Pod Security, and the policy (enforce=restricted:latest) will be ignored`, }, }, { @@ -1180,7 +1180,7 @@ func TestExemptNamespaceWarning(t *testing.T) { api.EnforceLevelLabel: string(api.LevelBaseline), }, expectWarning: true, - expectWarningContains: "(enforce=baseline:latest, warn=baseline:latest)", + expectWarningContains: "(enforce=baseline:latest)", }, { name: "warn-on-warn", labels: map[string]string{ @@ -1206,7 +1206,7 @@ func TestExemptNamespaceWarning(t *testing.T) { }, defaultPolicy: baselinePolicy, expectWarning: true, - expectWarningContains: "(enforce=baseline:v1.23, audit=baseline:v1.23, warn=baseline:latest)", + expectWarningContains: "(warn=baseline:latest)", }} const ( @@ -1228,7 +1228,7 @@ func TestExemptNamespaceWarning(t *testing.T) { policy, err := api.PolicyToEvaluate(labels, defaultPolicy) require.NoError(t, err.ToAggregate()) - warning := a.exemptNamespaceWarning(test.name, policy) + warning := a.exemptNamespaceWarning(test.name, policy, labels) if !test.expectWarning { assert.Empty(t, warning) return diff --git a/staging/src/k8s.io/pod-security-admission/api/helpers.go b/staging/src/k8s.io/pod-security-admission/api/helpers.go index 200a82cdab0..706b6b36b20 100644 --- a/staging/src/k8s.io/pod-security-admission/api/helpers.go +++ b/staging/src/k8s.io/pod-security-admission/api/helpers.go @@ -161,35 +161,6 @@ func (p *Policy) String() string { return fmt.Sprintf("enforce=%#v, audit=%#v, warn=%#v", p.Enforce, p.Audit, p.Warn) } -// CompactString prints a minimalist representation of the policy that excludes any privileged -// levels. -func (p *Policy) CompactString() string { - sb := strings.Builder{} - if p.Enforce.Level != LevelPrivileged { - sb.WriteString("enforce=") - sb.WriteString(p.Enforce.String()) - } - if p.Audit.Level != LevelPrivileged { - if sb.Len() > 0 { - sb.WriteString(", ") - } - sb.WriteString("audit=") - sb.WriteString(p.Audit.String()) - } - if p.Warn.Level != LevelPrivileged { - if sb.Len() > 0 { - sb.WriteString(", ") - } - sb.WriteString("warn=") - sb.WriteString(p.Warn.String()) - } - if sb.Len() == 0 { - // All modes were privileged, just output "privileged". - return string(LevelPrivileged) - } - return sb.String() -} - // Equivalent determines whether two policies are functionally equivalent. Policies are considered // equivalent if all 3 modes are considered equivalent. func (p *Policy) Equivalent(other *Policy) bool {