Skip to content

Commit ef1df93

Browse files
committed
Detect Flex from VMSS orchestration mode
1 parent 835174a commit ef1df93

File tree

13 files changed

+129
-75
lines changed

13 files changed

+129
-75
lines changed

azure/converters/vmss.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ func SDKToVMSS(sdkvmss compute.VirtualMachineScaleSet, sdkinstances []compute.Vi
5050
vmss.Instances = make([]azure.VMSSVM, len(sdkinstances))
5151
for i, vm := range sdkinstances {
5252
vmss.Instances[i] = *SDKToVMSSVM(vm)
53+
vmss.Instances[i].OrchestrationMode = infrav1.OrchestrationModeType(sdkvmss.OrchestrationMode)
5354
}
5455
}
5556

@@ -64,7 +65,7 @@ func SDKToVMSS(sdkvmss compute.VirtualMachineScaleSet, sdkinstances []compute.Vi
6465
}
6566

6667
// SDKVMToVMSSVM converts an Azure SDK VM to a VMSS VM.
67-
func SDKVMToVMSSVM(sdkInstance compute.VirtualMachine) *azure.VMSSVM {
68+
func SDKVMToVMSSVM(sdkInstance compute.VirtualMachine, mode infrav1.OrchestrationModeType) *azure.VMSSVM {
6869
instance := azure.VMSSVM{
6970
ID: to.String(sdkInstance.ID),
7071
}
@@ -92,6 +93,8 @@ func SDKVMToVMSSVM(sdkInstance compute.VirtualMachine) *azure.VMSSVM {
9293
instance.AvailabilityZone = to.StringSlice(sdkInstance.Zones)[0]
9394
}
9495

96+
instance.OrchestrationMode = mode
97+
9598
return &instance
9699
}
97100

azure/converters/vmss_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -350,7 +350,7 @@ func Test_SDKVMToVMSSVM(t *testing.T) {
350350
t.Run(c.Name, func(t *testing.T) {
351351
t.Parallel()
352352
g := gomega.NewGomegaWithT(t)
353-
subject := converters.SDKVMToVMSSVM(c.Subject)
353+
subject := converters.SDKVMToVMSSVM(c.Subject, "")
354354
g.Expect(subject).To(gomega.Equal(c.Expected))
355355
})
356356
}

azure/scope/machinepool.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -282,7 +282,7 @@ func (m *MachinePoolScope) applyAzureMachinePoolMachines(ctx context.Context) er
282282
}
283283

