Skip to content

Commit 599e7ab

Browse files
punkwalkerAmitSahastra
authored andcommitted
Initial changes for supporting HostResourceGroupArn parameter in AWSMachine.Spec
Signed-off-by: Pankaj Walke <[email protected]>
1 parent 125ac27 commit 599e7ab

15 files changed

+592
-0
lines changed

api/v1beta1/awscluster_conversion.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,14 @@ func (src *AWSCluster) ConvertTo(dstRaw conversion.Hub) error {
6262
dst.Status.Bastion.NetworkInterfaceType = restored.Status.Bastion.NetworkInterfaceType
6363
dst.Status.Bastion.CapacityReservationID = restored.Status.Bastion.CapacityReservationID
6464
dst.Status.Bastion.MarketType = restored.Status.Bastion.MarketType
65+
dst.Status.Bastion.HostAffinity = restored.Status.Bastion.HostAffinity
66+
dst.Status.Bastion.HostID = restored.Status.Bastion.HostID
67+
dst.Status.Bastion.HostResourceGroupArn = restored.Status.Bastion.HostResourceGroupArn
68+
dst.Status.Bastion.CapacityReservationPreference = restored.Status.Bastion.CapacityReservationPreference
69+
dst.Status.Bastion.CPUOptions = restored.Status.Bastion.CPUOptions
70+
if restored.Status.Bastion.DynamicHostAllocation != nil {
71+
dst.Status.Bastion.DynamicHostAllocation = restored.Status.Bastion.DynamicHostAllocation
72+
}
6573
}
6674
dst.Spec.Partition = restored.Spec.Partition
6775

