diff --git a/internal/controllers/machinepool/machinepool_controller_noderef.go b/internal/controllers/machinepool/machinepool_controller_noderef.go index 8440e96a314d..d12a8dff0cda 100644 --- a/internal/controllers/machinepool/machinepool_controller_noderef.go +++ b/internal/controllers/machinepool/machinepool_controller_noderef.go @@ -70,8 +70,34 @@ func (r *Reconciler) reconcileNodeRefs(ctx context.Context, s *scope) (ctrl.Resu readyReplicas = mp.Status.Deprecated.V1Beta1.ReadyReplicas } if ptr.Deref(mp.Status.Replicas, 0) == readyReplicas && len(mp.Status.NodeRefs) == int(readyReplicas) { - v1beta1conditions.MarkTrue(mp, clusterv1.ReplicasReadyV1Beta1Condition) - return ctrl.Result{}, nil + // Validate that the UIDs in NodeRefs are still valid + if s.nodeRefMap != nil { + // Create a name-to-node mapping for efficient lookup + nodeNameMap := make(map[string]*corev1.Node, len(s.nodeRefMap)) + for _, node := range s.nodeRefMap { + nodeNameMap[node.Name] = node + } + + validNodeRefs := true + for _, nodeRef := range mp.Status.NodeRefs { + foundNode, exists := nodeNameMap[nodeRef.Name] + + // If node not found or UID doesn't match, mark as invalid + if !exists || foundNode.UID != nodeRef.UID { + log.V(1).Info("NodeRefs do not match current Nodes, will reassign") + validNodeRefs = false + break + } + } + + if validNodeRefs { + v1beta1conditions.MarkTrue(mp, clusterv1.ReplicasReadyV1Beta1Condition) + return ctrl.Result{}, nil + } + } else { + // If nodeRefMap is nil, we can't validate UIDs, so proceed with reconciliation + log.V(2).Info("NodeRefMap is nil, proceeding with reconciliation to validate NodeRefs") + } } // Check that the MachinePool has valid ProviderIDList.