Skip to content

Commit 6a1f654

Browse files
authored
Merge pull request #5292 from helio/fix-vmss-update-state-on-get
MachinePool always update vmssState
2 parents 4b18ac2 + 4f65eac commit 6a1f654

File tree

2 files changed

+42
-37
lines changed

2 files changed

+42
-37
lines changed

azure/services/scalesets/scalesets.go

Lines changed: 34 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ func (s *Service) Reconcile(ctx context.Context) (retErr error) {
9797
return errors.Errorf("%T is not of type ScaleSetSpec", spec)
9898
}
9999

100-
_, err := s.Client.Get(ctx, spec)
100+
result, err := s.Client.Get(ctx, spec)
101101
if err == nil {
102102
// We can only get the existing instances if the VMSS already exists
103103
scaleSetSpec.VMSSInstances, err = s.Client.ListInstances(ctx, spec.ResourceGroupName(), spec.ResourceName())
@@ -106,34 +106,51 @@ func (s *Service) Reconcile(ctx context.Context) (retErr error) {
106106
s.Scope.UpdatePutStatus(infrav1.BootstrapSucceededCondition, serviceName, err)
107107
return err
108108
}
109+
if result != nil {
110+
if err := s.updateScopeState(ctx, result, scaleSetSpec); err != nil {
111+
return err
112+
}
113+
}
109114
} else if !azure.ResourceNotFound(err) {
110115
return errors.Wrapf(err, "failed to get existing VMSS")
111116
}
112117

113-
result, err := s.CreateOrUpdateResource(ctx, scaleSetSpec, serviceName)
118+
result, err = s.CreateOrUpdateResource(ctx, scaleSetSpec, serviceName)
114119
s.Scope.UpdatePutStatus(infrav1.BootstrapSucceededCondition, serviceName, err)
115120

116121
if err == nil && result != nil {
117-
vmss, ok := result.(armcompute.VirtualMachineScaleSet)
118-
if !ok {
119-
return errors.Errorf("%T is not an armcompute.VirtualMachineScaleSet", result)
122+
if err := s.updateScopeState(ctx, result, scaleSetSpec); err != nil {
123+
return err
120124
}
125+
}
121126

122-
fetchedVMSS := converters.SDKToVMSS(vmss, scaleSetSpec.VMSSInstances)
123-
if err := s.Scope.ReconcileReplicas(ctx, &fetchedVMSS); err != nil {
124-
return errors.Wrap(err, "unable to reconcile VMSS replicas")
125-
}
127+
return err
128+
}
126129

127-
// Transform the VMSS resource representation to conform to the cloud-provider-azure representation
128-
providerID, err := azprovider.ConvertResourceGroupNameToLower(azureutil.ProviderIDPrefix + fetchedVMSS.ID)
129-
if err != nil {
130-
return errors.Wrapf(err, "failed to parse VMSS ID %s", fetchedVMSS.ID)
131-
}
132-
s.Scope.SetProviderID(providerID)
133-
s.Scope.SetVMSSState(&fetchedVMSS)
130+
// updateScopeState updates the scope's VMSS state and provider ID
131+
//
132+
// Code later in the reconciler uses scope's VMSS state for determining scale status and whether to create/delete
133+
// AzureMachinePoolMachines.
134+
// N.B.: before calling this function, make sure scaleSetSpec.VMSSInstances is updated to the latest state.
135+
func (s *Service) updateScopeState(ctx context.Context, result interface{}, scaleSetSpec *ScaleSetSpec) error {
136+
vmss, ok := result.(armcompute.VirtualMachineScaleSet)
137+
if !ok {
138+
return errors.Errorf("%T is not an armcompute.VirtualMachineScaleSet", result)
134139
}
135140

136-
return err
141+
fetchedVMSS := converters.SDKToVMSS(vmss, scaleSetSpec.VMSSInstances)
142+
if err := s.Scope.ReconcileReplicas(ctx, &fetchedVMSS); err != nil {
143+
return errors.Wrap(err, "unable to reconcile VMSS replicas")
144+
}
145+
146+
// Transform the VMSS resource representation to conform to the cloud-provider-azure representation
147+
providerID, err := azprovider.ConvertResourceGroupNameToLower(azureutil.ProviderIDPrefix + fetchedVMSS.ID)
148+
if err != nil {
149+
return errors.Wrapf(err, "failed to parse VMSS ID %s", fetchedVMSS.ID)
150+
}
151+
s.Scope.SetProviderID(providerID)
152+
s.Scope.SetVMSSState(&fetchedVMSS)
153+
return nil
137154
}
138155

