@@ -24,6 +24,9 @@ import (
24
24
"time"
25
25
26
26
"k8s.io/client-go/kubernetes"
27
+ "sigs.k8s.io/controller-runtime/pkg/client/apiutil"
28
+ "sigs.k8s.io/controller-runtime/pkg/event"
29
+ "sigs.k8s.io/controller-runtime/pkg/predicate"
27
30
28
31
"sigs.k8s.io/controller-runtime/pkg/manager"
29
32
@@ -38,7 +41,6 @@ import (
38
41
39
42
ctrl "sigs.k8s.io/controller-runtime"
40
43
"sigs.k8s.io/controller-runtime/pkg/client"
41
- "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
42
44
43
45
corev1 "k8s.io/api/core/v1"
44
46
v1 "k8s.io/api/core/v1"
@@ -52,7 +54,8 @@ import (
52
54
)
53
55
54
56
const (
55
- secretManagedLabel = "secrets-store.csi.k8s.io/managed"
57
+ SecretManagedLabel = "secrets-store.csi.k8s.io/managed"
58
+ SecretUsedLabel = "secrets-store.csi.k8s.io/used"
56
59
secretCreationFailedReason = "FailedToCreateSecret"
57
60
)
58
61
@@ -108,7 +111,7 @@ func (r *SecretProviderClassPodStatusReconciler) Patcher(ctx context.Context) er
108
111
109
112
spcPodStatusList := & v1alpha1.SecretProviderClassPodStatusList {}
110
113
spcMap := make (map [string ]v1alpha1.SecretProviderClass )
111
- secretOwnerMap := make (map [types.NamespacedName ][]* v1alpha1. SecretProviderClassPodStatus )
114
+ secretOwnerMap := make (map [types.NamespacedName ][]metav1. OwnerReference )
112
115
// get a list of all spc pod status that belong to the node
113
116
err := r .reader .List (ctx , spcPodStatusList , r .ListOptionsLabelSelector ())
114
117
if err != nil {
@@ -119,21 +122,56 @@ func (r *SecretProviderClassPodStatusReconciler) Patcher(ctx context.Context) er
119
122
for i := range spcPodStatuses {
120
123
spcName := spcPodStatuses [i ].Status .SecretProviderClassName
121
124
spc := & v1alpha1.SecretProviderClass {}
122
- if val , exists := spcMap [spcPodStatuses [i ].Namespace + "/" + spcName ]; exists {
125
+ namespace := spcPodStatuses [i ].Namespace
126
+
127
+ if val , exists := spcMap [namespace + "/" + spcName ]; exists {
123
128
spc = & val
124
129
} else {
125
- if err := r .reader .Get (ctx , client.ObjectKey {Namespace : spcPodStatuses [ i ]. Namespace , Name : spcName }, spc ); err != nil {
130
+ if err := r .reader .Get (ctx , client.ObjectKey {Namespace : namespace , Name : spcName }, spc ); err != nil {
126
131
return fmt .Errorf ("failed to get spc %s, err: %+v" , spcName , err )
127
132
}
128
- spcMap [spcPodStatuses [i ].Namespace + "/" + spcName ] = * spc
133
+ spcMap [namespace + "/" + spcName ] = * spc
134
+ }
135
+ // get the pod and check if the pod has a owner reference
136
+ pod := & v1.Pod {}
137
+ err = r .reader .Get (ctx , client.ObjectKey {Namespace : namespace , Name : spcPodStatuses [i ].Status .PodName }, pod )
138
+ if err != nil {
139
+ return fmt .Errorf ("failed to fetch pod during patching, err: %+v" , err )
129
140
}
141
+ var ownerRefs []metav1.OwnerReference
142
+ for _ , ownerRef := range pod .GetOwnerReferences () {
143
+ ownerRefs = append (ownerRefs , metav1.OwnerReference {
144
+ APIVersion : ownerRef .APIVersion ,
145
+ Kind : ownerRef .Kind ,
146
+ UID : ownerRef .UID ,
147
+ Name : ownerRef .Name ,
148
+ })
149
+ }
150
+ // If a pod has no owner references, then it's a static pod and
151
+ // doesn't belong to a replicaset. In this case, use the spcps as
152
+ // owner reference just like we do it today
153
+ if len (ownerRefs ) == 0 {
154
+ // Create a new owner ref.
155
+ gvk , err := apiutil .GVKForObject (& spcPodStatuses [i ], r .scheme )
156
+ if err != nil {
157
+ return err
158
+ }
159
+ ref := metav1.OwnerReference {
160
+ APIVersion : gvk .GroupVersion ().String (),
161
+ Kind : gvk .Kind ,
162
+ UID : spcPodStatuses [i ].GetUID (),
163
+ Name : spcPodStatuses [i ].GetName (),
164
+ }
165
+ ownerRefs = append (ownerRefs , ref )
166
+ }
167
+
130
168
for _ , secret := range spc .Spec .SecretObjects {
131
- key := types.NamespacedName {Name : secret .SecretName , Namespace : spcPodStatuses [ i ]. Namespace }
169
+ key := types.NamespacedName {Name : secret .SecretName , Namespace : namespace }
132
170
val , exists := secretOwnerMap [key ]
133
171
if exists {
134
- secretOwnerMap [key ] = append (val , & spcPodStatuses [ i ] )
172
+ secretOwnerMap [key ] = append (val , ownerRefs ... )
135
173
} else {
136
- secretOwnerMap [key ] = [] * v1alpha1. SecretProviderClassPodStatus { & spcPodStatuses [ i ]}
174
+ secretOwnerMap [key ] = ownerRefs
137
175
}
138
176
}
139
177
}
@@ -191,22 +229,6 @@ func (r *SecretProviderClassPodStatusReconciler) Reconcile(ctx context.Context,
191
229
return ctrl.Result {}, err
192
230
}
193
231
194
- // reconcile delete
195
- if ! spcPodStatus .GetDeletionTimestamp ().IsZero () {
196
- klog .InfoS ("reconcile complete" , "spcps" , req .NamespacedName .String ())
197
- return ctrl.Result {}, nil
198
- }
199
-
200
- node , ok := spcPodStatus .GetLabels ()[v1alpha1 .InternalNodeLabel ]
201
- if ! ok {
202
- klog .V (3 ).InfoS ("node label not found, ignoring this spc pod status" , "spcps" , klog .KObj (spcPodStatus ))
203
- return ctrl.Result {}, nil
204
- }
205
- if ! strings .EqualFold (node , r .nodeID ) {
206
- klog .V (3 ).InfoS ("ignoring as spc pod status belongs diff node" , "node" , node , "spcps" , klog .KObj (spcPodStatus ))
207
- return ctrl.Result {}, nil
208
- }
209
-
210
232
// Obtain the full pod metadata. An object reference is needed for sending
211
233
// events and the UID is helpful for validating the SPCPS TargetPath.
212
234
pod := & v1.Pod {}
@@ -296,7 +318,7 @@ func (r *SecretProviderClassPodStatusReconciler) Reconcile(ctx context.Context,
296
318
// Set secrets-store.csi.k8s.io/managed=true label on the secret that's created and managed
297
319
// by the secrets-store-csi-driver. This label will be used to perform a filtered list watch
298
320
// only on secrets created and managed by the driver
299
- labelsMap [secretManagedLabel ] = "true"
321
+ labelsMap [SecretManagedLabel ] = "true"
300
322
301
323
createFn := func () (bool , error ) {
302
324
if err := r .createK8sSecret (ctx , secretName , req .Namespace , datamap , labelsMap , secretType ); err != nil {
@@ -335,9 +357,41 @@ func (r *SecretProviderClassPodStatusReconciler) Reconcile(ctx context.Context,
335
357
func (r * SecretProviderClassPodStatusReconciler ) SetupWithManager (mgr ctrl.Manager ) error {
336
358
return ctrl .NewControllerManagedBy (mgr ).
337
359
For (& v1alpha1.SecretProviderClassPodStatus {}).
360
+ WithEventFilter (r .belongsToNodePredicate ()).
338
361
Complete (r )
339
362
}
340
363
364
+ // belongsToNodePredicate defines predicates for handlers
365
+ func (r * SecretProviderClassPodStatusReconciler ) belongsToNodePredicate () predicate.Funcs {
366
+ return predicate.Funcs {
367
+ UpdateFunc : func (e event.UpdateEvent ) bool {
368
+ return r .processIfBelongsToNode (e .ObjectNew )
369
+ },
370
+ CreateFunc : func (e event.CreateEvent ) bool {
371
+ return r .processIfBelongsToNode (e .Object )
372
+ },
373
+ DeleteFunc : func (e event.DeleteEvent ) bool {
374
+ return false
375
+ },
376
+ GenericFunc : func (e event.GenericEvent ) bool {
377
+ return r .processIfBelongsToNode (e .Object )
378
+ },
379
+ }
380
+ }
381
+
382
+ // processIfBelongsToNode determines if the secretproviderclasspodstatus belongs to the node based on the
383
+ // internal.secrets-store.csi.k8s.io/node-name: <node name> label. If belongs to node, then the spcps is processed.
384
+ func (r * SecretProviderClassPodStatusReconciler ) processIfBelongsToNode (objMeta metav1.Object ) bool {
385
+ node , ok := objMeta .GetLabels ()[v1alpha1 .InternalNodeLabel ]
386
+ if ! ok {
387
+ return false
388
+ }
389
+ if ! strings .EqualFold (node , r .nodeID ) {
390
+ return false
391
+ }
392
+ return true
393
+ }
394
+
341
395
// createK8sSecret creates K8s secret with data from mounted files
342
396
// If a secret with the same name already exists in the namespace of the pod, the error is nil.
343
397
func (r * SecretProviderClassPodStatusReconciler ) createK8sSecret (ctx context.Context , name , namespace string , datamap map [string ][]byte , labelsmap map [string ]string , secretType corev1.SecretType ) error {
@@ -363,7 +417,7 @@ func (r *SecretProviderClassPodStatusReconciler) createK8sSecret(ctx context.Con
363
417
}
364
418
365
419
// patchSecretWithOwnerRef patches the secret owner reference with the spc pod status
366
- func (r * SecretProviderClassPodStatusReconciler ) patchSecretWithOwnerRef (ctx context.Context , name , namespace string , spcPodStatus ... * v1alpha1. SecretProviderClassPodStatus ) error {
420
+ func (r * SecretProviderClassPodStatusReconciler ) patchSecretWithOwnerRef (ctx context.Context , name , namespace string , ownerRefs ... metav1. OwnerReference ) error {
367
421
secret := & corev1.Secret {}
368
422
secretKey := types.NamespacedName {
369
423
Namespace : namespace ,
@@ -380,23 +434,23 @@ func (r *SecretProviderClassPodStatusReconciler) patchSecretWithOwnerRef(ctx con
380
434
patch := client .MergeFromWithOptions (secret .DeepCopy (), client.MergeFromWithOptimisticLock {})
381
435
needsPatch := false
382
436
437
+ secretOwnerRefs := secret .GetOwnerReferences ()
383
438
secretOwnerMap := make (map [string ]types.UID )
384
- for _ , or := range secret . GetOwnerReferences () {
439
+ for _ , or := range secretOwnerRefs {
385
440
secretOwnerMap [or .Name ] = or .UID
386
441
}
387
442
388
- for i := range spcPodStatus {
389
- if _ , exists := secretOwnerMap [spcPodStatus [i ].Name ]; exists {
443
+ for i := range ownerRefs {
444
+ if _ , exists := secretOwnerMap [ownerRefs [i ].Name ]; exists {
390
445
continue
391
446
}
392
447
needsPatch = true
393
- err := controllerutil .SetOwnerReference (spcPodStatus [i ], secret , r .scheme )
394
- if err != nil {
395
- return err
396
- }
448
+ klog .Infof ("Adding %s/%s as owner ref for %s/%s" , ownerRefs [i ].APIVersion , ownerRefs [i ].Name , namespace , name )
449
+ secretOwnerRefs = append (secretOwnerRefs , ownerRefs [i ])
397
450
}
398
451
399
452
if needsPatch {
453
+ secret .SetOwnerReferences (secretOwnerRefs )
400
454
return r .writer .Patch (ctx , secret , patch )
401
455
}
402
456
return nil
0 commit comments