@@ -232,11 +232,11 @@ func (r *ReconciliationRunner) CheckOwnedCRDsForReadiness(gvks ...schema.GroupVe
232
232
} else if ! found {
233
233
return r .RequeueWithMessage (
234
234
fmt .Sprintf (
235
- "Owned object of kind %s with name %s not found, requeueing ." ,
235
+ "Owned object of kind %s with name %s not found, requeuing ." ,
236
236
gvk .Kind ,
237
237
owned .GetName ()))
238
238
} else {
239
- r .Log .Info (fmt .Sprintf ("Owned object %s of kind %s not ready, requeueing " , name , gvk .Kind ))
239
+ r .Log .Info (fmt .Sprintf ("Owned object %s of kind %s not ready, requeuing " , name , gvk .Kind ))
240
240
return ctrl.Result {RequeueAfter : RequeueTimeout }, nil
241
241
}
242
242
}
@@ -246,6 +246,66 @@ func (r *ReconciliationRunner) CheckOwnedCRDsForReadiness(gvks ...schema.GroupVe
246
246
}
247
247
}
248
248
249
+ // CheckOwnedObjectsDeleted queries for the presence of owned objects and requeues if any are still present. Primarily
250
+ // used to prevent deletions of owners before dependents.
251
+ func (r * ReconciliationRunner ) DeleteOwnedObjects (gvks ... schema.GroupVersionKind ) CloudStackReconcilerMethod {
252
+ return func () (ctrl.Result , error ) {
253
+ // For each GroupVersionKind...
254
+ for _ , gvk := range gvks {
255
+ // Query to find objects of this kind.
256
+ potentiallyOnwedObjs := & unstructured.UnstructuredList {}
257
+ potentiallyOnwedObjs .SetGroupVersionKind (gvk )
258
+ err := r .K8sClient .List (r .RequestCtx , potentiallyOnwedObjs )
259
+ if err != nil {
260
+ return ctrl.Result {}, errors .Wrapf (err , "requesting owned objects with gvk %s" , gvk )
261
+ }
262
+
263
+ // Filter objects not actually owned by reconciliation subject via owner reference UID.
264
+ for _ , pOwned := range potentiallyOnwedObjs .Items {
265
+ _pOwned := pOwned
266
+ refs := pOwned .GetOwnerReferences ()
267
+ for _ , ref := range refs {
268
+ if ref .UID == r .ReconciliationSubject .GetUID () {
269
+ if err := r .K8sClient .Delete (r .RequestCtx , & _pOwned ); err != nil {
270
+ return ctrl.Result {}, err
271
+ }
272
+ }
273
+ }
274
+ }
275
+ }
276
+ return ctrl.Result {}, nil
277
+ }
278
+ }
279
+
280
+ // CheckOwnedObjectsDeleted queries for the presence of owned objects and requeues if any are still present. Primarily
281
+ // used to prevent deletions of owners before dependents.
282
+ func (r * ReconciliationRunner ) CheckOwnedObjectsDeleted (gvks ... schema.GroupVersionKind ) CloudStackReconcilerMethod {
283
+ return func () (ctrl.Result , error ) {
284
+ // For each GroupVersionKind...
285
+ for _ , gvk := range gvks {
286
+ // Query to find objects of this kind.
287
+ potentiallyOnwedObjs := & unstructured.UnstructuredList {}
288
+ potentiallyOnwedObjs .SetGroupVersionKind (gvk )
289
+ err := r .K8sClient .List (r .RequestCtx , potentiallyOnwedObjs )
290
+ if err != nil {
291
+ return ctrl.Result {}, errors .Wrapf (err , "requesting owned objects with gvk %s" , gvk )
292
+ }
293
+
294
+ // Filter objects not actually owned by reconciliation subject via owner reference UID.
295
+ for _ , pOwned := range potentiallyOnwedObjs .Items {
296
+ refs := pOwned .GetOwnerReferences ()
297
+ for _ , ref := range refs {
298
+ if ref .UID == r .ReconciliationSubject .GetUID () {
299
+ return r .RequeueWithMessage (
300
+ fmt .Sprintf ("Owned object %s of kind %s not yet deleted" , pOwned .GetKind (), pOwned .GetName ()))
301
+ }
302
+ }
303
+ }
304
+ }
305
+ return ctrl.Result {}, nil
306
+ }
307
+ }
308
+
249
309
// RequeueIfCloudStackClusterNotReady requeues the reconciliation request if the CloudStackCluster is not ready.
250
310
func (r * ReconciliationRunner ) RequeueIfCloudStackClusterNotReady () (ctrl.Result , error ) {
251
311
if ! r .CSCluster .Status .Ready {
@@ -272,9 +332,9 @@ func (r *ReconciliationRunner) PatchChangesBackToAPI() (res ctrl.Result, retErr
272
332
273
333
// RequeueWithMessage is a convenience method to log requeue message and then return a result with RequeueAfter set.
274
334
func (r * ReconciliationRunner ) RequeueWithMessage (msg string , keysAndValues ... interface {}) (ctrl.Result , error ) {
275
- // Add requeueing to message if not present. Might turn this into a lint check later.
276
- if ! strings .Contains (strings .ToLower (msg ), "requeue " ) {
277
- msg = msg + " Requeueing ."
335
+ // Add requeuing to message if not present. Might turn this into a lint check later.
336
+ if ! strings .Contains (strings .ToLower (msg ), "requeu " ) {
337
+ msg = msg + " Requeuing ."
278
338
}
279
339
r .Log .Info (msg , keysAndValues ... )
280
340
return ctrl.Result {RequeueAfter : RequeueTimeout }, nil
@@ -284,7 +344,7 @@ func (r *ReconciliationRunner) RequeueWithMessage(msg string, keysAndValues ...i
284
344
func (r * ReconciliationRunner ) RequeueWithMessageStage (msg string , keysAndValues ... interface {}) CloudStackReconcilerMethod {
285
345
return func () (ctrl.Result , error ) {
286
346
if ! strings .Contains (strings .ToLower (msg ), "requeue" ) {
287
- msg = msg + " Requeueing ."
347
+ msg = msg + " Requeuing ."
288
348
}
289
349
r .Log .Info (msg , keysAndValues ... )
290
350
return ctrl.Result {RequeueAfter : RequeueTimeout }, nil
@@ -381,6 +441,7 @@ func (r *ReconciliationRunner) GetReconciliationSubject() (res ctrl.Result, rete
381
441
r .Log .V (1 ).Info ("Getting reconciliation subject." )
382
442
err := client .IgnoreNotFound (r .K8sClient .Get (r .RequestCtx , r .Request .NamespacedName , r .ReconciliationSubject ))
383
443
if r .ReconciliationSubject .GetName () == "" { // Resource does not exist. No need to reconcile.
444
+ r .Log .V (1 ).Info ("Resource not found. Exiting reconciliation." )
384
445
r .SetReturnEarly ()
385
446
}
386
447
if err != nil {
@@ -428,7 +489,7 @@ func (r *ReconciliationRunner) NewChildObjectMeta(name string) metav1.ObjectMeta
428
489
Name : strings .ToLower (name ),
429
490
Namespace : r .Request .Namespace ,
430
491
Labels : map [string ]string {clusterv1 .ClusterLabelName : r .CAPICluster .Name ,
431
- infrav1 .CloudStackClusterLabelName : r .CSCluster .ClusterName },
492
+ infrav1 .CloudStackClusterLabelName : r .CSCluster .Name },
432
493
OwnerReferences : []metav1.OwnerReference {
433
494
* metav1 .NewControllerRef (r .ReconciliationSubject , ownerGVK ),
434
495
},
@@ -438,11 +499,11 @@ func (r *ReconciliationRunner) NewChildObjectMeta(name string) metav1.ObjectMeta
438
499
// RequeueIfMissingBaseCRs checks that the ReconciliationSubject, CAPI Cluster, and CloudStackCluster objects were
439
500
// actually fetched and reques if not. The base reconciliation stages will continue even if not so as to allow deletion.
440
501
func (r * ReconciliationRunner ) RequeueIfMissingBaseCRs () (ctrl.Result , error ) {
441
- r .Log .V (1 ).Info ("Requeueing if missing ReconciliationSubject, CloudStack cluster, or CAPI cluster." )
502
+ r .Log .V (1 ).Info ("Requeuing if missing ReconciliationSubject, CloudStack cluster, or CAPI cluster." )
442
503
if r .CSCluster .GetName () == "" {
443
- return r .RequeueWithMessage ("CloudStackCluster wasn't found. Requeueing ." )
504
+ return r .RequeueWithMessage ("CloudStackCluster wasn't found. Requeuing ." )
444
505
} else if r .CAPICluster .GetName () == "" {
445
- return r .RequeueWithMessage ("CAPI Cluster wasn't found. Requeueing ." )
506
+ return r .RequeueWithMessage ("CAPI Cluster wasn't found. Requeuing ." )
446
507
}
447
508
return ctrl.Result {}, nil
448
509
}
0 commit comments