@@ -64,10 +64,15 @@ func Register(plugins *admission.Plugins) {
6464func NewKubeValidatingAdmissionPolicy () * KubeValidatingAdmissionPolicy {
6565 return & KubeValidatingAdmissionPolicy {
6666 Handler : admission .NewHandler (admission .Connect , admission .Create , admission .Delete , admission .Update ),
67- delegates : make (map [logicalcluster. Name ]* stoppableValidatingAdmissionPolicy ),
67+ delegates : make (map [delegateKey ]* stoppableValidatingAdmissionPolicy ),
6868 }
6969}
7070
71+ type delegateKey struct {
72+ policyCluster logicalcluster.Name
73+ targetCluster logicalcluster.Name
74+ }
75+
7176type KubeValidatingAdmissionPolicy struct {
7277 * admission.Handler
7378
@@ -83,7 +88,7 @@ type KubeValidatingAdmissionPolicy struct {
8388 getAPIBindings func (clusterName logicalcluster.Name ) ([]* apisv1alpha2.APIBinding , error )
8489
8590 delegatesLock sync.RWMutex
86- delegates map [logicalcluster. Name ]* stoppableValidatingAdmissionPolicy
91+ delegates map [delegateKey ]* stoppableValidatingAdmissionPolicy
8792
8893 logicalClusterDeletionMonitorStarter sync.Once
8994}
@@ -120,8 +125,9 @@ func (k *KubeValidatingAdmissionPolicy) SetKcpInformers(local, global kcpinforme
120125 k .delegatesLock .Lock ()
121126 defer k .delegatesLock .Unlock ()
122127
128+ // Remove all delegates that involve this cluster (either as policy or target)
123129 for key , delegate := range k .delegates {
124- if key == clName {
130+ if key . policyCluster == clName || key . targetCluster == clName {
125131 delete (k .delegates , key )
126132 delegate .stop ()
127133 }
@@ -168,7 +174,7 @@ func (k *KubeValidatingAdmissionPolicy) Validate(ctx context.Context, a admissio
168174 return err
169175 }
170176
171- delegate , err := k .getOrCreateDelegate (sourceCluster )
177+ delegate , err := k .getOrCreateDelegate (sourceCluster , cluster . Name )
172178 if err != nil {
173179 return err
174180 }
@@ -193,10 +199,16 @@ func (k *KubeValidatingAdmissionPolicy) getSourceClusterForGroupResource(cluster
193199 return clusterName , nil
194200}
195201
196- // getOrCreateDelegate creates an actual plugin for clusterName.
197- func (k * KubeValidatingAdmissionPolicy ) getOrCreateDelegate (clusterName logicalcluster.Name ) (* stoppableValidatingAdmissionPolicy , error ) {
202+ // getOrCreateDelegate creates an actual plugin for policyClusterName (where policies are defined).
203+ // targetClusterName is the cluster where the object being validated resides.
204+ func (k * KubeValidatingAdmissionPolicy ) getOrCreateDelegate (policyClusterName , targetClusterName logicalcluster.Name ) (* stoppableValidatingAdmissionPolicy , error ) {
205+ key := delegateKey {
206+ policyCluster : policyClusterName ,
207+ targetCluster : targetClusterName ,
208+ }
209+
198210 k .delegatesLock .RLock ()
199- delegate := k .delegates [clusterName ]
211+ delegate := k .delegates [key ]
200212 k .delegatesLock .RUnlock ()
201213
202214 if delegate != nil {
@@ -206,7 +218,7 @@ func (k *KubeValidatingAdmissionPolicy) getOrCreateDelegate(clusterName logicalc
206218 k .delegatesLock .Lock ()
207219 defer k .delegatesLock .Unlock ()
208220
209- delegate = k .delegates [clusterName ]
221+ delegate = k .delegates [key ]
210222 if delegate != nil {
211223 return delegate , nil
212224 }
@@ -229,29 +241,29 @@ func (k *KubeValidatingAdmissionPolicy) getOrCreateDelegate(clusterName logicalc
229241 stop : cancel ,
230242 }
231243
232- plugin .SetNamespaceInformer (k .localKubeSharedInformerFactory .Core ().V1 ().Namespaces ().Cluster (clusterName ))
233- plugin .SetExternalKubeClientSet (k .kubeClusterClient .Cluster (clusterName .Path ()))
244+ plugin .SetNamespaceInformer (k .localKubeSharedInformerFactory .Core ().V1 ().Namespaces ().Cluster (policyClusterName ))
245+ plugin .SetExternalKubeClientSet (k .kubeClusterClient .Cluster (policyClusterName .Path ()))
234246
235247 // TODO(ncdc): this is super inefficient to do per workspace
236- discoveryClient := memory .NewMemCacheClient (k .kubeClusterClient .Cluster (clusterName .Path ()).Discovery ())
248+ discoveryClient := memory .NewMemCacheClient (k .kubeClusterClient .Cluster (policyClusterName .Path ()).Discovery ())
237249 restMapper := restmapper .NewDeferredDiscoveryRESTMapper (discoveryClient )
238250 plugin .SetRESTMapper (restMapper )
239251
240- plugin .SetDynamicClient (k .dynamicClusterClient .Cluster (clusterName .Path ()))
252+ plugin .SetDynamicClient (k .dynamicClusterClient .Cluster (policyClusterName .Path ()))
241253 plugin .SetDrainedNotification (ctx .Done ())
242254 plugin .SetAuthorizer (k .authorizer )
243- plugin .SetClusterName (clusterName )
244- plugin .SetSourceFactory (func (_ informers.SharedInformerFactory , client kubernetes.Interface , dynamicClient dynamic.Interface , restMapper meta.RESTMapper , clusterName logicalcluster.Name ) generic.Source [validating.PolicyHook ] {
255+ plugin .SetClusterName (policyClusterName )
256+ plugin .SetSourceFactory (func (_ informers.SharedInformerFactory , client kubernetes.Interface , dynamicClient dynamic.Interface , restMapper meta.RESTMapper , cn logicalcluster.Name ) generic.Source [validating.PolicyHook ] {
245257 return generic .NewPolicySource (
246- k .globalKubeSharedInformerFactory .Admissionregistration ().V1 ().ValidatingAdmissionPolicies ().Informer ().Cluster (clusterName ),
247- k .globalKubeSharedInformerFactory .Admissionregistration ().V1 ().ValidatingAdmissionPolicyBindings ().Informer ().Cluster (clusterName ),
258+ k .globalKubeSharedInformerFactory .Admissionregistration ().V1 ().ValidatingAdmissionPolicies ().Informer ().Cluster (cn ),
259+ k .globalKubeSharedInformerFactory .Admissionregistration ().V1 ().ValidatingAdmissionPolicyBindings ().Informer ().Cluster (cn ),
248260 validating .NewValidatingAdmissionPolicyAccessor ,
249261 validating .NewValidatingAdmissionPolicyBindingAccessor ,
250262 validating .CompilePolicy ,
251263 nil ,
252264 dynamicClient ,
253265 restMapper ,
254- clusterName ,
266+ cn ,
255267 )
256268 })
257269
@@ -260,7 +272,7 @@ func (k *KubeValidatingAdmissionPolicy) getOrCreateDelegate(clusterName logicalc
260272 return nil , err
261273 }
262274
263- k .delegates [clusterName ] = delegate
275+ k .delegates [key ] = delegate
264276
265277 return delegate , nil
266278}
@@ -269,19 +281,22 @@ func (k *KubeValidatingAdmissionPolicy) logicalClusterDeleted(clusterName logica
269281 k .delegatesLock .Lock ()
270282 defer k .delegatesLock .Unlock ()
271283
272- delegate := k .delegates [clusterName ]
273-
274284 logger := klog .Background ().WithValues ("clusterName" , clusterName )
275285
276- if delegate == nil {
277- logger .V (3 ).Info ("received event to stop validating admission policy for logical cluster, but it wasn't in the map" )
278- return
286+ // Remove all delegates that involve this cluster (either as policy or target)
287+ found := false
288+ for key , delegate := range k .delegates {
289+ if key .policyCluster == clusterName || key .targetCluster == clusterName {
290+ logger .V (2 ).Info ("stopping validating admission policy for logical cluster" )
291+ delete (k .delegates , key )
292+ delegate .stop ()
293+ found = true
294+ }
279295 }
280296
281- logger .V (2 ).Info ("stopping validating admission policy for logical cluster" )
282-
283- delete (k .delegates , clusterName )
284- delegate .stop ()
297+ if ! found {
298+ logger .V (3 ).Info ("received event to stop validating admission policy for logical cluster, but it wasn't in the map" )
299+ }
285300}
286301
287302type stoppableValidatingAdmissionPolicy struct {
0 commit comments