Skip to content

Commit 22d1158

Browse files
authored
Merge pull request #11985 from daimaxiaxie/early-bind-providerid
🐛 Machine deletion: fallback to InfraMachine providerID if Machine providerID is not set
2 parents df41845 + 867f640 commit 22d1158

File tree

2 files changed

+68
-6
lines changed

2 files changed

+68
-6
lines changed

internal/controllers/machine/machine_controller.go

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ import (
5353
"sigs.k8s.io/cluster-api/controllers/external"
5454
"sigs.k8s.io/cluster-api/controllers/noderefutil"
5555
"sigs.k8s.io/cluster-api/feature"
56+
"sigs.k8s.io/cluster-api/internal/contract"
5657
"sigs.k8s.io/cluster-api/internal/controllers/machine/drain"
5758
"sigs.k8s.io/cluster-api/util"
5859
"sigs.k8s.io/cluster-api/util/annotations"
@@ -436,7 +437,7 @@ func (r *Reconciler) reconcileDelete(ctx context.Context, s *scope) (ctrl.Result
436437
s.deletingReason = clusterv1.MachineDeletingReason
437438
s.deletingMessage = "Deletion started"
438439

439-
err := r.isDeleteNodeAllowed(ctx, cluster, m)
440+
err := r.isDeleteNodeAllowed(ctx, cluster, m, s.infraMachine)
440441
isDeleteNodeAllowed := err == nil
441442
if err != nil {
442443
switch err {
@@ -711,14 +712,24 @@ func (r *Reconciler) nodeVolumeDetachTimeoutExceeded(machine *clusterv1.Machine)
711712

712713
// isDeleteNodeAllowed returns nil only if the Machine's NodeRef is not nil
713714
// and if the Machine is not the last control plane node in the cluster.
714-
func (r *Reconciler) isDeleteNodeAllowed(ctx context.Context, cluster *clusterv1.Cluster, machine *clusterv1.Machine) error {
715+
func (r *Reconciler) isDeleteNodeAllowed(ctx context.Context, cluster *clusterv1.Cluster, machine *clusterv1.Machine, infraMachine *unstructured.Unstructured) error {
715716
log := ctrl.LoggerFrom(ctx)
716717
// Return early if the cluster is being deleted.
717718
if !cluster.DeletionTimestamp.IsZero() {
718719
return errClusterIsBeingDeleted
719720
}
720721

721-
if machine.Status.NodeRef == nil && machine.Spec.ProviderID != nil {
722+
var providerID string
723+
if machine.Spec.ProviderID != nil {
724+
providerID = *machine.Spec.ProviderID
725+
} else if infraMachine != nil {
726+
// Fallback to retrieve from infraMachine.
727+
if providerIDFromInfraMachine, err := contract.InfrastructureMachine().ProviderID().Get(infraMachine); err == nil {
728+
providerID = *providerIDFromInfraMachine
729+
}
730+
}
731+
732+
if machine.Status.NodeRef == nil && providerID != "" {
722733
// If we don't have a node reference, but a provider id has been set,
723734
// try to retrieve the node one more time.
724735
//
@@ -729,7 +740,7 @@ func (r *Reconciler) isDeleteNodeAllowed(ctx context.Context, cluster *clusterv1
729740
if err != nil {
730741
log.Error(err, "Failed to get cluster client while deleting Machine and checking for nodes")
731742
} else {
732-
node, err := r.getNode(ctx, remoteClient, *machine.Spec.ProviderID)
743+
node, err := r.getNode(ctx, remoteClient, providerID)
733744
if err != nil && err != ErrNodeNotFound {
734745
log.Error(err, "Failed to get node while deleting Machine")
735746
} else if err == nil {

internal/controllers/machine/machine_controller_test.go

Lines changed: 53 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2604,6 +2604,7 @@ func TestIsDeleteNodeAllowed(t *testing.T) {
26042604
name string
26052605
cluster *clusterv1.Cluster
26062606
machine *clusterv1.Machine
2607+
infraMachine *unstructured.Unstructured
26072608
expectedError error
26082609
}{
26092610
{
@@ -2630,6 +2631,7 @@ func TestIsDeleteNodeAllowed(t *testing.T) {
26302631
},
26312632
Status: clusterv1.MachineStatus{},
26322633
},
2634+
infraMachine: nil,
26332635
expectedError: errNilNodeRef,
26342636
},
26352637
{
@@ -2660,6 +2662,7 @@ func TestIsDeleteNodeAllowed(t *testing.T) {
26602662
},
26612663
},
26622664
},
2665+
infraMachine: nil,
26632666
expectedError: errNoControlPlaneNodes,
26642667
},
26652668
{
@@ -2692,6 +2695,7 @@ func TestIsDeleteNodeAllowed(t *testing.T) {
26922695
},
26932696
},
26942697
},
2698+
infraMachine: nil,
26952699
expectedError: errNoControlPlaneNodes,
26962700
},
26972701
{
@@ -2722,6 +2726,7 @@ func TestIsDeleteNodeAllowed(t *testing.T) {
27222726
},
27232727
},
27242728
},
2729+
infraMachine: nil,
27252730
expectedError: nil,
27262731
},
27272732
{
@@ -2735,6 +2740,7 @@ func TestIsDeleteNodeAllowed(t *testing.T) {
27352740
},
27362741
},
27372742
machine: &clusterv1.Machine{},
2743+
infraMachine: nil,
27382744
expectedError: errClusterIsBeingDeleted,
27392745
},
27402746
{
@@ -2773,6 +2779,7 @@ func TestIsDeleteNodeAllowed(t *testing.T) {
27732779
},
27742780
},
27752781
},
2782+
infraMachine: nil,
27762783
expectedError: nil,
27772784
},
27782785
{
@@ -2811,6 +2818,7 @@ func TestIsDeleteNodeAllowed(t *testing.T) {
28112818
},
28122819
},
28132820
},
2821+
infraMachine: nil,
28142822
expectedError: errControlPlaneIsBeingDeleted,
28152823
},
28162824
{
@@ -2849,8 +2857,40 @@ func TestIsDeleteNodeAllowed(t *testing.T) {
28492857
},
28502858
},
28512859
},
2860+
infraMachine: nil,
28522861
expectedError: errControlPlaneIsBeingDeleted,
28532862
},
2863+
{
2864+
name: "no nodeRef, infrastructure machine has providerID",
2865+
cluster: &clusterv1.Cluster{
2866+
ObjectMeta: metav1.ObjectMeta{
2867+
Name: "test-cluster",
2868+
Namespace: metav1.NamespaceDefault,
2869+
},
2870+
},
2871+
machine: &clusterv1.Machine{
2872+
ObjectMeta: metav1.ObjectMeta{
2873+
Name: "created",
2874+
Namespace: metav1.NamespaceDefault,
2875+
Labels: map[string]string{
2876+
clusterv1.ClusterNameLabel: "test-cluster",
2877+
},
2878+
Finalizers: []string{clusterv1.MachineFinalizer},
2879+
},
2880+
Spec: clusterv1.MachineSpec{
2881+
ClusterName: "test-cluster",
2882+
InfrastructureRef: corev1.ObjectReference{},
2883+
Bootstrap: clusterv1.Bootstrap{DataSecretName: ptr.To("data")},
2884+
},
2885+
Status: clusterv1.MachineStatus{},
2886+
},
2887+
infraMachine: &unstructured.Unstructured{Object: map[string]interface{}{
2888+
"spec": map[string]interface{}{
2889+
"providerID": "test-node-1",
2890+
},
2891+
}},
2892+
expectedError: nil,
2893+
},
28542894
}
28552895

