@@ -177,9 +177,10 @@ func (r *MachinePoolReconciler) reconcileExternal(ctx context.Context, cluster *
177
177
}
178
178
179
179
// reconcileBootstrap reconciles the Spec.Bootstrap.ConfigRef object on a MachinePool.
180
- func (r * MachinePoolReconciler ) reconcileBootstrap (ctx context.Context , cluster * clusterv1. Cluster , m * expv1. MachinePool ) (ctrl.Result , error ) {
180
+ func (r * MachinePoolReconciler ) reconcileBootstrap (ctx context.Context , s * scope ) (ctrl.Result , error ) {
181
181
log := ctrl .LoggerFrom (ctx )
182
-
182
+ cluster := s .cluster
183
+ m := s .machinePool
183
184
// Call generic external reconciler if we have an external reference.
184
185
var bootstrapConfig * unstructured.Unstructured
185
186
if m .Spec .Template .Spec .Bootstrap .ConfigRef != nil {
@@ -241,9 +242,10 @@ func (r *MachinePoolReconciler) reconcileBootstrap(ctx context.Context, cluster
241
242
}
242
243
243
244
// reconcileInfrastructure reconciles the Spec.InfrastructureRef object on a MachinePool.
244
- func (r * MachinePoolReconciler ) reconcileInfrastructure (ctx context.Context , cluster * clusterv1. Cluster , mp * expv1. MachinePool ) (ctrl.Result , error ) {
245
+ func (r * MachinePoolReconciler ) reconcileInfrastructure (ctx context.Context , s * scope ) (ctrl.Result , error ) {
245
246
log := ctrl .LoggerFrom (ctx )
246
-
247
+ cluster := s .cluster
248
+ mp := s .machinePool
247
249
// Call generic external reconciler.
248
250
infraReconcileResult , err := r .reconcileExternal (ctx , cluster , mp , & mp .Spec .Template .Spec .InfrastructureRef )
249
251
if err != nil {
@@ -283,8 +285,19 @@ func (r *MachinePoolReconciler) reconcileInfrastructure(ctx context.Context, clu
283
285
conditions .WithFallbackValue (ready , clusterv1 .WaitingForInfrastructureFallbackReason , clusterv1 .ConditionSeverityInfo , "" ),
284
286
)
285
287
286
- if err := r .reconcileMachines (ctx , mp , infraConfig ); err != nil {
287
- return ctrl.Result {}, errors .Wrapf (err , "failed to reconcile Machines for MachinePool %s" , klog .KObj (mp ))
288
+ clusterClient , err := r .Tracker .GetClient (ctx , util .ObjectKey (cluster ))
289
+ if err != nil {
290
+ return ctrl.Result {}, err
291
+ }
292
+
293
+ var getNodeRefsErr error
294
+ // Get the nodeRefsMap from the cluster.
295
+ s .nodeRefMap , getNodeRefsErr = r .getNodeRefMap (ctx , clusterClient )
296
+
297
+ err = r .reconcileMachines (ctx , s , infraConfig )
298
+
299
+ if err != nil || getNodeRefsErr != nil {
300
+ return ctrl.Result {}, kerrors .NewAggregate ([]error {errors .Wrapf (err , "failed to reconcile Machines for MachinePool %s" , klog .KObj (mp )), errors .Wrapf (getNodeRefsErr , "failed to get nodeRefs for MachinePool %s" , klog .KObj (mp ))})
288
301
}
289
302
290
303
if ! mp .Status .InfrastructureReady {
@@ -328,8 +341,9 @@ func (r *MachinePoolReconciler) reconcileInfrastructure(ctx context.Context, clu
328
341
// infrastructure is created accordingly.
329
342
// Note: When supported by the cloud provider implementation of the MachinePool, machines will provide a means to interact
330
343
// with the corresponding infrastructure (e.g. delete a specific machine in case MachineHealthCheck detects it is unhealthy).
331
- func (r * MachinePoolReconciler ) reconcileMachines (ctx context.Context , mp * expv1. MachinePool , infraMachinePool * unstructured.Unstructured ) error {
344
+ func (r * MachinePoolReconciler ) reconcileMachines (ctx context.Context , s * scope , infraMachinePool * unstructured.Unstructured ) error {
332
345
log := ctrl .LoggerFrom (ctx )
346
+ mp := s .machinePool
333
347
334
348
var infraMachineKind string
335
349
if err := util .UnstructuredUnmarshalField (infraMachinePool , & infraMachineKind , "status" , "infrastructureMachineKind" ); err != nil {
@@ -376,15 +390,15 @@ func (r *MachinePoolReconciler) reconcileMachines(ctx context.Context, mp *expv1
376
390
return err
377
391
}
378
392
379
- if err := r .createOrUpdateMachines (ctx , mp , machineList .Items , infraMachineList .Items ); err != nil {
393
+ if err := r .createOrUpdateMachines (ctx , s , machineList .Items , infraMachineList .Items ); err != nil {
380
394
return errors .Wrapf (err , "failed to create machines for MachinePool %q in namespace %q" , mp .Name , mp .Namespace )
381
395
}
382
396
383
397
return nil
384
398
}
385
399
386
400
// createOrUpdateMachines creates a MachinePool Machine for each infraMachine if it doesn't already exist and sets the owner reference and infraRef.
387
- func (r * MachinePoolReconciler ) createOrUpdateMachines (ctx context.Context , mp * expv1. MachinePool , machines []clusterv1.Machine , infraMachines []unstructured.Unstructured ) error {
401
+ func (r * MachinePoolReconciler ) createOrUpdateMachines (ctx context.Context , s * scope , machines []clusterv1.Machine , infraMachines []unstructured.Unstructured ) error {
388
402
log := ctrl .LoggerFrom (ctx )
389
403
390
404
// Construct a set of names of infraMachines that already have a Machine.
@@ -398,19 +412,30 @@ func (r *MachinePoolReconciler) createOrUpdateMachines(ctx context.Context, mp *
398
412
var errs []error
399
413
for i := range infraMachines {
400
414
infraMachine := & infraMachines [i ]
415
+
416
+ // Get Spec.ProviderID from the infraMachine.
417
+ var providerID string
418
+ var node * corev1.Node
419
+ if err := util .UnstructuredUnmarshalField (infraMachine , & providerID , "spec" , "providerID" ); err != nil {
420
+ log .V (4 ).Info ("could not retrieve providerID for infraMachine" , "infraMachine" , klog .KObj (infraMachine ))
421
+ } else {
422
+ // Retrieve the Node for the infraMachine from the nodeRefsMap using the providerID.
423
+ node = s .nodeRefMap [providerID ]
424
+ }
425
+
401
426
// If infraMachine already has a Machine, update it if needed.
402
427
if existingMachine , ok := infraMachineToMachine [infraMachine .GetName ()]; ok {
403
428
log .V (2 ).Info ("Patching existing Machine for infraMachine" , infraMachine .GetKind (), klog .KObj (infraMachine ), "Machine" , klog .KObj (& existingMachine ))
404
429
405
- desiredMachine := computeDesiredMachine (mp , infraMachine , & existingMachine )
430
+ desiredMachine := r . computeDesiredMachine (s . machinePool , infraMachine , & existingMachine , node )
406
431
if err := ssa .Patch (ctx , r .Client , MachinePoolControllerName , desiredMachine , ssa.WithCachingProxy {Cache : r .ssaCache , Original : & existingMachine }); err != nil {
407
432
log .Error (err , "failed to update Machine" , "Machine" , klog .KObj (desiredMachine ))
408
433
errs = append (errs , errors .Wrapf (err , "failed to update Machine %q" , klog .KObj (desiredMachine )))
409
434
}
410
435
} else {
411
436
// Otherwise create a new Machine for the infraMachine.
412
437
log .Info ("Creating new Machine for infraMachine" , "infraMachine" , klog .KObj (infraMachine ))
413
- machine := computeDesiredMachine (mp , infraMachine , nil )
438
+ machine := r . computeDesiredMachine (s . machinePool , infraMachine , nil , node )
414
439
415
440
if err := ssa .Patch (ctx , r .Client , MachinePoolControllerName , machine ); err != nil {
416
441
errs = append (errs , errors .Wrapf (err , "failed to create new Machine for infraMachine %q in namespace %q" , infraMachine .GetName (), infraMachine .GetNamespace ()))
@@ -432,14 +457,19 @@ func (r *MachinePoolReconciler) createOrUpdateMachines(ctx context.Context, mp *
432
457
433
458
// computeDesiredMachine constructs the desired Machine for an infraMachine.
434
459
// If the Machine exists, it ensures the Machine always owned by the MachinePool.
435
- func computeDesiredMachine (mp * expv1.MachinePool , infraMachine * unstructured.Unstructured , existingMachine * clusterv1.Machine ) * clusterv1.Machine {
460
+ func ( r * MachinePoolReconciler ) computeDesiredMachine (mp * expv1.MachinePool , infraMachine * unstructured.Unstructured , existingMachine * clusterv1.Machine , existingNode * corev1. Node ) * clusterv1.Machine {
436
461
infraRef := corev1.ObjectReference {
437
462
APIVersion : infraMachine .GetAPIVersion (),
438
463
Kind : infraMachine .GetKind (),
439
464
Name : infraMachine .GetName (),
440
465
Namespace : infraMachine .GetNamespace (),
441
466
}
442
467
468
+ var kubernetesVersion * string
469
+ if existingNode != nil && existingNode .Status .NodeInfo .KubeletVersion != "" {
470
+ kubernetesVersion = & existingNode .Status .NodeInfo .KubeletVersion
471
+ }
472
+
443
473
machine := & clusterv1.Machine {
444
474
ObjectMeta : metav1.ObjectMeta {
445
475
Name : infraMachine .GetName (),
@@ -452,6 +482,7 @@ func computeDesiredMachine(mp *expv1.MachinePool, infraMachine *unstructured.Uns
452
482
Spec : clusterv1.MachineSpec {
453
483
ClusterName : mp .Spec .ClusterName ,
454
484
InfrastructureRef : infraRef ,
485
+ Version : kubernetesVersion ,
455
486
},
456
487
}
457
488
@@ -537,3 +568,29 @@ func (r *MachinePoolReconciler) waitForMachineCreation(ctx context.Context, mach
537
568
538
569
return nil
539
570
}
571
+
572
+ func (r * MachinePoolReconciler ) getNodeRefMap (ctx context.Context , c client.Client ) (map [string ]* corev1.Node , error ) {
573
+ log := ctrl .LoggerFrom (ctx )
574
+ nodeRefsMap := make (map [string ]* corev1.Node )
575
+ nodeList := corev1.NodeList {}
576
+ for {
577
+ if err := c .List (ctx , & nodeList , client .Continue (nodeList .Continue )); err != nil {
578
+ return nil , err
579
+ }
580
+
581
+ for _ , node := range nodeList .Items {
582
+ if node .Spec .ProviderID == "" {
583
+ log .V (2 ).Info ("No ProviderID detected, skipping" , "providerID" , node .Spec .ProviderID )
584
+ continue
585
+ }
586
+
587
+ nodeRefsMap [node .Spec .ProviderID ] = & node
588
+ }
589
+
590
+ if nodeList .Continue == "" {
591
+ break
592
+ }
593
+ }
594
+
595
+ return nodeRefsMap , nil
596
+ }
0 commit comments