Skip to content

Commit b1ac1ea

Browse files
authored
Merge pull request #3337 from richardcase/nodegroupupdate
feat: add nodegroup update config support
2 parents ba0b47f + bbfff61 commit b1ac1ea

14 files changed

+224
-1
lines changed

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

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -659,6 +659,25 @@ spec:
659659
- value
660660
type: object
661661
type: array
662+
updateConfig:
663+
description: UpdateConfig holds the optional config to control the
664+
behaviour of the update to the nodegroup.
665+
properties:
666+
maxUnavailable:
667+
description: MaxUnavailable is the maximum number of nodes unavailable
668+
at once during a version update. Nodes will be updated in parallel.
669+
The maximum number is 100.
670+
maximum: 100
671+
minimum: 1
672+
type: integer
673+
maxUnavailablePrecentage:
674+
description: MaxUnavailablePercentage is the maximum percentage
675+
of nodes unavailable during a version update. This percentage
676+
of nodes will be updated in parallel, up to 100 nodes at once.
677+
maximum: 100
678+
minimum: 1
679+
type: integer
680+
type: object
662681
type: object
663682
status:
664683
description: AWSManagedMachinePoolStatus defines the observed state of

exp/api/v1alpha3/conversion.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ func (r *AWSManagedMachinePool) ConvertTo(dstRaw conversion.Hub) error {
9191
dst.Spec.Taints = restored.Spec.Taints
9292
dst.Spec.CapacityType = restored.Spec.CapacityType
9393
dst.Spec.RoleAdditionalPolicies = restored.Spec.RoleAdditionalPolicies
94+
dst.Spec.UpdateConfig = restored.Spec.UpdateConfig
9495

9596
return nil
9697
}

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/conversion.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ func (src *AWSManagedMachinePool) ConvertTo(dstRaw conversion.Hub) error {
6464
}
6565

6666
dst.Spec.RoleAdditionalPolicies = restored.Spec.RoleAdditionalPolicies
67+
dst.Spec.UpdateConfig = restored.Spec.UpdateConfig
6768

6869
return nil
6970
}

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/awsmanagedmachinepool_types.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,11 @@ type AWSManagedMachinePoolSpec struct {
144144
// +kubebuilder:default:=onDemand
145145
// +optional
146146
CapacityType *ManagedMachinePoolCapacityType `json:"capacityType,omitempty"`
147+
148+
// UpdateConfig holds the optional config to control the behaviour of the update
149+
// to the nodegroup.
150+
// +optional
151+
UpdateConfig *UpdateConfig `json:"updateConfig,omitempty"`
147152
}
148153

149154
// ManagedMachinePoolScaling specifies scaling options.

exp/api/v1beta1/awsmanagedmachinepool_webhook.go

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,27 @@ func (r *AWSManagedMachinePool) validateScaling() field.ErrorList {
7676
return allErrs
7777
}
7878

