@@ -196,6 +196,11 @@ func (r *Reconciler) Reconcile(ctx context.Context, req ctrl.Request) (_ ctrl.Re
196
196
}
197
197
198
198
// Initialize the patch helper
199
+ s := & scope {
200
+ cluster : cluster ,
201
+ machine : m ,
202
+ }
203
+
199
204
patchHelper , err := patch .NewHelper (m , r .Client )
200
205
if err != nil {
201
206
return ctrl.Result {}, err
@@ -215,15 +220,34 @@ func (r *Reconciler) Reconcile(ctx context.Context, req ctrl.Request) (_ ctrl.Re
215
220
}
216
221
}()
217
222
218
- // Reconcile labels.
223
+ // Always add the cluster label labels.
219
224
if m .Labels == nil {
220
225
m .Labels = make (map [string ]string )
221
226
}
222
227
m .Labels [clusterv1 .ClusterNameLabel ] = m .Spec .ClusterName
223
228
229
+ // Add finalizer first if not set to avoid the race condition between init and delete.
230
+ // Note: Finalizers in general can only be added when the deletionTimestamp is not set.
231
+ if ! controllerutil .ContainsFinalizer (m , clusterv1 .MachineFinalizer ) && m .ObjectMeta .DeletionTimestamp .IsZero () {
232
+ controllerutil .AddFinalizer (m , clusterv1 .MachineFinalizer )
233
+ return ctrl.Result {}, nil
234
+ }
235
+
236
+ alwaysReconcile := []machineReconcileFunc {
237
+ r .reconcileBootstrap ,
238
+ r .reconcileInfrastructure ,
239
+ r .reconcileNode ,
240
+ r .reconcileCertificateExpiry ,
241
+ }
242
+
224
243
// Handle deletion reconciliation loop.
225
244
if ! m .ObjectMeta .DeletionTimestamp .IsZero () {
226
- res , err := r .reconcileDelete (ctx , cluster , m )
245
+ reconcileDelete := append (
246
+ alwaysReconcile ,
247
+ r .reconcileDelete ,
248
+ )
249
+
250
+ res , err := doReconcile (ctx , reconcileDelete , s )
227
251
// Requeue if the reconcile failed because the ClusterCacheTracker was locked for
228
252
// the current cluster because of concurrent access.
229
253
if errors .Is (err , remote .ErrClusterLocked ) {
@@ -233,15 +257,13 @@ func (r *Reconciler) Reconcile(ctx context.Context, req ctrl.Request) (_ ctrl.Re
233
257
return res , err
234
258
}
235
259
236
- // Add finalizer first if not set to avoid the race condition between init and delete.
237
- // Note: Finalizers in general can only be added when the deletionTimestamp is not set.
238
- if ! controllerutil .ContainsFinalizer (m , clusterv1 .MachineFinalizer ) {
239
- controllerutil .AddFinalizer (m , clusterv1 .MachineFinalizer )
240
- return ctrl.Result {}, nil
241
- }
242
-
243
260
// Handle normal reconciliation loop.
244
- res , err := r .reconcile (ctx , cluster , m )
261
+ reconcileNormal := append (
262
+ []machineReconcileFunc {r .reconcileMachineOwner },
263
+ alwaysReconcile ... ,
264
+ )
265
+
266
+ res , err := doReconcile (ctx , reconcileNormal , s )
245
267
// Requeue if the reconcile failed because the ClusterCacheTracker was locked for
246
268
// the current cluster because of concurrent access.
247
269
if errors .Is (err , remote .ErrClusterLocked ) {
@@ -285,36 +307,26 @@ func patchMachine(ctx context.Context, patchHelper *patch.Helper, machine *clust
285
307
clusterv1 .MachineHealthCheckSucceededCondition ,
286
308
clusterv1 .MachineOwnerRemediatedCondition ,
287
309
}},
310
+ patch.WithOwnedV1Beta2Conditions {Conditions : []string {
311
+ clusterv1 .MachineAvailableV1Beta2Condition ,
312
+ clusterv1 .MachineReadyV1Beta2Condition ,
313
+ clusterv1 .MachineBootstrapConfigReadyV1Beta2Condition ,
314
+ clusterv1 .MachineInfrastructureReadyV1Beta2Condition ,
315
+ clusterv1 .MachineNodeReadyV1Beta2Condition ,
316
+ clusterv1 .MachineNodeHealthyV1Beta2Condition ,
317
+ clusterv1 .MachineDeletingV1Beta2Condition ,
318
+ clusterv1 .MachinePausedV1Beta2Condition ,
319
+ }},
288
320
)
289
321
290
322
return patchHelper .Patch (ctx , machine , options ... )
291
323
}
292
324
293
- func (r * Reconciler ) reconcile (ctx context.Context , cluster * clusterv1.Cluster , m * clusterv1.Machine ) (ctrl.Result , error ) {
294
- // If the machine is a stand-alone one, meaning not originated from a MachineDeployment, then set it as directly
295
- // owned by the Cluster (if not already present).
296
- if r .shouldAdopt (m ) {
297
- m .SetOwnerReferences (util .EnsureOwnerRef (m .GetOwnerReferences (), metav1.OwnerReference {
298
- APIVersion : clusterv1 .GroupVersion .String (),
299
- Kind : "Cluster" ,
300
- Name : cluster .Name ,
301
- UID : cluster .UID ,
302
- }))
303
- }
304
-
305
- phases := []func (context.Context , * scope ) (ctrl.Result , error ){
306
- r .reconcileBootstrap ,
307
- r .reconcileInfrastructure ,
308
- r .reconcileNode ,
309
- r .reconcileCertificateExpiry ,
310
- }
325
+ type machineReconcileFunc func (context.Context , * scope ) (ctrl.Result , error )
311
326
327
+ func doReconcile (ctx context.Context , phases []machineReconcileFunc , s * scope ) (ctrl.Result , error ) {
312
328
res := ctrl.Result {}
313
329
errs := []error {}
314
- s := & scope {
315
- cluster : cluster ,
316
- machine : m ,
317
- }
318
330
for _ , phase := range phases {
319
331
// Call the inner reconciliation methods.
320
332
phaseResult , err := phase (ctx , s )
@@ -346,10 +358,30 @@ type scope struct {
346
358
// bootstrapConfig is the BootstrapConfig object that is referenced by the
347
359
// Machine. It is set after reconcileBootstrap is called.
348
360
bootstrapConfig * unstructured.Unstructured
361
+
362
+ // node is the Kubernetes node hosted on the machine.
363
+ node * corev1.Node
364
+ }
365
+
366
+ func (r * Reconciler ) reconcileMachineOwner (_ context.Context , s * scope ) (ctrl.Result , error ) {
367
+ // If the machine is a stand-alone one, meaning not originated from a MachineDeployment, then set it as directly
368
+ // owned by the Cluster (if not already present).
369
+ if r .shouldAdopt (s .machine ) {
370
+ s .machine .SetOwnerReferences (util .EnsureOwnerRef (s .machine .GetOwnerReferences (), metav1.OwnerReference {
371
+ APIVersion : clusterv1 .GroupVersion .String (),
372
+ Kind : "Cluster" ,
373
+ Name : s .cluster .Name ,
374
+ UID : s .cluster .UID ,
375
+ }))
376
+ }
377
+
378
+ return ctrl.Result {}, nil
349
379
}
350
380
351
- func (r * Reconciler ) reconcileDelete (ctx context.Context , cluster * clusterv1. Cluster , m * clusterv1. Machine ) (ctrl.Result , error ) { //nolint:gocyclo
381
+ func (r * Reconciler ) reconcileDelete (ctx context.Context , s * scope ) (ctrl.Result , error ) { //nolint:gocyclo
352
382
log := ctrl .LoggerFrom (ctx )
383
+ cluster := s .cluster
384
+ m := s .machine
353
385
354
386
err := r .isDeleteNodeAllowed (ctx , cluster , m )
355
387
isDeleteNodeAllowed := err == nil
@@ -463,20 +495,7 @@ func (r *Reconciler) reconcileDelete(ctx context.Context, cluster *clusterv1.Clu
463
495
}
464
496
conditions .MarkTrue (m , clusterv1 .PreTerminateDeleteHookSucceededCondition )
465
497
466
- // Return early and don't remove the finalizer if we got an error or
467
- // the external reconciliation deletion isn't ready.
468
-
469
- patchHelper , err := patch .NewHelper (m , r .Client )
470
- if err != nil {
471
- return ctrl.Result {}, err
472
- }
473
- conditions .MarkFalse (m , clusterv1 .MachineNodeHealthyCondition , clusterv1 .DeletingReason , clusterv1 .ConditionSeverityInfo , "" )
474
- if err := patchMachine (ctx , patchHelper , m ); err != nil {
475
- conditions .MarkFalse (m , clusterv1 .MachineNodeHealthyCondition , clusterv1 .DeletionFailedReason , clusterv1 .ConditionSeverityInfo , "" )
476
- return ctrl.Result {}, errors .Wrap (err , "failed to patch Machine" )
477
- }
478
-
479
- infrastructureDeleted , err := r .reconcileDeleteInfrastructure (ctx , cluster , m )
498
+ infrastructureDeleted , err := r .reconcileDeleteInfrastructure (ctx , s )
480
499
if err != nil {
481
500
return ctrl.Result {}, err
482
501
}
@@ -485,7 +504,7 @@ func (r *Reconciler) reconcileDelete(ctx context.Context, cluster *clusterv1.Clu
485
504
return ctrl.Result {}, nil
486
505
}
487
506
488
- bootstrapDeleted , err := r .reconcileDeleteBootstrap (ctx , cluster , m )
507
+ bootstrapDeleted , err := r .reconcileDeleteBootstrap (ctx , s )
489
508
if err != nil {
490
509
return ctrl.Result {}, err
491
510
}
@@ -849,78 +868,34 @@ func (r *Reconciler) deleteNode(ctx context.Context, cluster *clusterv1.Cluster,
849
868
return nil
850
869
}
851
870
852
- func (r * Reconciler ) reconcileDeleteBootstrap (ctx context.Context , cluster * clusterv1.Cluster , m * clusterv1.Machine ) (bool , error ) {
853
- obj , err := r .reconcileDeleteExternal (ctx , cluster , m , m .Spec .Bootstrap .ConfigRef )
854
- if err != nil {
855
- return false , err
856
- }
857
-
858
- if obj == nil {
859
- // Marks the bootstrap as deleted
860
- conditions .MarkFalse (m , clusterv1 .BootstrapReadyCondition , clusterv1 .DeletedReason , clusterv1 .ConditionSeverityInfo , "" )
871
+ func (r * Reconciler ) reconcileDeleteBootstrap (ctx context.Context , s * scope ) (bool , error ) {
872
+ if s .bootstrapConfig == nil {
873
+ conditions .MarkFalse (s .machine , clusterv1 .BootstrapReadyCondition , clusterv1 .DeletedReason , clusterv1 .ConditionSeverityInfo , "" )
861
874
return true , nil
862
875
}
863
876
864
- // Report a summary of current status of the bootstrap object defined for this machine.
865
- conditions .SetMirror (m , clusterv1 .BootstrapReadyCondition ,
866
- conditions .UnstructuredGetter (obj ),
867
- conditions .WithFallbackValue (false , clusterv1 .DeletingReason , clusterv1 .ConditionSeverityInfo , "" ),
868
- )
869
- return false , nil
870
- }
871
-
872
- func (r * Reconciler ) reconcileDeleteInfrastructure (ctx context.Context , cluster * clusterv1.Cluster , m * clusterv1.Machine ) (bool , error ) {
873
- obj , err := r .reconcileDeleteExternal (ctx , cluster , m , & m .Spec .InfrastructureRef )
874
- if err != nil {
875
- return false , err
876
- }
877
-
878
- if obj == nil {
879
- // Marks the infrastructure as deleted
880
- conditions .MarkFalse (m , clusterv1 .InfrastructureReadyCondition , clusterv1 .DeletedReason , clusterv1 .ConditionSeverityInfo , "" )
881
- return true , nil
877
+ if err := r .Client .Delete (ctx , s .bootstrapConfig ); err != nil && ! apierrors .IsNotFound (err ) {
878
+ return false , errors .Wrapf (err ,
879
+ "failed to delete %v %q for Machine %q in namespace %q" ,
880
+ s .bootstrapConfig .GroupVersionKind (), s .bootstrapConfig .GetName (), s .machine .Name , s .machine .Namespace )
882
881
}
883
882
884
- // Report a summary of current status of the bootstrap object defined for this machine.
885
- conditions .SetMirror (m , clusterv1 .InfrastructureReadyCondition ,
886
- conditions .UnstructuredGetter (obj ),
887
- conditions .WithFallbackValue (false , clusterv1 .DeletingReason , clusterv1 .ConditionSeverityInfo , "" ),
888
- )
889
883
return false , nil
890
884
}
891
885
892
- // reconcileDeleteExternal tries to delete external references.
893
- func (r * Reconciler ) reconcileDeleteExternal (ctx context.Context , cluster * clusterv1.Cluster , m * clusterv1.Machine , ref * corev1.ObjectReference ) (* unstructured.Unstructured , error ) {
894
- if ref == nil {
895
- return nil , nil
896
- }
897
-
898
- // get the external object
899
- obj , err := external .Get (ctx , r .Client , ref , m .Namespace )
900
- if err != nil && ! apierrors .IsNotFound (errors .Cause (err )) {
901
- return nil , errors .Wrapf (err , "failed to get %s %q for Machine %q in namespace %q" ,
902
- ref .GroupVersionKind (), ref .Name , m .Name , m .Namespace )
886
+ func (r * Reconciler ) reconcileDeleteInfrastructure (ctx context.Context , s * scope ) (bool , error ) {
887
+ if s .infraMachine == nil {
888
+ conditions .MarkFalse (s .machine , clusterv1 .InfrastructureReadyCondition , clusterv1 .DeletedReason , clusterv1 .ConditionSeverityInfo , "" )
889
+ return true , nil
903
890
}
904
891
905
- if obj != nil {
906
- // reconcileExternal ensures that we set the object's OwnerReferences correctly and watch the object.
907
- // The machine delete logic depends on reconciling the machine when the external objects are deleted.
908
- // This avoids a race condition where the machine is deleted before the external objects are ever reconciled
909
- // by this controller.
910
- if _ , err := r .ensureExternalOwnershipAndWatch (ctx , cluster , m , ref ); err != nil {
911
- return nil , err
912
- }
913
-
914
- // Issue a delete request.
915
- if err := r .Client .Delete (ctx , obj ); err != nil && ! apierrors .IsNotFound (err ) {
916
- return obj , errors .Wrapf (err ,
917
- "failed to delete %v %q for Machine %q in namespace %q" ,
918
- obj .GroupVersionKind (), obj .GetName (), m .Name , m .Namespace )
919
- }
892
+ if err := r .Client .Delete (ctx , s .infraMachine ); err != nil && ! apierrors .IsNotFound (err ) {
893
+ return false , errors .Wrapf (err ,
894
+ "failed to delete %v %q for Machine %q in namespace %q" ,
895
+ s .infraMachine .GroupVersionKind (), s .infraMachine .GetName (), s .machine .Name , s .machine .Namespace )
920
896
}
921
897
922
- // Return true if there are no more external objects.
923
- return obj , nil
898
+ return false , nil
924
899
}
925
900
926
901
// shouldAdopt returns true if the Machine should be adopted as a stand-alone Machine directly owned by the Cluster.
0 commit comments