@@ -4,12 +4,10 @@ import (
44 "context"
55 "time"
66
7- corev1 "k8s.io/api/core/v1"
87 apierrors "k8s.io/apimachinery/pkg/api/errors"
98 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
109 "k8s.io/apimachinery/pkg/labels"
1110 "k8s.io/apimachinery/pkg/selection"
12- applyconfiguration "k8s.io/client-go/applyconfigurations/core/v1"
1311 "k8s.io/client-go/kubernetes"
1412 "k8s.io/client-go/rest"
1513 "k8s.io/client-go/util/retry"
@@ -25,11 +23,6 @@ const (
2523 checkInterval = 240 * time .Minute // Adjust the interval as needed.
2624)
2725
28- var podSecurityAlertLabels = []string {
29- psapi .AuditLevelLabel ,
30- psapi .WarnLevelLabel ,
31- }
32-
3326// PodSecurityReadinessController checks if namespaces are ready for Pod Security Admission enforcement.
3427type PodSecurityReadinessController struct {
3528 kubeClient kubernetes.Interface
@@ -46,19 +39,12 @@ func NewPodSecurityReadinessController(
4639) (factory.Controller , error ) {
4740 warningsHandler := & warningsHandler {}
4841
49- kubeClientCopy := rest .CopyConfig (kubeConfig )
50- kubeClientCopy .WarningHandler = warningsHandler
51- // We don't want to overwhelm the apiserver with requests. On a cluster with
52- // 10k namespaces, we would send 10k + 1 requests to the apiserver.
53- kubeClientCopy .QPS = 2
54- kubeClientCopy .Burst = 2
55- kubeClient , err := kubernetes .NewForConfig (kubeClientCopy )
42+ kubeClient , err := newWarningAwareKubeClient (warningsHandler , kubeConfig )
5643 if err != nil {
5744 return nil , err
5845 }
5946
60- selector := labels .NewSelector ()
61- labelsRequirement , err := labels .NewRequirement (psapi .EnforceLevelLabel , selection .DoesNotExist , []string {})
47+ selector , err := nonEnforcingSelector ()
6248 if err != nil {
6349 return nil , err
6450 }
@@ -67,7 +53,7 @@ func NewPodSecurityReadinessController(
6753 operatorClient : operatorClient ,
6854 kubeClient : kubeClient ,
6955 warningsHandler : warningsHandler ,
70- namespaceSelector : selector . Add ( * labelsRequirement ). String () ,
56+ namespaceSelector : selector ,
7157 }
7258
7359 return factory .New ().
@@ -114,58 +100,23 @@ func (c *PodSecurityReadinessController) sync(ctx context.Context, syncCtx facto
114100 return err
115101}
116102
117- func (c * PodSecurityReadinessController ) isNamespaceViolating (ctx context.Context , ns * corev1.Namespace ) (bool , error ) {
118- if ns .Labels [psapi .EnforceLevelLabel ] != "" {
119- // If someone has taken care of the enforce label, we don't need to
120- // check for violations. Global Config nor PS-Label-Syncer will modify
121- // it.
122- return false , nil
123- }
124-
125- targetLevel := ""
126- for _ , label := range podSecurityAlertLabels {
127- levelStr , ok := ns .Labels [label ]
128- if ! ok {
129- continue
130- }
131-
132- level , err := psapi .ParseLevel (levelStr )
133- if err != nil {
134- klog .V (4 ).InfoS ("invalid level" , "namespace" , ns .Name , "level" , levelStr )
135- continue
136- }
137-
138- if targetLevel == "" {
139- targetLevel = levelStr
140- continue
141- }
142-
143- if psapi .CompareLevels (psapi .Level (targetLevel ), level ) < 0 {
144- targetLevel = levelStr
145- }
146- }
147-
148- if targetLevel == "" {
149- // Global Config will set it to "restricted".
150- targetLevel = string (psapi .LevelRestricted )
151- }
152-
153- nsApply := applyconfiguration .Namespace (ns .Name ).WithLabels (map [string ]string {
154- psapi .EnforceLevelLabel : string (targetLevel ),
155- })
156-
157- _ , err := c .kubeClient .CoreV1 ().
158- Namespaces ().
159- Apply (ctx , nsApply , metav1.ApplyOptions {
160- DryRun : []string {metav1 .DryRunAll },
161- FieldManager : "pod-security-readiness-controller" ,
162- })
103+ func nonEnforcingSelector () (string , error ) {
104+ selector := labels .NewSelector ()
105+ labelsRequirement , err := labels .NewRequirement (psapi .EnforceLevelLabel , selection .DoesNotExist , []string {})
163106 if err != nil {
164- return false , err
107+ return "" , err
165108 }
166109
167- // The information we want is in the warnings. It collects violations.
168- warnings := c .warningsHandler .PopAll ()
110+ return selector .Add (* labelsRequirement ).String (), nil
111+ }
112+
113+ func newWarningAwareKubeClient (warningsHandler * warningsHandler , kubeConfig * rest.Config ) (* kubernetes.Clientset , error ) {
114+ kubeClientCopy := rest .CopyConfig (kubeConfig )
115+ kubeClientCopy .WarningHandler = warningsHandler
116+ // We don't want to overwhelm the apiserver with requests. On a cluster with
117+ // 10k namespaces, we would send 10k + 1 requests to the apiserver.
118+ kubeClientCopy .QPS = 2
119+ kubeClientCopy .Burst = 2
169120
170- return len ( warnings ) > 0 , nil
121+ return kubernetes . NewForConfig ( kubeClientCopy )
171122}
0 commit comments