284284
// determine which machines need to be created to reflect the current state in Azure
285-
azureMachinesByProviderID := m.vmssState.InstancesByProviderID()
285+
azureMachinesByProviderID := m.vmssState.InstancesByProviderID(m.AzureMachinePool.Spec.OrchestrationMode)
286286
for key, val := range azureMachinesByProviderID {
287287
if _, ok := existingMachinesByProviderID[key]; !ok {
288288
log.V(4).Info("creating AzureMachinePoolMachine", "providerID", key)

azure/scope/machinepoolmachine.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,11 @@ func (s *MachinePoolMachineScope) ScaleSetName() string {
163163
return s.MachinePoolScope.Name()
164164
}
165165

166+
// OrchestrationMode is the VMSS orchestration mode, either Uniform or Flexible.
167+
func (s *MachinePoolMachineScope) OrchestrationMode() infrav1.OrchestrationModeType {
168+
return s.AzureMachinePool.Spec.OrchestrationMode
169+
}
170+
166171
// SetLongRunningOperationState will set the future on the AzureMachinePoolMachine status to allow the resource to continue
167172
// in the next reconciliation.
168173
func (s *MachinePoolMachineScope) SetLongRunningOperationState(future *infrav1.Future) {
@@ -259,6 +264,7 @@ func (s *MachinePoolMachineScope) PatchObject(ctx context.Context) error {
259264
patch.WithOwnedConditions{Conditions: []clusterv1.ConditionType{
260265
clusterv1.ReadyCondition,
261266
clusterv1.MachineNodeHealthyCondition,
267+
clusterv1.DrainingSucceededCondition,
262268
}})
263269
}
264270

azure/scope/strategies/machinepool_deployments/machinepool_deployment_strategy.go

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -158,13 +158,7 @@ func (rollingUpdateStrategy rollingUpdateStrategy) SelectMachinesToDelete(ctx co
158158
return append(failedMachines, deletingMachines...), nil
159159
}
160160

161-
// if we have failed machines, remove them
162-
if len(failedMachines) > 0 {
163-
log.Info("failed machines", "desiredReplicaCount", desiredReplicaCount, "maxUnavailable", maxUnavailable, "failedMachines", getProviderIDs(failedMachines))
164-
return failedMachines, nil
165-
}
166-
167-
// if we have not yet reached our desired count, don't try to delete anything but failed machines
161+
// if we have not yet reached our desired count, don't try to delete anything
168162
if len(readyMachines) < int(desiredReplicaCount) {
169163
log.Info("not enough ready machines", "desiredReplicaCount", desiredReplicaCount, "readyMachinesCount", len(readyMachines), "machinesByProviderID", len(machinesByProviderID))
170164
return []infrav1exp.AzureMachinePoolMachine{}, nil

azure/services/scalesets/scalesets.go

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -293,13 +293,7 @@ func (s *Service) patchVMSSIfNeeded(ctx context.Context, infraVMSS *azure.VMSS)
293293
}
294294

295295
hasModelChanges := hasModelModifyingDifferences(infraVMSS, vmss)
296-
var isFlex bool
297-
for _, instance := range infraVMSS.Instances {
298-
if instance.IsFlex() {
299-
isFlex = true
300-
break
301-
}
302-
}
296+
isFlex := s.Scope.ScaleSetSpec().OrchestrationMode == infrav1.FlexibleOrchestrationMode
303297
updated := true
304298
if !isFlex {
305299
updated = infraVMSS.HasEnoughLatestModelOrNotMixedModel()

azure/services/scalesetvms/mock_scalesetvms/scalesetvms_mock.go

Lines changed: 14 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

azure/services/scalesetvms/scalesetvms.go

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ type (
4242
InstanceID() string
4343
ProviderID() string
4444
ScaleSetName() string
45+
OrchestrationMode() infrav1.OrchestrationModeType
4546
SetVMSSVM(vmssvm *azure.VMSSVM)
4647
}
4748

@@ -77,10 +78,11 @@ func (s *Service) Reconcile(ctx context.Context) error {
7778
vmssName = s.Scope.ScaleSetName()
7879
instanceID = s.Scope.InstanceID()
7980
providerID = s.Scope.ProviderID()
81+
isFlex = s.Scope.OrchestrationMode() == infrav1.FlexibleOrchestrationMode
8082
)
8183

8284
// Fetch the latest instance or VM data. AzureMachinePoolReconciler handles model mutations.
83-
if isFlex(instanceID) {
85+
if isFlex {
8486
resourceID := strings.TrimPrefix(providerID, azure.ProviderIDPrefix)
8587
log.V(4).Info("VMSS is flex", "vmssName", vmssName, "providerID", providerID, "resourceID", resourceID)
8688
// Using VMSS Flex, so fetch by resource ID.
@@ -91,7 +93,7 @@ func (s *Service) Reconcile(ctx context.Context) error {
9193
}
9294
return errors.Wrap(err, "failed getting vm")
9395
}
94-
s.Scope.SetVMSSVM(converters.SDKVMToVMSSVM(vm))
96+
s.Scope.SetVMSSVM(converters.SDKVMToVMSSVM(vm, infrav1.FlexibleOrchestrationMode))
9597
return nil
9698
}
9799

@@ -116,6 +118,7 @@ func (s *Service) Delete(ctx context.Context) error {
116118
vmssName = s.Scope.ScaleSetName()
117119
instanceID = s.Scope.InstanceID()
118120
providerID = s.Scope.ProviderID()
121+
isFlex = s.Scope.OrchestrationMode() == infrav1.FlexibleOrchestrationMode
119122
)
120123

121124
ctx, log, done := tele.StartSpanWithLogger(
@@ -127,24 +130,20 @@ func (s *Service) Delete(ctx context.Context) error {
127130
)
128131
defer done()
129132

130-
if isFlex(instanceID) {
133+
if isFlex {
131134
return s.deleteVMSSFlexVM(ctx, strings.TrimPrefix(providerID, azure.ProviderIDPrefix))
132135
}
133136
return s.deleteVMSSUniformInstance(ctx, resourceGroup, vmssName, instanceID, log)
134137
}
135138

136-
func isFlex(instanceID string) bool {
137-
return instanceID == ""
138-
}
139-
140139
func (s *Service) deleteVMSSFlexVM(ctx context.Context, resourceID string) error {
141140
ctx, log, done := tele.StartSpanWithLogger(ctx, "scalesetvms.Service.deleteVMSSFlexVM")
142141
defer done()
143142

144143
defer func() {
145144
if vm, err := s.VMClient.GetByID(ctx, resourceID); err == nil && vm.VirtualMachineProperties != nil {
146145
log.V(4).Info("vmss vm delete in progress", "state", vm.ProvisioningState)
147-
s.Scope.SetVMSSVM(converters.SDKVMToVMSSVM(vm))
146+
s.Scope.SetVMSSVM(converters.SDKVMToVMSSVM(vm, s.Scope.OrchestrationMode()))
148147
}
149148
}()
150149

azure/services/scalesetvms/scalesetvms_test.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,7 @@ func TestService_Reconcile(t *testing.T) {
150150
scopeMock.EXPECT().SubscriptionID().Return("subID").AnyTimes()
151151
scopeMock.EXPECT().BaseURI().Return("https://localhost/").AnyTimes()
152152
scopeMock.EXPECT().Authorizer().Return(nil).AnyTimes()
153+
scopeMock.EXPECT().OrchestrationMode().Return(infrav1.UniformOrchestrationMode).AnyTimes()
153154

154155
service := NewService(scopeMock)
155156
service.Client = clientMock
@@ -268,6 +269,7 @@ func TestService_Delete(t *testing.T) {
268269
scopeMock.EXPECT().SubscriptionID().Return("subID").AnyTimes()
269270
scopeMock.EXPECT().BaseURI().Return("https://localhost/").AnyTimes()
270271
scopeMock.EXPECT().Authorizer().Return(nil).AnyTimes()
272+
scopeMock.EXPECT().OrchestrationMode().Return(infrav1.UniformOrchestrationMode).AnyTimes()
271273

272274
service := NewService(scopeMock)
273275
service.Client = clientMock

azure/types.go

Lines changed: 11 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -94,13 +94,14 @@ type ExtensionSpec struct {
9494
type (
9595
// VMSSVM defines a VM in a virtual machine scale set.
9696
VMSSVM struct {
97-
ID string `json:"id,omitempty"`
98-
InstanceID string `json:"instanceID,omitempty"`
99-
Image infrav1.Image `json:"image,omitempty"`
100-
Name string `json:"name,omitempty"`
101-
AvailabilityZone string `json:"availabilityZone,omitempty"`
102-
State infrav1.ProvisioningState `json:"vmState,omitempty"`
103-
BootstrappingState infrav1.ProvisioningState `json:"bootstrappingState,omitempty"`
97+
ID string `json:"id,omitempty"`
98+
InstanceID string `json:"instanceID,omitempty"`
99+
Image infrav1.Image `json:"image,omitempty"`
100+
Name string `json:"name,omitempty"`
101+
AvailabilityZone string `json:"availabilityZone,omitempty"`
102+
State infrav1.ProvisioningState `json:"vmState,omitempty"`
103+
BootstrappingState infrav1.ProvisioningState `json:"bootstrappingState,omitempty"`
104+
OrchestrationMode infrav1.OrchestrationModeType `json:"orchestrationMode,omitempty"`
104105
}
105106

106107
// VMSS defines a virtual machine scale set.
@@ -129,9 +130,10 @@ func (vmss VMSS) HasModelChanges(other VMSS) bool {
129130
}
130131

131132
// InstancesByProviderID returns VMSSVMs by ID.
132-
func (vmss VMSS) InstancesByProviderID() map[string]VMSSVM {
133+
func (vmss VMSS) InstancesByProviderID(mode infrav1.OrchestrationModeType) map[string]VMSSVM {
133134
instancesByProviderID := make(map[string]VMSSVM, len(vmss.Instances))
134135
for _, instance := range vmss.Instances {
136+
instance.OrchestrationMode = mode
135137
instancesByProviderID[instance.ProviderID()] = instance
136138
}
137139

@@ -140,7 +142,7 @@ func (vmss VMSS) InstancesByProviderID() map[string]VMSSVM {
140142

141143
// ProviderID returns the K8s provider ID for the VMSS instance.
142144
func (vm VMSSVM) ProviderID() string {
143-
if vm.IsFlex() {
145+
if vm.OrchestrationMode == infrav1.FlexibleOrchestrationMode {
144146
// ProviderID for Flex scaleset VMs looks like this:
145147
// azure:///subscriptions/<sub_id>/resourceGroups/my-cluster/providers/Microsoft.Compute/virtualMachines/my-cluster_1234abcd
146148
splitOnSlash := strings.Split(vm.ID, "/")
@@ -153,11 +155,6 @@ func (vm VMSSVM) ProviderID() string {
153155
return ProviderIDPrefix + vm.ID
154156
}
155157

156-
// IsFlex returns true if the VMSS instance is a Flex VM.
157-
func (vm VMSSVM) IsFlex() bool {
158-
return vm.InstanceID == ""
159-
}
160-
161158
// HasLatestModelAppliedToAll returns true if all VMSS instance have the latest model applied.
162159
func (vmss VMSS) HasLatestModelAppliedToAll() bool {
163160
for _, instance := range vmss.Instances {

0 commit comments

Comments
 (0)