Skip to content

Commit d6adece

Browse files
committed
podsecurityreadinesscontroller: wire down psapi.ParseLevel to classific
1 parent 465832d commit d6adece

File tree

3 files changed

+39
-66
lines changed

3 files changed

+39
-66
lines changed

pkg/operator/podsecurityreadinesscontroller/classification.go

Lines changed: 11 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ package podsecurityreadinesscontroller
22

33
import (
44
"context"
5-
"fmt"
65
"strings"
76

87
securityv1 "github.com/openshift/api/security/v1"
@@ -22,7 +21,12 @@ var (
2221
)
2322
)
2423

25-
func (c *PodSecurityReadinessController) classifyViolatingNamespace(ctx context.Context, conditions *podSecurityOperatorConditions, ns *corev1.Namespace, enforceLevel string) error {
24+
func (c *PodSecurityReadinessController) classifyViolatingNamespace(
25+
ctx context.Context,
26+
conditions *podSecurityOperatorConditions,
27+
ns *corev1.Namespace,
28+
enforceLevel psapi.Level,
29+
) error {
2630
if runLevelZeroNamespaces.Has(ns.Name) {
2731
conditions.addViolatingRunLevelZero(ns)
2832
return nil
@@ -56,23 +60,11 @@ func (c *PodSecurityReadinessController) classifyViolatingNamespace(ctx context.
5660
return nil
5761
}
5862

59-
func (c *PodSecurityReadinessController) isUserViolation(ctx context.Context, ns *corev1.Namespace, label string) (bool, error) {
60-
var enforcementLevel psapi.Level
61-
switch strings.ToLower(label) {
62-
case "restricted":
63-
enforcementLevel = psapi.LevelRestricted
64-
case "baseline":
65-
enforcementLevel = psapi.LevelBaseline
66-
case "privileged":
67-
// If privileged is violating, something is seriously wrong
68-
// but testing against privileged level is pointless (everything passes)
69-
klog.V(2).InfoS("Namespace violating privileged level - skipping user check",
70-
"namespace", ns.Name)
71-
return false, nil
72-
default:
73-
return false, fmt.Errorf("unknown level: %q", label)
74-
}
75-
63+
func (c *PodSecurityReadinessController) isUserViolation(
64+
ctx context.Context,
65+
ns *corev1.Namespace,
66+
enforcementLevel psapi.Level,
67+
) (bool, error) {
7668
allPods, err := c.kubeClient.CoreV1().Pods(ns.Name).List(ctx, metav1.ListOptions{})
7769
if err != nil {
7870
klog.V(2).ErrorS(err, "Failed to list pods in namespace", "namespace", ns.Name)
@@ -102,28 +94,14 @@ func (c *PodSecurityReadinessController) isUserViolation(ctx context.Context, ns
10294

10395
enforcementVersion := psapi.LatestVersion()
10496
for _, pod := range userPods {
105-
klog.InfoS("Evaluating user pod against PSA level",
106-
"namespace", ns.Name, "pod", pod.Name, "level", label,
107-
"podSecurityContext", pod.Spec.SecurityContext)
108-
10997
results := c.psaEvaluator.EvaluatePod(
11098
psapi.LevelVersion{Level: enforcementLevel, Version: enforcementVersion},
11199
&pod.ObjectMeta,
112100
&pod.Spec,
113101
)
114102

115-
klog.InfoS("PSA evaluation results",
116-
"namespace", ns.Name, "pod", pod.Name, "level", label,
117-
"resultCount", len(results))
118-
119103
for _, result := range results {
120-
klog.InfoS("PSA evaluation result",
121-
"namespace", ns.Name, "pod", pod.Name, "level", label,
122-
"allowed", result.Allowed, "reason", result.ForbiddenReason,
123-
"detail", result.ForbiddenDetail)
124104
if !result.Allowed {
125-
klog.InfoS("User pod violates PSA level",
126-
"namespace", ns.Name, "pod", pod.Name, "level", label)
127105
return true, nil
128106
}
129107
}

pkg/operator/podsecurityreadinesscontroller/classification_test.go

Lines changed: 13 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import (
1313
"k8s.io/apimachinery/pkg/runtime"
1414
"k8s.io/client-go/kubernetes/fake"
1515
clienttesting "k8s.io/client-go/testing"
16+
psapi "k8s.io/pod-security-admission/api"
1617
"k8s.io/pod-security-admission/policy"
1718
)
1819

@@ -68,7 +69,7 @@ func TestClassifyViolatingNamespace(t *testing.T) {
6869
name string
6970
namespace *corev1.Namespace
7071
pods []corev1.Pod
71-
enforceLevel string
72+
enforceLevel psapi.Level
7273
expectedConditions podSecurityOperatorConditions
7374
expectError bool
7475
}{
@@ -80,7 +81,7 @@ func TestClassifyViolatingNamespace(t *testing.T) {
8081
},
8182
},
8283
pods: []corev1.Pod{},
83-
enforceLevel: "restricted",
84+
enforceLevel: psapi.LevelRestricted,
8485
expectedConditions: podSecurityOperatorConditions{
8586
violatingRunLevelZeroNamespaces: []string{"kube-system"},
8687
},
@@ -94,7 +95,7 @@ func TestClassifyViolatingNamespace(t *testing.T) {
9495
},
9596
},
9697
pods: []corev1.Pod{},
97-
enforceLevel: "restricted",
98+
enforceLevel: psapi.LevelRestricted,
9899
expectedConditions: podSecurityOperatorConditions{
99100
violatingRunLevelZeroNamespaces: []string{"default"},
100101
},
@@ -108,7 +109,7 @@ func TestClassifyViolatingNamespace(t *testing.T) {
108109
},
109110
},
110111
pods: []corev1.Pod{},
111-
enforceLevel: "restricted",
112+
enforceLevel: psapi.LevelRestricted,
112113
expectedConditions: podSecurityOperatorConditions{
113114
violatingRunLevelZeroNamespaces: []string{"kube-public"},
114115
},
@@ -122,7 +123,7 @@ func TestClassifyViolatingNamespace(t *testing.T) {
122123
},
123124
},
124125
pods: []corev1.Pod{},
125-
enforceLevel: "restricted",
126+
enforceLevel: psapi.LevelRestricted,
126127
expectedConditions: podSecurityOperatorConditions{
127128
violatingOpenShiftNamespaces: []string{"openshift-test"},
128129
},
@@ -155,7 +156,7 @@ func TestClassifyViolatingNamespace(t *testing.T) {
155156
pods: []corev1.Pod{
156157
newUserSCCPodPrivileged("user-pod", "customer-ns"),
157158
},
158-
enforceLevel: "restricted",
159+
enforceLevel: psapi.LevelRestricted,
159160
expectedConditions: podSecurityOperatorConditions{
160161
violatingUserSCCNamespaces: []string{"customer-ns"},
161162
},
@@ -171,7 +172,7 @@ func TestClassifyViolatingNamespace(t *testing.T) {
171172
pods: []corev1.Pod{
172173
newUserSCCPodWithPrivilegedContainer("user-scc-violating-pod", "user-scc-violation-test"),
173174
},
174-
enforceLevel: "restricted",
175+
enforceLevel: psapi.LevelRestricted,
175176
expectedConditions: podSecurityOperatorConditions{
176177
violatingUserSCCNamespaces: []string{"user-scc-violation-test"},
177178
},
@@ -187,7 +188,7 @@ func TestClassifyViolatingNamespace(t *testing.T) {
187188
pods: []corev1.Pod{
188189
newServiceAccountPod("sa-pod", "customer-ns"),
189190
},
190-
enforceLevel: "restricted",
191+
enforceLevel: psapi.LevelRestricted,
191192
expectedConditions: podSecurityOperatorConditions{
192193
violatingCustomerNamespaces: []string{"customer-ns"},
193194
},
@@ -221,7 +222,7 @@ func TestClassifyViolatingNamespace(t *testing.T) {
221222
pods: []corev1.Pod{
222223
newUserSCCPodRestricted("user-pod", "customer-ns"),
223224
},
224-
enforceLevel: "restricted",
225+
enforceLevel: psapi.LevelRestricted,
225226
expectedConditions: podSecurityOperatorConditions{
226227
violatingCustomerNamespaces: []string{"customer-ns"},
227228
},
@@ -235,7 +236,7 @@ func TestClassifyViolatingNamespace(t *testing.T) {
235236
},
236237
},
237238
pods: []corev1.Pod{},
238-
enforceLevel: "restricted",
239+
enforceLevel: psapi.LevelRestricted,
239240
expectedConditions: podSecurityOperatorConditions{
240241
violatingCustomerNamespaces: []string{"customer-ns"},
241242
},
@@ -265,7 +266,7 @@ func TestClassifyViolatingNamespace(t *testing.T) {
265266
},
266267
},
267268
},
268-
enforceLevel: "restricted",
269+
enforceLevel: psapi.LevelRestricted,
269270
expectedConditions: podSecurityOperatorConditions{
270271
violatingCustomerNamespaces: []string{"customer-ns"},
271272
},
@@ -281,24 +282,12 @@ func TestClassifyViolatingNamespace(t *testing.T) {
281282
pods: []corev1.Pod{
282283
newUserSCCPodPrivileged("user-pod", "customer-ns"),
283284
},
284-
enforceLevel: "privileged",
285+
enforceLevel: psapi.LevelPrivileged,
285286
expectedConditions: podSecurityOperatorConditions{
286287
violatingCustomerNamespaces: []string{"customer-ns"},
287288
},
288289
expectError: false,
289290
},
290-
{
291-
name: "invalid PSA level causes error",
292-
namespace: &corev1.Namespace{
293-
ObjectMeta: metav1.ObjectMeta{
294-
Name: "customer-ns",
295-
},
296-
},
297-
pods: []corev1.Pod{},
298-
enforceLevel: "invalid-level",
299-
expectedConditions: podSecurityOperatorConditions{},
300-
expectError: true,
301-
},
302291
} {
303292
t.Run(tt.name, func(t *testing.T) {
304293
controller, err := createTestController(tt.pods)

pkg/operator/podsecurityreadinesscontroller/violation.go

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -23,15 +23,15 @@ var (
2323
// isNamespaceViolating checks if a namespace is ready for Pod Security Admission enforcement.
2424
// It returns true if the namespace is violating the Pod Security Admission policy, along with
2525
// the enforce label it was tested against.
26-
func (c *PodSecurityReadinessController) isNamespaceViolating(ctx context.Context, ns *corev1.Namespace) (bool, string, error) {
26+
func (c *PodSecurityReadinessController) isNamespaceViolating(ctx context.Context, ns *corev1.Namespace) (bool, psapi.Level, error) {
2727
nsApplyConfig, err := applyconfiguration.ExtractNamespace(ns, syncerControllerName)
2828
if err != nil {
2929
return false, "", err
3030
}
3131

3232
enforceLabel := determineEnforceLabelForNamespace(nsApplyConfig)
3333
nsApply := applyconfiguration.Namespace(ns.Name).WithLabels(map[string]string{
34-
psapi.EnforceLevelLabel: enforceLabel,
34+
psapi.EnforceLevelLabel: string(enforceLabel),
3535
})
3636

3737
_, err = c.kubeClient.CoreV1().
@@ -53,16 +53,22 @@ func (c *PodSecurityReadinessController) isNamespaceViolating(ctx context.Contex
5353
return false, "", nil
5454
}
5555

56-
func determineEnforceLabelForNamespace(ns *applyconfiguration.NamespaceApplyConfiguration) string {
57-
if _, ok := ns.Annotations[securityv1.MinimallySufficientPodSecurityStandard]; ok {
56+
func determineEnforceLabelForNamespace(ns *applyconfiguration.NamespaceApplyConfiguration) psapi.Level {
57+
if pssAnnotation, ok := ns.Annotations[securityv1.MinimallySufficientPodSecurityStandard]; ok {
5858
// This should generally exist and will be the only supported method of determining
5959
// the enforce level going forward - however, we're keeping the label fallback for
6060
// now to account for any workloads not yet annotated using a new enough version of
6161
// the syncer, such as during upgrade scenarios.
62-
return ns.Annotations[securityv1.MinimallySufficientPodSecurityStandard]
62+
level, err := psapi.ParseLevel(pssAnnotation)
63+
if err == nil {
64+
return level
65+
}
66+
if err != nil {
67+
klog.V(2).InfoS("invalid level in scc annotation", "value", level)
68+
}
6369
}
6470

65-
targetLevel := ""
71+
var targetLevel psapi.Level
6672
for label := range alertLabels {
6773
value, ok := ns.Labels[label]
6874
if !ok {
@@ -76,18 +82,18 @@ func determineEnforceLabelForNamespace(ns *applyconfiguration.NamespaceApplyConf
7682
}
7783

7884
if targetLevel == "" {
79-
targetLevel = value
85+
targetLevel = level
8086
continue
8187
}
8288

8389
if psapi.CompareLevels(psapi.Level(targetLevel), level) < 0 {
84-
targetLevel = value
90+
targetLevel = level
8591
}
8692
}
8793

8894
if targetLevel == "" {
8995
// Global Config will set it to "restricted", but shouldn't happen.
90-
return string(psapi.LevelRestricted)
96+
return psapi.LevelRestricted
9197
}
9298

9399
return targetLevel

0 commit comments

Comments
 (0)