28562896
emp := &unstructured.Unstructured{
@@ -2889,6 +2929,16 @@ func TestIsDeleteNodeAllowed(t *testing.T) {
28892929
empBeingDeleted.SetDeletionTimestamp(&metav1.Time{Time: time.Now()})
28902930
empBeingDeleted.SetFinalizers([]string{"block-deletion"})
28912931

2932+
testNodeA := &corev1.Node{
2933+
ObjectMeta: metav1.ObjectMeta{
2934+
Name: "node-1",
2935+
},
2936+
Spec: corev1.NodeSpec{
2937+
ProviderID: "test-node-1",
2938+
},
2939+
}
2940+
remoteClient := fake.NewClientBuilder().WithIndex(&corev1.Node{}, "spec.providerID", index.NodeByProviderID).WithObjects(testNodeA).Build()
2941+
28922942
for _, tc := range testCases {
28932943
t.Run(tc.name, func(t *testing.T) {
28942944
g := NewWithT(t)
@@ -2949,10 +2999,11 @@ func TestIsDeleteNodeAllowed(t *testing.T) {
29492999
empBeingDeleted,
29503000
).Build()
29513001
mr := &Reconciler{
2952-
Client: c,
3002+
Client: c,
3003+
ClusterCache: clustercache.NewFakeClusterCache(remoteClient, client.ObjectKeyFromObject(tc.cluster)),
29533004
}
29543005

2955-
err := mr.isDeleteNodeAllowed(ctx, tc.cluster, tc.machine)
3006+
err := mr.isDeleteNodeAllowed(ctx, tc.cluster, tc.machine, tc.infraMachine)
29563007
if tc.expectedError == nil {
29573008
g.Expect(err).ToNot(HaveOccurred())
29583009
} else {

0 commit comments

Comments
 (0)