Skip to content

Commit 724a4e7

Browse files
authored
Merge pull request #2604 from jackfrancis/synthesize-aks-capz-nodepool-labels
Implement ScaleSetPriority for AzureManagedMachinePool
2 parents 0da9473 + d498079 commit 724a4e7

17 files changed

+217
-1
lines changed

azure/converters/managedagentpool.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,5 +43,6 @@ func AgentPoolToManagedClusterAgentPoolProfile(pool containerservice.AgentPool)
4343
NodeLabels: properties.NodeLabels,
4444
EnableUltraSSD: properties.EnableUltraSSD,
4545
EnableNodePublicIP: properties.EnableNodePublicIP,
46+
ScaleSetPriority: properties.ScaleSetPriority,
4647
}
4748
}

azure/scope/managedmachinepool.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,7 @@ func buildAgentPoolSpec(managedControlPlane *infrav1exp.AzureManagedControlPlane
176176
EnableUltraSSD: managedMachinePool.Spec.EnableUltraSSD,
177177
Headers: maps.FilterByKeyPrefix(agentPoolAnnotations, azure.CustomHeaderPrefix),
178178
EnableNodePublicIP: managedMachinePool.Spec.EnableNodePublicIP,
179+
ScaleSetPriority: managedMachinePool.Spec.ScaleSetPriority,
179180
}
180181

181182
if managedMachinePool.Spec.OSDiskSizeGB != nil {

azure/services/agentpools/spec.go

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import (
2626
"github.com/pkg/errors"
2727
infrav1 "sigs.k8s.io/cluster-api-provider-azure/api/v1beta1"
2828
"sigs.k8s.io/cluster-api-provider-azure/azure"
29+
azureutil "sigs.k8s.io/cluster-api-provider-azure/util/azure"
2930
)
3031

3132
// AgentPoolSpec contains agent pool specification details.
@@ -92,6 +93,9 @@ type AgentPoolSpec struct {
9293

9394
// EnableNodePublicIP controls whether or not nodes in the agent pool each have a public IP address.
9495
EnableNodePublicIP *bool `json:"enableNodePublicIP,omitempty"`
96+
97+
// ScaleSetPriority specifies the ScaleSetPriority for the node pool. Allowed values are 'Spot' and 'Regular'
98+
ScaleSetPriority *string `json:"scaleSetPriority,omitempty"`
9599
}
96100

97101
// ResourceName returns the name of the agent pool.
@@ -116,6 +120,7 @@ func (s *AgentPoolSpec) CustomHeaders() map[string]string {
116120

117121
// Parameters returns the parameters for the agent pool.
118122
func (s *AgentPoolSpec) Parameters(existing interface{}) (params interface{}, err error) {
123+
nodeLabels := s.NodeLabels
119124
if existing != nil {
120125
existingPool, ok := existing.(containerservice.AgentPool)
121126
if !ok {
@@ -169,6 +174,12 @@ func (s *AgentPoolSpec) Parameters(existing interface{}) (params interface{}, er
169174
// agent pool is up to date, nothing to do
170175
return nil, nil
171176
}
177+
// We do a just-in-time merge of existent kubernetes.azure.com-prefixed labels
178+
// So that we don't unintentionally delete them
179+
// See https://github.com/Azure/AKS/issues/3152
180+
if normalizedProfile.NodeLabels != nil {
181+
nodeLabels = mergeSystemNodeLabels(normalizedProfile.NodeLabels, existingPool.NodeLabels)
182+
}
172183
}
173184

174185
var availabilityZones *[]string
@@ -202,16 +213,30 @@ func (s *AgentPoolSpec) Parameters(existing interface{}) (params interface{}, er
202213
MaxPods: s.MaxPods,
203214
MinCount: s.MinCount,
204215
Mode: containerservice.AgentPoolMode(s.Mode),
205-
NodeLabels: s.NodeLabels,
216+
NodeLabels: nodeLabels,
206217
NodeTaints: nodeTaints,
207218
OrchestratorVersion: s.Version,
208219
OsDiskSizeGB: &s.OSDiskSizeGB,
209220
OsDiskType: containerservice.OSDiskType(to.String(s.OsDiskType)),
210221
OsType: containerservice.OSType(to.String(s.OSType)),
222+
ScaleSetPriority: containerservice.ScaleSetPriority(to.String(s.ScaleSetPriority)),
211223
Type: containerservice.AgentPoolTypeVirtualMachineScaleSets,
212224
VMSize: sku,
213225
VnetSubnetID: vnetSubnetID,
214226
EnableNodePublicIP: s.EnableNodePublicIP,
215227
},
216228
}, nil
217229
}
230+
231+
// mergeSystemNodeLabels appends any kubernetes.azure.com-prefixed labels from the AKS label set
232+
// into the local capz label set.
233+
func mergeSystemNodeLabels(capz, aks map[string]*string) map[string]*string {
234+
ret := capz
235+
// Look for labels returned from the AKS node pool API that begin with kubernetes.azure.com
236+
for aksNodeLabelKey := range aks {
237+
if azureutil.IsAzureSystemNodeLabelKey(aksNodeLabelKey) {
238+
ret[aksNodeLabelKey] = aks[aksNodeLabelKey]
239+
}
240+
}
241+
return ret
242+
}

azure/services/agentpools/spec_test.go

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -373,3 +373,82 @@ func TestParameters(t *testing.T) {
373373
})
374374
}
375375
}
376+
377+
func TestMergeSystemNodeLabels(t *testing.T) {
378+
testcases := []struct {
379+
name string
380+
capzLabels map[string]*string
381+
aksLabels map[string]*string
382+
expected map[string]*string
383+
}{
384+
{
385+
name: "update an existing label",
386+
capzLabels: map[string]*string{
387+
"foo": to.StringPtr("bar"),
388+
},
389+
aksLabels: map[string]*string{
390+
"foo": to.StringPtr("baz"),
391+
},
392+
expected: map[string]*string{
393+
"foo": to.StringPtr("bar"),
394+
},
395+
},
396+
{
397+
name: "delete labels",
398+
capzLabels: map[string]*string{},
399+
aksLabels: map[string]*string{
400+
"foo": to.StringPtr("bar"),
401+
"hello": to.StringPtr("world"),
402+
},
403+
expected: map[string]*string{},
404+
},
405+
{
406+
name: "delete one label",
407+
capzLabels: map[string]*string{
408+
"foo": to.StringPtr("bar"),
409+
},
410+
aksLabels: map[string]*string{
411+
"foo": to.StringPtr("bar"),
412+
"hello": to.StringPtr("world"),
413+
},
414+
expected: map[string]*string{
415+
"foo": to.StringPtr("bar"),
416+
},
417+
},
418+
{
419+
name: "retain system label during update",
420+
capzLabels: map[string]*string{
421+
"foo": to.StringPtr("bar"),
422+
},
423+
aksLabels: map[string]*string{
424+
"kubernetes.azure.com/scalesetpriority": to.StringPtr("spot"),
425+
},
426+
expected: map[string]*string{
427+
"foo": to.StringPtr("bar"),
428+
"kubernetes.azure.com/scalesetpriority": to.StringPtr("spot"),
429+
},
430+
},
431+
{
432+
name: "retain system label during delete",
433+
capzLabels: map[string]*string{},
434+
aksLabels: map[string]*string{
435+
"kubernetes.azure.com/scalesetpriority": to.StringPtr("spot"),
436+
},
437+
expected: map[string]*string{
438+
"kubernetes.azure.com/scalesetpriority": to.StringPtr("spot"),
439+
},
440+
},
441+
}
442+
443+
for _, tc := range testcases {
444+
t.Logf("Testing " + tc.name)
445+
tc := tc
446+
t.Run(tc.name, func(t *testing.T) {
447+
g := NewWithT(t)
448+
t.Parallel()
449+
450+
ret := mergeSystemNodeLabels(tc.capzLabels, tc.aksLabels)
451+
g.Expect(ret).To(Equal(tc.expected))
452+
})
453+
}
454+
}

