@@ -105,6 +105,9 @@ func (s *neverSkipSynchronizer) SkipSynchronize(prevState string, versionedObjec
105
105
106
106
// AuthorizationCache maintains a cache on the set of namespaces a user or group can access.
107
107
type AuthorizationCache struct {
108
+ // allKnownNamespaces we track all the known namespaces, so we can detect deletes.
109
+ // TODO remove this in favor of a list/watch mechanism for projects
110
+ allKnownNamespaces sets.String
108
111
namespaceStore cache.Store
109
112
namespaceInterface kclient.NamespaceInterface
110
113
lastSyncResourceVersioner LastSyncResourceVersioner
@@ -132,6 +135,7 @@ type AuthorizationCache struct {
132
135
// NewAuthorizationCache creates a new AuthorizationCache
133
136
func NewAuthorizationCache (reviewer Reviewer , namespaceInterface kclient.NamespaceInterface , policyClient policyclient.ReadOnlyPolicyClient ) * AuthorizationCache {
134
137
result := & AuthorizationCache {
138
+ allKnownNamespaces : sets.String {},
135
139
namespaceStore : cache .NewStore (cache .MetaNamespaceKeyFunc ),
136
140
namespaceInterface : namespaceInterface ,
137
141
lastSyncResourceVersioner : & unchangingLastSyncResourceVersioner {},
@@ -203,7 +207,7 @@ func (ac *AuthorizationCache) RemoveWatcher(watcher CacheWatcher) {
203
207
}
204
208
205
209
// synchronizeNamespaces synchronizes access over each namespace and returns a set of namespace names that were looked at in last sync
206
- func (ac * AuthorizationCache ) synchronizeNamespaces (userSubjectRecordStore cache.Store , groupSubjectRecordStore cache.Store , reviewRecordStore cache.Store ) * sets.String {
210
+ func (ac * AuthorizationCache ) synchronizeNamespaces (userSubjectRecordStore cache.Store , groupSubjectRecordStore cache.Store , reviewRecordStore cache.Store ) sets.String {
207
211
namespaceSet := sets .NewString ()
208
212
items := ac .namespaceStore .List ()
209
213
for i := range items {
@@ -217,7 +221,7 @@ func (ac *AuthorizationCache) synchronizeNamespaces(userSubjectRecordStore cache
217
221
utilruntime .HandleError (fmt .Errorf ("error synchronizing: %v" , err ))
218
222
}
219
223
}
220
- return & namespaceSet
224
+ return namespaceSet
221
225
}
222
226
223
227
// synchronizePolicies synchronizes access over each policy
@@ -257,16 +261,20 @@ func (ac *AuthorizationCache) synchronizePolicyBindings(userSubjectRecordStore c
257
261
}
258
262
259
263
// purgeDeletedNamespaces will remove all namespaces enumerated in a reviewRecordStore that are not in the namespace set
260
- func purgeDeletedNamespaces ( namespaceSet * sets.String , userSubjectRecordStore cache.Store , groupSubjectRecordStore cache.Store , reviewRecordStore cache.Store ) {
264
+ func ( ac * AuthorizationCache ) purgeDeletedNamespaces ( oldNamespaces , newNamespaces sets.String , userSubjectRecordStore cache.Store , groupSubjectRecordStore cache.Store , reviewRecordStore cache.Store ) {
261
265
reviewRecordItems := reviewRecordStore .List ()
262
266
for i := range reviewRecordItems {
263
267
reviewRecord := reviewRecordItems [i ].(* reviewRecord )
264
- if ! namespaceSet .Has (reviewRecord .namespace ) {
268
+ if ! newNamespaces .Has (reviewRecord .namespace ) {
265
269
deleteNamespaceFromSubjects (userSubjectRecordStore , reviewRecord .users , reviewRecord .namespace )
266
270
deleteNamespaceFromSubjects (groupSubjectRecordStore , reviewRecord .groups , reviewRecord .namespace )
267
271
reviewRecordStore .Delete (reviewRecord )
268
272
}
269
273
}
274
+
275
+ for namespace := range oldNamespaces .Difference (newNamespaces ) {
276
+ ac .notifyWatchers (namespace , nil , sets.String {}, sets.String {})
277
+ }
270
278
}
271
279
272
280
// invalidateCache returns true if there was a change in the cluster namespace that holds cluster policy and policy bindings
@@ -327,17 +335,18 @@ func (ac *AuthorizationCache) synchronize() {
327
335
}
328
336
329
337
// iterate over caches and synchronize our three caches
330
- namespaceSet := ac .synchronizeNamespaces (userSubjectRecordStore , groupSubjectRecordStore , reviewRecordStore )
338
+ newKnownNamespaces := ac .synchronizeNamespaces (userSubjectRecordStore , groupSubjectRecordStore , reviewRecordStore )
331
339
ac .synchronizePolicies (userSubjectRecordStore , groupSubjectRecordStore , reviewRecordStore )
332
340
ac .synchronizePolicyBindings (userSubjectRecordStore , groupSubjectRecordStore , reviewRecordStore )
333
- purgeDeletedNamespaces (namespaceSet , userSubjectRecordStore , groupSubjectRecordStore , reviewRecordStore )
341
+ ac . purgeDeletedNamespaces (ac . allKnownNamespaces , newKnownNamespaces , userSubjectRecordStore , groupSubjectRecordStore , reviewRecordStore )
334
342
335
343
// if we did a full rebuild, now we swap the fully rebuilt cache
336
344
if invalidateCache {
337
345
ac .userSubjectRecordStore = userSubjectRecordStore
338
346
ac .groupSubjectRecordStore = groupSubjectRecordStore
339
347
ac .reviewRecordStore = reviewRecordStore
340
348
}
349
+ ac .allKnownNamespaces = newKnownNamespaces
341
350
342
351
// we were able to update our cache since this last observation period
343
352
ac .lastState = currentState
@@ -486,24 +495,11 @@ func addSubjectsToNamespace(subjectRecordStore cache.Store, subjects []string, n
486
495
}
487
496
}
488
497
489
- func (ac * AuthorizationCache ) notifyWatchers (namespace string , exists * reviewRecord , latestUsers , latestGroups sets.String ) {
490
- existingGroups := sets.String {}
491
- existingUsers := sets.String {}
492
- if exists != nil {
493
- existingGroups = sets .NewString (exists .groups ... )
494
- existingUsers = sets .NewString (exists .users ... )
495
- }
496
-
497
- // calculate once to avoid fanning out.
498
- removedUsers := existingUsers .Difference (latestUsers )
499
- removedGroups := existingGroups .Difference (latestGroups )
500
- addedUsers := latestUsers .Difference (existingUsers )
501
- addedGroups := latestGroups .Difference (existingGroups )
502
-
498
+ func (ac * AuthorizationCache ) notifyWatchers (namespace string , exists * reviewRecord , users , groups sets.String ) {
503
499
ac .watcherLock .Lock ()
504
500
defer ac .watcherLock .Unlock ()
505
501
for _ , watcher := range ac .watchers {
506
- watcher .GroupMembershipChanged (namespace , latestUsers , latestGroups , removedUsers , removedGroups , addedUsers , addedGroups )
502
+ watcher .GroupMembershipChanged (namespace , users , groups )
507
503
}
508
504
}
509
505
0 commit comments