139156
// Delete deletes a scale set asynchronously. Delete sends a DELETE request to Azure and if accepted without error,

azure/services/scalesets/scalesets_test.go

Lines changed: 8 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -120,14 +120,14 @@ func TestReconcileVMSS(t *testing.T) {
120120
spec := getDefaultVMSSSpec()
121121
// Validate spec
122122
s.ScaleSetSpec(gomockinternal.AContext()).Return(spec).AnyTimes()
123-
m.Get(gomockinternal.AContext(), &defaultSpec).Return(&resultVMSS, nil)
123+
m.Get(gomockinternal.AContext(), &defaultSpec).Return(resultVMSS, nil)
124124
m.ListInstances(gomockinternal.AContext(), defaultSpec.ResourceGroup, defaultSpec.Name).Return(defaultInstances, nil)
125125
r.CreateOrUpdateResource(gomockinternal.AContext(), spec, serviceName).Return(getResultVMSS(), nil)
126126
s.UpdatePutStatus(infrav1.BootstrapSucceededCondition, serviceName, nil)
127127

128-
s.ReconcileReplicas(gomockinternal.AContext(), &fetchedVMSS).Return(nil)
129-
s.SetProviderID(azureutil.ProviderIDPrefix + defaultVMSSID)
130-
s.SetVMSSState(&fetchedVMSS)
128+
s.ReconcileReplicas(gomockinternal.AContext(), &fetchedVMSS).Return(nil).Times(2)
129+
s.SetProviderID(azureutil.ProviderIDPrefix + defaultVMSSID).Times(2)
130+
s.SetVMSSState(&fetchedVMSS).Times(2)
131131
},
132132
},
133133
{
@@ -178,28 +178,16 @@ func TestReconcileVMSS(t *testing.T) {
178178
s.DefaultedAzureServiceReconcileTimeout().Return(reconciler.DefaultAzureServiceReconcileTimeout)
179179
spec := getDefaultVMSSSpec()
180180
s.ScaleSetSpec(gomockinternal.AContext()).Return(spec).AnyTimes()
181-
m.Get(gomockinternal.AContext(), &defaultSpec).Return(&resultVMSS, nil)
181+
m.Get(gomockinternal.AContext(), &defaultSpec).Return(resultVMSS, nil)
182182
m.ListInstances(gomockinternal.AContext(), defaultSpec.ResourceGroup, defaultSpec.Name).Return(defaultInstances, nil)
183183

184184
r.CreateOrUpdateResource(gomockinternal.AContext(), spec, serviceName).
185185
Return(nil, internalError())
186186
s.UpdatePutStatus(infrav1.BootstrapSucceededCondition, serviceName, internalError())
187-
},
188-
},
189-
{
190-
name: "failed to reconcile replicas",
191-
expectedError: "unable to reconcile VMSS replicas:.*#: Internal Server Error: StatusCode=500",
192-
expect: func(g *WithT, s *mock_scalesets.MockScaleSetScopeMockRecorder, r *mock_async.MockReconcilerMockRecorder, m *mock_scalesets.MockClientMockRecorder) {
193-
s.DefaultedAzureServiceReconcileTimeout().Return(reconciler.DefaultAzureServiceReconcileTimeout)
194-
spec := getDefaultVMSSSpec()
195-
s.ScaleSetSpec(gomockinternal.AContext()).Return(spec).AnyTimes()
196-
m.Get(gomockinternal.AContext(), &defaultSpec).Return(&resultVMSS, nil)
197-
m.ListInstances(gomockinternal.AContext(), defaultSpec.ResourceGroup, defaultSpec.Name).Return(defaultInstances, nil)
198187

199-
r.CreateOrUpdateResource(gomockinternal.AContext(), spec, serviceName).Return(getResultVMSS(), nil)
200-
s.UpdatePutStatus(infrav1.BootstrapSucceededCondition, serviceName, nil)
201-
202-
s.ReconcileReplicas(gomockinternal.AContext(), &fetchedVMSS).Return(internalError())
188+
s.ReconcileReplicas(gomockinternal.AContext(), &fetchedVMSS).Return(nil)
189+
s.SetProviderID(azureutil.ProviderIDPrefix + defaultVMSSID)
190+
s.SetVMSSState(&fetchedVMSS)
203191
},
204192
},
205193
{

0 commit comments

Comments
 (0)