Skip to content

Commit 5b87067

Browse files
authored
Merge pull request #4943 from helio/fix-delete-machine-vmss-vm
fix: delete Machine instead of AzureMachinePoolMachine if VMSS VM is failed
2 parents 52df930 + 4955ce7 commit 5b87067

File tree

2 files changed

+37
-10
lines changed

2 files changed

+37
-10
lines changed

exp/controllers/azuremachinepoolmachine_controller.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -297,8 +297,9 @@ func (ampmr *AzureMachinePoolMachineController) reconcileNormal(ctx context.Cont
297297
machineScope.SetFailureReason(capierrors.UpdateMachineError)
298298
machineScope.SetFailureMessage(errors.Errorf("Azure VM state is %s", state))
299299
case infrav1.Deleting:
300-
if err := ampmr.Client.Delete(ctx, machineScope.AzureMachinePoolMachine); err != nil {
301-
return reconcile.Result{}, errors.Wrap(err, "machine pool machine failed to be deleted when deleting")
300+
log.V(4).Info("deleting machine because state is Deleting", "machine", machineScope.Name())
301+
if err := ampmr.Client.Delete(ctx, machineScope.Machine); err != nil {
302+
return reconcile.Result{}, errors.Wrap(err, "machine failed to be deleted when deleting")
302303
}
303304
}
304305

exp/controllers/azuremachinepoolmachine_controller_test.go

Lines changed: 34 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import (
2727
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
2828
"k8s.io/apimachinery/pkg/runtime"
2929
"k8s.io/apimachinery/pkg/types"
30+
"k8s.io/utils/ptr"
3031
infrav1 "sigs.k8s.io/cluster-api-provider-azure/api/v1beta1"
3132
"sigs.k8s.io/cluster-api-provider-azure/azure"
3233
"sigs.k8s.io/cluster-api-provider-azure/azure/mock_azure"
@@ -45,30 +46,49 @@ func TestAzureMachinePoolMachineReconciler_Reconcile(t *testing.T) {
4546
cases := []struct {
4647
Name string
4748
Setup func(cb *fake.ClientBuilder, reconciler *mock_azure.MockReconcilerMockRecorder)
48-
Verify func(g *WithT, result ctrl.Result, err error)
49+
Verify func(g *WithT, c client.Client, result ctrl.Result, err error)
4950
}{
5051
{
5152
Name: "should successfully reconcile",
5253
Setup: func(cb *fake.ClientBuilder, reconciler *mock_azure.MockReconcilerMockRecorder) {
53-
objects := getReadyMachinePoolMachineClusterObjects(false)
54+
objects := getReadyMachinePoolMachineClusterObjects(false, nil)
5455
reconciler.Reconcile(gomock2.AContext()).Return(nil)
5556
cb.WithObjects(objects...)
5657
},
57-
Verify: func(g *WithT, result ctrl.Result, err error) {
58+
Verify: func(g *WithT, c client.Client, result ctrl.Result, err error) {
5859
g.Expect(err).NotTo(HaveOccurred())
5960
},
6061
},
6162
{
6263
Name: "should successfully delete",
6364
Setup: func(cb *fake.ClientBuilder, reconciler *mock_azure.MockReconcilerMockRecorder) {
64-
objects := getReadyMachinePoolMachineClusterObjects(true)
65+
objects := getReadyMachinePoolMachineClusterObjects(true, nil)
6566
reconciler.Delete(gomock2.AContext()).Return(nil)
6667
cb.WithObjects(objects...)
6768
},
68-
Verify: func(g *WithT, result ctrl.Result, err error) {
69+
Verify: func(g *WithT, c client.Client, result ctrl.Result, err error) {
6970
g.Expect(err).NotTo(HaveOccurred())
7071
},
7172
},
73+
{
74+
Name: "should delete Machine if VMSS VM has state Deleting",
75+
Setup: func(cb *fake.ClientBuilder, reconciler *mock_azure.MockReconcilerMockRecorder) {
76+
objects := getReadyMachinePoolMachineClusterObjects(false, ptr.To(infrav1.Deleting))
77+
reconciler.Reconcile(gomock2.AContext()).Return(nil)
78+
cb.WithObjects(objects...)
79+
},
80+
Verify: func(g *WithT, c client.Client, result ctrl.Result, err error) {
81+
g.Expect(err).NotTo(HaveOccurred())
82+
83+
machine := &clusterv1.Machine{}
84+
err = c.Get(context.Background(), types.NamespacedName{
85+
Name: "ma1",
86+
Namespace: "default",
87+
}, machine)
88+
g.Expect(err).To(HaveOccurred())
89+
g.Expect(err.Error()).Should(ContainSubstring("not found"))
90+
},
91+
},
7292
}
7393

7494
for _, c := range cases {
@@ -97,7 +117,8 @@ func TestAzureMachinePoolMachineReconciler_Reconcile(t *testing.T) {
97117
defer mockCtrl.Finish()
98118

99119
c.Setup(cb, reconciler.EXPECT())
100-
controller := NewAzureMachinePoolMachineController(cb.Build(), nil, reconcilerutils.Timeouts{}, "foo")
120+
cl := cb.Build()
121+
controller := NewAzureMachinePoolMachineController(cl, nil, reconcilerutils.Timeouts{}, "foo")
101122
controller.reconcilerFactory = func(_ *scope.MachinePoolMachineScope) (azure.Reconciler, error) {
102123
return reconciler, nil
103124
}
@@ -107,12 +128,12 @@ func TestAzureMachinePoolMachineReconciler_Reconcile(t *testing.T) {
107128
Namespace: "default",
108129
},
109130
})
110-
c.Verify(g, res, err)
131+
c.Verify(g, cl, res, err)
111132
})
112133
}
113134
}
114135

115-
func getReadyMachinePoolMachineClusterObjects(ampmIsDeleting bool) []client.Object {
136+
func getReadyMachinePoolMachineClusterObjects(ampmIsDeleting bool, ampmProvisioningState *infrav1.ProvisioningState) []client.Object {
116137
azCluster := &infrav1.AzureCluster{
117138
TypeMeta: metav1.TypeMeta{
118139
Kind: "AzureCluster",
@@ -253,6 +274,11 @@ func getReadyMachinePoolMachineClusterObjects(ampmIsDeleting bool) []client.Obje
253274
Time: time.Now(),
254275
}
255276
}
277+
if ampmProvisioningState != nil {
278+
ampm.Status = infrav1exp.AzureMachinePoolMachineStatus{
279+
ProvisioningState: ampmProvisioningState,
280+
}
281+
}
256282

257283
return []client.Object{cluster, azCluster, mp, amp, ma, ampm, fakeIdentity, fakeSecret}
258284
}

0 commit comments

Comments
 (0)