api/v1beta1/awsmachine_conversion.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,10 @@ func (src *AWSMachine) ConvertTo(dstRaw conversion.Hub) error {
4343
dst.Spec.SecurityGroupOverrides = restored.Spec.SecurityGroupOverrides
4444
dst.Spec.CapacityReservationID = restored.Spec.CapacityReservationID
4545
dst.Spec.MarketType = restored.Spec.MarketType
46+
dst.Spec.HostID = restored.Spec.HostID
47+
dst.Spec.HostResourceGroupArn = restored.Spec.HostResourceGroupArn
48+
dst.Spec.HostAffinity = restored.Spec.HostAffinity
49+
dst.Spec.CapacityReservationPreference = restored.Spec.CapacityReservationPreference
4650
dst.Spec.NetworkInterfaceType = restored.Spec.NetworkInterfaceType
4751
if restored.Spec.ElasticIPPool != nil {
4852
if dst.Spec.ElasticIPPool == nil {
@@ -107,6 +111,10 @@ func (r *AWSMachineTemplate) ConvertTo(dstRaw conversion.Hub) error {
107111
dst.Spec.Template.Spec.SecurityGroupOverrides = restored.Spec.Template.Spec.SecurityGroupOverrides
108112
dst.Spec.Template.Spec.CapacityReservationID = restored.Spec.Template.Spec.CapacityReservationID
109113
dst.Spec.Template.Spec.MarketType = restored.Spec.Template.Spec.MarketType
114+
dst.Spec.Template.Spec.HostID = restored.Spec.Template.Spec.HostID
115+
dst.Spec.Template.Spec.HostResourceGroupArn = restored.Spec.Template.Spec.HostResourceGroupArn
116+
dst.Spec.Template.Spec.HostAffinity = restored.Spec.Template.Spec.HostAffinity
117+
dst.Spec.Template.Spec.CapacityReservationPreference = restored.Spec.Template.Spec.CapacityReservationPreference
110118
dst.Spec.Template.Spec.NetworkInterfaceType = restored.Spec.Template.Spec.NetworkInterfaceType
111119
if restored.Spec.Template.Spec.ElasticIPPool != nil {
112120
if dst.Spec.Template.Spec.ElasticIPPool == nil {

api/v1beta1/zz_generated.conversion.go

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

api/v1beta2/awsmachine_types.go

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,53 @@ type AWSMachineSpec struct {
221221
// If marketType is not specified and spotMarketOptions is provided, the marketType defaults to "Spot".
222222
// +optional
223223
MarketType MarketType `json:"marketType,omitempty"`
224+
225+
// HostID specifies the Dedicated Host on which the instance must be started.
226+
// This field is mutually exclusive with DynamicHostAllocation.
227+
// +kubebuilder:validation:Pattern=`^h-[0-9a-f]{17}$`
228+
// +kubebuilder:validation:MaxLength=19
229+
// +optional
230+
HostID *string `json:"hostID,omitempty"`
231+
232+
// HostResourceGroupArn specifies the Dedicated Host Resource Group ARN on which the instance must be started.
233+
// This field is mutually exclusive with DynamicHostAllocation and HostID.
234+
// Note: The instance's AMI licenses must match the licenses associated with the host resource group.
235+
// If the host resource group has no associated licenses, ensure the AMI also has no special licensing requirements.
236+
// +kubebuilder:validation:Pattern=`^arn:aws[a-z\-]*:resource-groups:[a-z0-9\-]+:[0-9]{12}:group/[a-zA-Z0-9\-_]+$`
237+
// +optional
238+
HostResourceGroupArn *string `json:"hostResourceGroupArn,omitempty"`
239+
240+
// HostAffinity specifies the dedicated host affinity setting for the instance.
241+
// When HostAffinity is set to host, an instance started onto a specific host always restarts on the same host if stopped.
242+
// When HostAffinity is set to default, and you stop and restart the instance, it can be restarted on any available host.
243+
// When HostAffinity is defined, HostID is required.
244+
// +optional
245+
// +kubebuilder:validation:Enum:=default;host
246+
// +kubebuilder:default=host
247+
HostAffinity *string `json:"hostAffinity,omitempty"`
248+
249+
// DynamicHostAllocation enables automatic allocation of a single dedicated host.
250+
// This field is mutually exclusive with HostID and always allocates exactly one host.
251+
// Cost effectiveness of allocating a single instance on a dedicated host may vary
252+
// depending on the instance type and the region.
253+
// +optional
254+
DynamicHostAllocation *DynamicHostAllocationSpec `json:"dynamicHostAllocation,omitempty"`
255+
256+
// CapacityReservationPreference specifies the preference for use of Capacity Reservations by the instance. Valid values include:
257+
// "Open": The instance may make use of open Capacity Reservations that match its AZ and InstanceType
258+
// "None": The instance may not make use of any Capacity Reservations. This is to conserve open reservations for desired workloads
259+
// "CapacityReservationsOnly": The instance will only run if matched or targeted to a Capacity Reservation. Note that this is incompatible with a MarketType of `Spot`
260+
// +kubebuilder:validation:Enum="";None;CapacityReservationsOnly;Open
261+
// +optional
262+
CapacityReservationPreference CapacityReservationPreference `json:"capacityReservationPreference,omitempty"`
263+
}
264+
265+
// DynamicHostAllocationSpec defines the configuration for dynamic dedicated host allocation.
266+
// This specification always allocates exactly one dedicated host per machine.
267+
type DynamicHostAllocationSpec struct {
268+
// Tags to apply to the allocated dedicated host.
269+
// +optional
270+
Tags map[string]string `json:"tags,omitempty"`
224271
}
225272

226273
// CloudInit defines options related to the bootstrapping systems where

api/v1beta2/awsmachine_webhook.go

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -458,6 +458,32 @@ func (r *AWSMachine) validateAdditionalSecurityGroups() field.ErrorList {
458458
return allErrs
459459
}
460460

461+
func (r *AWSMachine) validateHostAllocation() field.ErrorList {
462+
var allErrs field.ErrorList
463+
464+
// Check if multiple host allocation options are specified
465+
hasHostID := r.Spec.HostID != nil && len(*r.Spec.HostID) > 0
466+
hasHostResourceGroupArn := r.Spec.HostResourceGroupArn != nil && len(*r.Spec.HostResourceGroupArn) > 0
467+
hasDynamicHostAllocation := r.Spec.DynamicHostAllocation != nil
468+
469+
count := 0
470+
if hasHostID {
471+
count++
472+
}
473+
if hasHostResourceGroupArn {
474+
count++
475+
}
476+
if hasDynamicHostAllocation {
477+
count++
478+
}
479+
480+
if count > 1 {
481+
allErrs = append(allErrs, field.Forbidden(field.NewPath("spec"), "hostID, hostResourceGroupArn, and dynamicHostAllocation are mutually exclusive"))
482+
}
483+
484+
return allErrs
485+
}
486+
461487
func (r *AWSMachine) validateSSHKeyName() field.ErrorList {
462488
return validateSSHKeyName(r.Spec.SSHKeyName)
463489
}

api/v1beta2/awsmachine_webhook_test.go

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -493,6 +493,97 @@ func TestAWSMachineCreate(t *testing.T) {
493493
},
494494
wantErr: true,
495495
},
496+
{
497+
name: "hostID and dynamicHostAllocation are mutually exclusive",
498+
machine: &AWSMachine{
499+
Spec: AWSMachineSpec{
500+
InstanceType: "test",
501+
HostID: aws.String("h-1234567890abcdef0"),
502+
DynamicHostAllocation: &DynamicHostAllocationSpec{
503+
Tags: map[string]string{
504+
"Environment": "test",
505+
},
506+
},
507+
},
508+
},
509+
wantErr: true,
510+
},
511+
{
512+
name: "hostID alone is valid",
513+
machine: &AWSMachine{
514+
Spec: AWSMachineSpec{
515+
InstanceType: "test",
516+
HostID: aws.String("h-1234567890abcdef0"),
517+
},
518+
},
519+
wantErr: false,
520+
},
521+
{
522+
name: "dynamicHostAllocation alone is valid",
523+
machine: &AWSMachine{
524+
Spec: AWSMachineSpec{
525+
InstanceType: "test",
526+
DynamicHostAllocation: &DynamicHostAllocationSpec{
527+
Tags: map[string]string{
528+
"Environment": "test",
529+
},
530+
},
531+
},
532+
},
533+
wantErr: false,
534+
},
535+
{
536+
name: "hostResourceGroupArn alone is valid",
537+
machine: &AWSMachine{
538+
Spec: AWSMachineSpec{
539+
InstanceType: "test",
540+
HostResourceGroupArn: aws.String("arn:aws:resource-groups:us-west-2:123456789012:group/test-group"),
541+
},
542+
},
543+
wantErr: false,
544+
},
545+
{
546+
name: "hostID and hostResourceGroupArn are mutually exclusive",
547+
machine: &AWSMachine{
548+
Spec: AWSMachineSpec{
549+
InstanceType: "test",
550+
HostID: aws.String("h-1234567890abcdef0"),
551+
HostResourceGroupArn: aws.String("arn:aws:resource-groups:us-west-2:123456789012:group/test-group"),
552+
},
553+
},
554+
wantErr: true,
555+
},
556+
{
557+
name: "hostResourceGroupArn and dynamicHostAllocation are mutually exclusive",
558+
machine: &AWSMachine{
559+
Spec: AWSMachineSpec{
560+
InstanceType: "test",
561+
HostResourceGroupArn: aws.String("arn:aws:resource-groups:us-west-2:123456789012:group/test-group"),
562+
DynamicHostAllocation: &DynamicHostAllocationSpec{
563+
Tags: map[string]string{
564+
"Environment": "test",
565+
},
566+
},
567+
},
568+
},
569+
wantErr: true,
570+
},
571+
{
572+
name: "all three host allocation options are mutually exclusive",
573+
machine: &AWSMachine{
574+
Spec: AWSMachineSpec{
575+
InstanceType: "test",
576+
HostID: aws.String("h-1234567890abcdef0"),
577+
HostResourceGroupArn: aws.String("arn:aws:resource-groups:us-west-2:123456789012:group/test-group"),
578+
DynamicHostAllocation: &DynamicHostAllocationSpec{
579+
Tags: map[string]string{
580+
"Environment": "test",
581+
},
582+
},
583+
},
584+
},
585+
wantErr: true,
586+
},
496587
}
497588
for _, tt := range tests {
498589
t.Run(tt.name, func(t *testing.T) {

api/v1beta2/awsmachinetemplate_webhook.go

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,35 @@ func (r *AWSMachineTemplate) validateIgnitionAndCloudInit() field.ErrorList {
171171

172172
return allErrs
173173
}
174+
175+
func (r *AWSMachineTemplate) validateHostAllocation() field.ErrorList {
176+
var allErrs field.ErrorList
177+
178+
spec := r.Spec.Template.Spec
179+
180+
// Check if multiple host allocation options are specified
181+
hasHostID := spec.HostID != nil && len(*spec.HostID) > 0
182+
hasHostResourceGroupArn := spec.HostResourceGroupArn != nil && len(*spec.HostResourceGroupArn) > 0
183+
hasDynamicHostAllocation := spec.DynamicHostAllocation != nil
184+
185+
count := 0
186+
if hasHostID {
187+
count++
188+
}
189+
if hasHostResourceGroupArn {
190+
count++
191+
}
192+
if hasDynamicHostAllocation {
193+
count++
194+
}
195+
196+
if count > 1 {
197+
allErrs = append(allErrs, field.Forbidden(field.NewPath("spec.template.spec"), "hostID, hostResourceGroupArn, and dynamicHostAllocation are mutually exclusive"))
198+
}
199+
200+
return allErrs
201+
}
202+
174203
func (r *AWSMachineTemplate) validateSSHKeyName() field.ErrorList {
175204
return validateSSHKeyName(r.Spec.Template.Spec.SSHKeyName)
176205
}

api/v1beta2/awsmachinetemplate_webhook_test.go

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,77 @@ func TestAWSMachineTemplateValidateCreate(t *testing.T) {
8080
},
8181
wantError: false,
8282
},
83+
{
84+
name: "hostID and dynamicHostAllocation are mutually exclusive",
85+
inputTemplate: &AWSMachineTemplate{
86+
ObjectMeta: metav1.ObjectMeta{},
87+
Spec: AWSMachineTemplateSpec{
88+
Template: AWSMachineTemplateResource{
89+
Spec: AWSMachineSpec{
90+
InstanceType: "test",
91+
HostID: aws.String("h-1234567890abcdef0"),
92+
DynamicHostAllocation: &DynamicHostAllocationSpec{
93+
Tags: map[string]string{
94+
"Environment": "test",
95+
},
96+
},
97+
},
98+
},
99+
},
100+
},
101+
wantError: true,
102+
},
103+
{
104+
name: "hostResourceGroupArn alone is valid",
105+
inputTemplate: &AWSMachineTemplate{
106+
ObjectMeta: metav1.ObjectMeta{},
107+
Spec: AWSMachineTemplateSpec{
108+
Template: AWSMachineTemplateResource{
109+
Spec: AWSMachineSpec{
110+
InstanceType: "test",
111+
HostResourceGroupArn: aws.String("arn:aws:resource-groups:us-west-2:123456789012:group/test-group"),
112+
},
113+
},
114+
},
115+
},
116+
wantError: false,
117+
},
118+
{
119+
name: "hostID and hostResourceGroupArn are mutually exclusive",
120+
inputTemplate: &AWSMachineTemplate{
121+
ObjectMeta: metav1.ObjectMeta{},
122+
Spec: AWSMachineTemplateSpec{
123+
Template: AWSMachineTemplateResource{
124+
Spec: AWSMachineSpec{
125+
InstanceType: "test",
126+
HostID: aws.String("h-1234567890abcdef0"),
127+
HostResourceGroupArn: aws.String("arn:aws:resource-groups:us-west-2:123456789012:group/test-group"),
128+
},
129+
},
130+
},
131+
},
132+
wantError: true,
133+
},
134+
{
135+
name: "hostResourceGroupArn and dynamicHostAllocation are mutually exclusive",
136+
inputTemplate: &AWSMachineTemplate{
137+
ObjectMeta: metav1.ObjectMeta{},
138+
Spec: AWSMachineTemplateSpec{
139+
Template: AWSMachineTemplateResource{
140+
Spec: AWSMachineSpec{
141+
InstanceType: "test",
142+
HostResourceGroupArn: aws.String("arn:aws:resource-groups:us-west-2:123456789012:group/test-group"),
143+
DynamicHostAllocation: &DynamicHostAllocationSpec{
144+
Tags: map[string]string{
145+
"Environment": "test",
146+
},
147+
},
148+
},
149+
},
150+
},
151+
},
152+
wantError: true,
153+
},
83154
}
84155
for _, tt := range tests {
85156
t.Run(tt.name, func(t *testing.T) {

0 commit comments

Comments
 (0)