config/crd/bases/infrastructure.cluster.x-k8s.io_azuremanagedmachinepools.yaml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -262,6 +262,13 @@ spec:
262262
items:
263263
type: string
264264
type: array
265+
scaleSetPriority:
266+
description: 'ScaleSetPriority specifies the ScaleSetPriority value.
267+
Default to Regular. Possible values include: ''Regular'', ''Spot'''
268+
enum:
269+
- Regular
270+
- Spot
271+
type: string
265272
scaling:
266273
description: Scaling specifies the autoscaling parameters for the
267274
node pool.

exp/api/v1alpha3/azuremanagedmachinepool_conversion.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ func (src *AzureManagedMachinePool) ConvertTo(dstRaw conversion.Hub) error {
4646
dst.Spec.NodeLabels = restored.Spec.NodeLabels
4747
dst.Spec.EnableUltraSSD = restored.Spec.EnableUltraSSD
4848
dst.Spec.EnableNodePublicIP = restored.Spec.EnableNodePublicIP
49+
dst.Spec.ScaleSetPriority = restored.Spec.ScaleSetPriority
4950

5051
dst.Status.LongRunningOperationStates = restored.Status.LongRunningOperationStates
5152
dst.Status.Conditions = restored.Status.Conditions

exp/api/v1alpha3/zz_generated.conversion.go

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

exp/api/v1alpha4/azuremanagedmachinepool_conversion.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ func (src *AzureManagedMachinePool) ConvertTo(dstRaw conversion.Hub) error {
4646
dst.Spec.NodeLabels = restored.Spec.NodeLabels
4747
dst.Spec.EnableUltraSSD = restored.Spec.EnableUltraSSD
4848
dst.Spec.EnableNodePublicIP = restored.Spec.EnableNodePublicIP
49+
dst.Spec.ScaleSetPriority = restored.Spec.ScaleSetPriority
4950

5051
dst.Status.LongRunningOperationStates = restored.Status.LongRunningOperationStates
5152
dst.Status.Conditions = restored.Status.Conditions

exp/api/v1alpha4/zz_generated.conversion.go

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

exp/api/v1beta1/azuremanagedmachinepool_types.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,11 @@ type AzureManagedMachinePoolSpec struct {
102102
// EnableNodePublicIP controls whether or not nodes in the pool each have a public IP address.
103103
// +optional
104104
EnableNodePublicIP *bool `json:"enableNodePublicIP,omitempty"`
105+
106+
// ScaleSetPriority specifies the ScaleSetPriority value. Default to Regular. Possible values include: 'Regular', 'Spot'
107+
// +kubebuilder:validation:Enum=Regular;Spot
108+
// +optional
109+
ScaleSetPriority *string `json:"scaleSetPriority,omitempty"`
105110
}
106111

107112
// ManagedMachinePoolScaling specifies scaling options.

0 commit comments

Comments
 (0)