Skip to content

Commit fbe33bc

Browse files
committed
export RoleInterface, prevent non-controlled NSes from appearing in the queue
1 parent f69c842 commit fbe33bc

File tree

2 files changed

+45
-17
lines changed

2 files changed

+45
-17
lines changed

pkg/psalabelsyncer/podsecurity_label_sync_controller.go

+30-6
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,6 @@ func (c *PodSecurityAdmissionLabelSynchronizationController) syncNamespace(ctx c
181181
for _, sccName := range nsSCCs.UnsortedList() {
182182
scc, err := c.sccLister.Get(sccName)
183183
if err != nil {
184-
// TODO: the SCC was removed in the meantime and synced in the cache?
185184
return err
186185
}
187186
sccPSaLevel, err := convertSCCToPSALevel(ns, scc)
@@ -239,6 +238,16 @@ func (c *PodSecurityAdmissionLabelSynchronizationController) queueKeysForObj(obj
239238
}
240239

241240
if ns := metaObj.GetObjectMeta().GetNamespace(); len(ns) > 0 { // it is a namespaced object
241+
controlled, err := c.checkNSControlled(ns)
242+
if err != nil {
243+
klog.Errorf("failed to determine whether namespace %q should be enqueued: %v", ns, err)
244+
return nil
245+
}
246+
247+
if !controlled {
248+
return nil
249+
}
250+
242251
return []string{ns}
243252
}
244253

@@ -260,6 +269,8 @@ func (c *PodSecurityAdmissionLabelSynchronizationController) allWatchedNamespace
260269
return qKeys
261270
}
262271

272+
// saToSCCCAcheEnqueueFunc is a function that allows the SAToSCCCache enqueue keys
273+
// in the queue of the `PodSecurityAdmissionLabelSynchronizationController` struct
263274
func (c *PodSecurityAdmissionLabelSynchronizationController) saToSCCCAcheEnqueueFunc(obj interface{}) {
264275
enqeueAllNS := func() {
265276
// NS was zero-len, we need to enqueue all controlled namespaces
@@ -273,16 +284,16 @@ func (c *PodSecurityAdmissionLabelSynchronizationController) saToSCCCAcheEnqueue
273284
}
274285
}
275286

276-
// TODO: maybe just allow setting 2 separate enqueuers for roles and SCCs?
277287
switch t := obj.(type) {
278-
case roleInterface: // TODO: should be exported
288+
case RoleInterface:
279289
if nsName := t.Namespace(); len(nsName) > 0 {
280-
ns, err := c.namespaceLister.Get(nsName)
290+
controlled, err := c.checkNSControlled(nsName)
281291
if err != nil {
282-
klog.Errorf("failed to enqueue namespace %q: %v", nsName, err)
292+
klog.Errorf("failed to determine whether namespace %q should be enqueued: %v", nsName, err)
283293
return
284294
}
285-
if ns.Labels[labelSyncControlLabel] != "false" {
295+
296+
if controlled {
286297
c.workQueue.Add(nsName)
287298
}
288299
return
@@ -293,6 +304,19 @@ func (c *PodSecurityAdmissionLabelSynchronizationController) saToSCCCAcheEnqueue
293304
}
294305
}
295306

307+
func (c *PodSecurityAdmissionLabelSynchronizationController) checkNSControlled(ns string) (bool, error) {
308+
nsObj, err := c.namespaceLister.Get(ns)
309+
if err != nil {
310+
return false, err
311+
}
312+
313+
if nsObj.Labels[labelSyncControlLabel] != "false" {
314+
return true, nil
315+
}
316+
317+
return false, nil
318+
}
319+
296320
// controlledNamespacesLabelSelector returns label selector to be used with the
297321
// PodSecurityAdmissionLabelSynchronizationController.
298322
func controlledNamespacesLabelSelector() (labels.Selector, error) {

pkg/psalabelsyncer/sccrolecache.go

+15-11
Original file line numberDiff line numberDiff line change
@@ -52,13 +52,15 @@ type roleBindingInterface interface {
5252
Subjects() []rbacv1.Subject
5353
}
5454

55-
type roleInterface interface {
55+
// RoleInterface is an interface for generic access to role-like object, such
56+
// as rbac.Role and rbac.ClusterRole
57+
type RoleInterface interface {
5658
Name() string
5759
Namespace() string
5860
Rules() []rbacv1.PolicyRule
5961
}
6062

61-
func usefulRolesKey(r roleInterface) string {
63+
func usefulRolesKey(r RoleInterface) string {
6264
return fmt.Sprintf("%s/%s", r.Namespace(), r.Name())
6365
}
6466

@@ -110,7 +112,9 @@ type roleObj struct {
110112
clusterRole *rbacv1.ClusterRole
111113
}
112114

113-
func newRoleObj(obj interface{}) (roleInterface, error) {
115+
// NewRoleObj expects either a Role or a ClusterRole as its `obj` input argument,
116+
// it returns an object that allows generic access to the role-like object
117+
func NewRoleObj(obj interface{}) (RoleInterface, error) {
114118
switch r := obj.(type) {
115119
case *rbacv1.ClusterRole:
116120
return &roleObj{
@@ -237,7 +241,7 @@ func (c *SAToSCCCache) handleRoleModified(obj interface{}) {
237241
return
238242
}
239243

240-
role, err := newRoleObj(obj)
244+
role, err := NewRoleObj(obj)
241245
if err != nil {
242246
klog.Warningf("unexpected error, this may be a bug: %v", err)
243247
return
@@ -256,7 +260,7 @@ func (c *SAToSCCCache) handleRoleModified(obj interface{}) {
256260
}
257261

258262
func (c *SAToSCCCache) handleRoleRemoved(obj interface{}) {
259-
role, err := newRoleObj(obj)
263+
role, err := NewRoleObj(obj)
260264
if err != nil {
261265
klog.Warningf("unexpected error, this may be a bug: %v", err)
262266
return
@@ -374,7 +378,7 @@ func (c *SAToSCCCache) SCCsFor(serviceAccount *corev1.ServiceAccount) (sets.Stri
374378
}
375379

376380
// getRoleFromRoleRef tries to retrieve the role or clusterrole from roleRef.
377-
func (c *SAToSCCCache) getRoleFromRoleRef(ns string, roleRef rbacv1.RoleRef) (roleInterface, error) {
381+
func (c *SAToSCCCache) getRoleFromRoleRef(ns string, roleRef rbacv1.RoleRef) (RoleInterface, error) {
378382
var err error
379383
var role interface{}
380384
switch kind := roleRef.Kind; kind {
@@ -394,7 +398,7 @@ func (c *SAToSCCCache) getRoleFromRoleRef(ns string, roleRef rbacv1.RoleRef) (ro
394398
return nil, fmt.Errorf("unknown kind in roleRef: %s", kind)
395399
}
396400

397-
return newRoleObj(role)
401+
return NewRoleObj(role)
398402
}
399403

400404
// IsRoleBindingRelevant returns true if the cluster/rolebinding supplied binds
@@ -426,7 +430,7 @@ func (c *SAToSCCCache) IsRoleInvolvesSCCs(obj interface{}, isRoleUpdate bool) bo
426430
c.usefulRolesLock.Lock()
427431
defer c.usefulRolesLock.Unlock()
428432

429-
role, err := newRoleObj(obj)
433+
role, err := NewRoleObj(obj)
430434
if err != nil {
431435
klog.Warningf("unexpected error, this may be a bug: %v", err)
432436
return false
@@ -473,15 +477,15 @@ func (c *SAToSCCCache) ReinitializeRoleCache() error {
473477
}
474478

475479
for _, r := range roles {
476-
role, err := newRoleObj(r)
480+
role, err := NewRoleObj(r)
477481
if err != nil {
478482
panic(err)
479483
}
480484
c.syncRoleCache(role, r.Rules, sccs)
481485
}
482486

483487
for _, r := range clusterRoles {
484-
role, err := newRoleObj(r)
488+
role, err := NewRoleObj(r)
485489
if err != nil {
486490
panic(err)
487491
}
@@ -494,7 +498,7 @@ func (c *SAToSCCCache) ReinitializeRoleCache() error {
494498
// syncRoleCache will write the current mapping of "role->SCCs it allows" to the cache.
495499
// It expects the c.usefulRolesLock to be already locked as even the wrapping context
496500
// handling roles and SCCs likely requires synchronization.
497-
func (c *SAToSCCCache) syncRoleCache(role roleInterface, rules []rbacv1.PolicyRule, sccs []*securityv1.SecurityContextConstraints) {
501+
func (c *SAToSCCCache) syncRoleCache(role RoleInterface, rules []rbacv1.PolicyRule, sccs []*securityv1.SecurityContextConstraints) {
498502
if c.usefulRolesLock.TryLock() {
499503
c.usefulRolesLock.Unlock()
500504
panic("syncRoleCache() requires the usefulRolesLock to be always locked before entering the function")

0 commit comments

Comments
 (0)