79+
func (r *AWSManagedMachinePool) validateNodegroupUpdateConfig() field.ErrorList {
80+
var allErrs field.ErrorList
81+
82+
if r.Spec.UpdateConfig != nil {
83+
nodegroupUpdateConfigField := field.NewPath("spec", "updateConfig")
84+
85+
if r.Spec.UpdateConfig.MaxUnavailable == nil && r.Spec.UpdateConfig.MaxUnavailablePercentage == nil {
86+
allErrs = append(allErrs, field.Invalid(nodegroupUpdateConfigField, r.Spec.UpdateConfig, "must specify one of maxUnavailable or maxUnavailablePercentage when using nodegroup updateconfig"))
87+
}
88+
89+
if r.Spec.UpdateConfig.MaxUnavailable != nil && r.Spec.UpdateConfig.MaxUnavailablePercentage != nil {
90+
allErrs = append(allErrs, field.Invalid(nodegroupUpdateConfigField, r.Spec.UpdateConfig, "cannot specify both maxUnavailable and maxUnavailablePercentage"))
91+
}
92+
}
93+
94+
if len(allErrs) == 0 {
95+
return nil
96+
}
97+
return allErrs
98+
}
99+
79100
func (r *AWSManagedMachinePool) validateRemoteAccess() field.ErrorList {
80101
var allErrs field.ErrorList
81102
if r.Spec.RemoteAccess == nil {
@@ -109,6 +130,9 @@ func (r *AWSManagedMachinePool) ValidateCreate() error {
109130
if errs := r.validateRemoteAccess(); len(errs) > 0 {
110131
allErrs = append(allErrs, errs...)
111132
}
133+
if errs := r.validateNodegroupUpdateConfig(); len(errs) > 0 {
134+
allErrs = append(allErrs, errs...)
135+
}
112136

113137
allErrs = append(allErrs, r.Spec.AdditionalTags.Validate()...)
114138

@@ -140,6 +164,9 @@ func (r *AWSManagedMachinePool) ValidateUpdate(old runtime.Object) error {
140164
if errs := r.validateScaling(); errs != nil || len(errs) == 0 {
141165
allErrs = append(allErrs, errs...)
142166
}
167+
if errs := r.validateNodegroupUpdateConfig(); len(errs) > 0 {
168+
allErrs = append(allErrs, errs...)
169+
}
143170

144171
if len(allErrs) == 0 {
145172
return nil

exp/api/v1beta1/awsmanagedmachinepool_webhook_test.go

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import (
2020
"strings"
2121
"testing"
2222

23+
"github.com/aws/aws-sdk-go/aws"
2324
. "github.com/onsi/gomega"
2425
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
2526

@@ -90,6 +91,41 @@ func TestAWSManagedMachinePool_ValidateCreate(t *testing.T) {
9091
},
9192
wantErr: true,
9293
},
94+
{
95+
name: "valid update config",
96+
pool: &AWSManagedMachinePool{
97+
Spec: AWSManagedMachinePoolSpec{
98+
EKSNodegroupName: "eks-node-group-3",
99+
UpdateConfig: &UpdateConfig{
100+
MaxUnavailable: aws.Int(1),
101+
},
102+
},
103+
},
104+
wantErr: false,
105+
},
106+
{
107+
name: "update config with no values",
108+
pool: &AWSManagedMachinePool{
109+
Spec: AWSManagedMachinePoolSpec{
110+
EKSNodegroupName: "eks-node-group-3",
111+
UpdateConfig: &UpdateConfig{},
112+
},
113+
},
114+
wantErr: true,
115+
},
116+
{
117+
name: "update config with both values",
118+
pool: &AWSManagedMachinePool{
119+
Spec: AWSManagedMachinePoolSpec{
120+
EKSNodegroupName: "eks-node-group-3",
121+
UpdateConfig: &UpdateConfig{
122+
MaxUnavailable: aws.Int(1),
123+
MaxUnavailablePercentage: aws.Int(10),
124+
},
125+
},
126+
},
127+
wantErr: true,
128+
},
93129
}
94130
for _, tt := range tests {
95131
t.Run(tt.name, func(t *testing.T) {
@@ -170,6 +206,40 @@ func TestAWSManagedMachinePool_ValidateUpdate(t *testing.T) {
170206
},
171207
wantErr: true,
172208
},
209+
{
210+
name: "adding update config is accepted",
211+
old: &AWSManagedMachinePool{
212+
Spec: AWSManagedMachinePoolSpec{
213+
EKSNodegroupName: "eks-node-group-1",
214+
},
215+
},
216+
new: &AWSManagedMachinePool{
217+
Spec: AWSManagedMachinePoolSpec{
218+
EKSNodegroupName: "eks-node-group-1",
219+
UpdateConfig: &UpdateConfig{
220+
MaxUnavailablePercentage: aws.Int(10),
221+
},
222+
},
223+
},
224+
wantErr: false,
225+
},
226+
{
227+
name: "removing update config is accepted",
228+
old: &AWSManagedMachinePool{
229+
Spec: AWSManagedMachinePoolSpec{
230+
EKSNodegroupName: "eks-node-group-1",
231+
UpdateConfig: &UpdateConfig{
232+
MaxUnavailablePercentage: aws.Int(10),
233+
},
234+
},
235+
},
236+
new: &AWSManagedMachinePool{
237+
Spec: AWSManagedMachinePoolSpec{
238+
EKSNodegroupName: "eks-node-group-1",
239+
},
240+
},
241+
wantErr: false,
242+
},
173243
}
174244
for _, tt := range tests {
175245
t.Run(tt.name, func(t *testing.T) {

exp/api/v1beta1/types.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -251,3 +251,21 @@ func (t *Taints) Contains(taint *Taint) bool {
251251

252252
return false
253253
}
254+
255+
// UpdateConfig is the configuration options for updating a nodegroup. Only one of MaxUnavailable
256+
// and MaxUnavailablePercentage should be specified.
257+
type UpdateConfig struct {
258+
// MaxUnavailable is the maximum number of nodes unavailable at once during a version update.
259+
// Nodes will be updated in parallel. The maximum number is 100.
260+
// +optional
261+
// +kubebuilder:validation:Maximum=100
262+
// +kubebuilder:validation:Minimum=1
263+
MaxUnavailable *int `json:"maxUnavailable,omitempty"`
264+
265+
// MaxUnavailablePercentage is the maximum percentage of nodes unavailable during a version update. This
266+
// percentage of nodes will be updated in parallel, up to 100 nodes at once.
267+
// +optional
268+
// +kubebuilder:validation:Maximum=100
269+
// +kubebuilder:validation:Minimum=1
270+
MaxUnavailablePercentage *int `json:"maxUnavailablePrecentage,omitempty"`
271+
}

exp/api/v1beta1/zz_generated.deepcopy.go

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

0 commit comments

Comments
 (0)