Skip to content

Commit 282cf95

Browse files
committed
feat: add capacity reservation group support
Add v1beta2 fields for targeting capacity reservation resource group ARNs from AWSMachine and AWSLaunchTemplate. Plumb the field through EC2 instance and launch template request generation, conversion restore paths, webhook validation, and generated CRDs. Keep reservation IDs and resource group ARNs mutually exclusive. Signed-off-by: Justin Miron <justin.miron@reddit.com>
1 parent 3f6ef66 commit 282cf95

26 files changed

Lines changed: 805 additions & 69 deletions

api/v1beta1/awscluster_conversion.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ func (src *AWSCluster) ConvertTo(dstRaw conversion.Hub) error {
6363
dst.Status.Bastion.NetworkInterfaceType = restored.Status.Bastion.NetworkInterfaceType
6464
dst.Status.Bastion.AssignPrimaryIPv6 = restored.Status.Bastion.AssignPrimaryIPv6
6565
dst.Status.Bastion.CapacityReservationID = restored.Status.Bastion.CapacityReservationID
66+
dst.Status.Bastion.CapacityReservationResourceGroupARN = restored.Status.Bastion.CapacityReservationResourceGroupARN
6667
dst.Status.Bastion.MarketType = restored.Status.Bastion.MarketType
6768
dst.Status.Bastion.HostAffinity = restored.Status.Bastion.HostAffinity
6869
dst.Status.Bastion.HostID = restored.Status.Bastion.HostID

api/v1beta1/awsmachine_conversion.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ func (src *AWSMachine) ConvertTo(dstRaw conversion.Hub) error {
4343
dst.Spec.PrivateDNSName = restored.Spec.PrivateDNSName
4444
dst.Spec.SecurityGroupOverrides = restored.Spec.SecurityGroupOverrides
4545
dst.Spec.CapacityReservationID = restored.Spec.CapacityReservationID
46+
dst.Spec.CapacityReservationResourceGroupARN = restored.Spec.CapacityReservationResourceGroupARN
4647
dst.Spec.MarketType = restored.Spec.MarketType
4748
dst.Spec.HostID = restored.Spec.HostID
4849
dst.Spec.HostAffinity = restored.Spec.HostAffinity
@@ -116,6 +117,7 @@ func (r *AWSMachineTemplate) ConvertTo(dstRaw conversion.Hub) error {
116117
dst.Spec.Template.Spec.PrivateDNSName = restored.Spec.Template.Spec.PrivateDNSName
117118
dst.Spec.Template.Spec.SecurityGroupOverrides = restored.Spec.Template.Spec.SecurityGroupOverrides
118119
dst.Spec.Template.Spec.CapacityReservationID = restored.Spec.Template.Spec.CapacityReservationID
120+
dst.Spec.Template.Spec.CapacityReservationResourceGroupARN = restored.Spec.Template.Spec.CapacityReservationResourceGroupARN
119121
dst.Spec.Template.Spec.MarketType = restored.Spec.Template.Spec.MarketType
120122
dst.Spec.Template.Spec.HostID = restored.Spec.Template.Spec.HostID
121123
dst.Spec.Template.Spec.HostAffinity = restored.Spec.Template.Spec.HostAffinity

api/v1beta1/zz_generated.conversion.go

Lines changed: 2 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: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -74,8 +74,9 @@ const (
7474
)
7575

7676
// AWSMachineSpec defines the desired state of an Amazon EC2 instance.
77-
// +kubebuilder:validation:XValidation:rule="!has(self.capacityReservationId) || !has(self.marketType) || self.marketType != 'Spot'",message="capacityReservationId may not be set when marketType is Spot"
78-
// +kubebuilder:validation:XValidation:rule="!has(self.capacityReservationId) || !has(self.spotMarketOptions)",message="capacityReservationId cannot be set when spotMarketOptions is specified"
77+
// +kubebuilder:validation:XValidation:rule="!has(self.capacityReservationId) || !has(self.capacityReservationResourceGroupARN)",message="capacityReservationId and capacityReservationResourceGroupARN are mutually exclusive"
78+
// +kubebuilder:validation:XValidation:rule="!(has(self.capacityReservationId) || has(self.capacityReservationResourceGroupARN)) || !has(self.marketType) || self.marketType != 'Spot'",message="capacity reservation targets may not be set when marketType is Spot"
79+
// +kubebuilder:validation:XValidation:rule="!(has(self.capacityReservationId) || has(self.capacityReservationResourceGroupARN)) || !has(self.spotMarketOptions)",message="capacity reservation targets cannot be set when spotMarketOptions is specified"
7980
type AWSMachineSpec struct {
8081
// ProviderID is the unique identifier as specified by the cloud provider.
8182
ProviderID *string `json:"providerID,omitempty"`
@@ -246,11 +247,15 @@ type AWSMachineSpec struct {
246247
// +optional
247248
CapacityReservationID *string `json:"capacityReservationId,omitempty"`
248249

250+
// CapacityReservationResourceGroupARN specifies the ARN of the target Capacity Reservation resource group in which to launch the instance.
251+
// +optional
252+
CapacityReservationResourceGroupARN *string `json:"capacityReservationResourceGroupARN,omitempty"`
253+
249254
// MarketType specifies the type of market for the EC2 instance. Valid values include:
250255
// "OnDemand" (default): The instance runs as a standard OnDemand instance.
251256
// "Spot": The instance runs as a Spot instance. When SpotMarketOptions is provided, the marketType defaults to "Spot".
252257
// "CapacityBlock": The instance utilizes pre-purchased compute capacity (capacity blocks) with AWS Capacity Reservations.
253-
// If this value is selected, CapacityReservationID must be specified to identify the target reservation.
258+
// If this value is selected, either CapacityReservationID or CapacityReservationResourceGroupARN must be specified to identify the target reservation.
254259
// If marketType is not specified and spotMarketOptions is provided, the marketType defaults to "Spot".
255260
// +optional
256261
MarketType MarketType `json:"marketType,omitempty"`

api/v1beta2/types.go

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -271,11 +271,15 @@ type Instance struct {
271271
// +optional
272272
CapacityReservationID *string `json:"capacityReservationId,omitempty"`
273273

274+
// CapacityReservationResourceGroupARN specifies the ARN of the target Capacity Reservation resource group in which to launch the instance.
275+
// +optional
276+
CapacityReservationResourceGroupARN *string `json:"capacityReservationResourceGroupARN,omitempty"`
277+
274278
// MarketType specifies the type of market for the EC2 instance. Valid values include:
275279
// "OnDemand" (default): The instance runs as a standard OnDemand instance.
276280
// "Spot": The instance runs as a Spot instance. When SpotMarketOptions is provided, the marketType defaults to "Spot".
277281
// "CapacityBlock": The instance utilizes pre-purchased compute capacity (capacity blocks) with AWS Capacity Reservations.
278-
// If this value is selected, CapacityReservationID must be specified to identify the target reservation.
282+
// If this value is selected, either CapacityReservationID or CapacityReservationResourceGroupARN must be specified to identify the target reservation.
279283
// If marketType is not specified and spotMarketOptions is provided, the marketType defaults to "Spot".
280284
// +optional
281285
MarketType MarketType `json:"marketType,omitempty"`
@@ -314,6 +318,16 @@ type Instance struct {
314318
CPUOptions CPUOptions `json:"cpuOptions,omitempty,omitzero"`
315319
}
316320

321+
// HasCapacityReservationTarget returns true when either supported capacity reservation target is set.
322+
func HasCapacityReservationTarget(capacityReservationID, capacityReservationResourceGroupARN *string) bool {
323+
return capacityReservationID != nil || capacityReservationResourceGroupARN != nil
324+
}
325+
326+
// HasConflictingCapacityReservationTargets returns true when more than one capacity reservation target is set.
327+
func HasConflictingCapacityReservationTargets(capacityReservationID, capacityReservationResourceGroupARN *string) bool {
328+
return capacityReservationID != nil && capacityReservationResourceGroupARN != nil
329+
}
330+
317331
// CapacityReservationPreference describes the preferred use of capacity reservations
318332
// of an instance
319333
// +kubebuilder:validation:Enum:="";None;CapacityReservationsOnly;Open

api/v1beta2/zz_generated.deepcopy.go

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

config/crd/bases/controlplane.cluster.x-k8s.io_awsmanagedcontrolplanes.yaml

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1241,6 +1241,11 @@ spec:
12411241
"None": The instance may not make use of any Capacity Reservations. This is to conserve open reservations for desired workloads
12421242
"CapacityReservationsOnly": The instance will only run if matched or targeted to a Capacity Reservation. Note that this is incompatible with a MarketType of `Spot`
12431243
type: string
1244+
capacityReservationResourceGroupARN:
1245+
description: CapacityReservationResourceGroupARN specifies the
1246+
ARN of the target Capacity Reservation resource group in which
1247+
to launch the instance.
1248+
type: string
12441249
cpuOptions:
12451250
description: |-
12461251
CPUOptions defines CPU-related settings for the instance, including the confidential computing policy.
@@ -1405,7 +1410,7 @@ spec:
14051410
"OnDemand" (default): The instance runs as a standard OnDemand instance.
14061411
"Spot": The instance runs as a Spot instance. When SpotMarketOptions is provided, the marketType defaults to "Spot".
14071412
"CapacityBlock": The instance utilizes pre-purchased compute capacity (capacity blocks) with AWS Capacity Reservations.
1408-
If this value is selected, CapacityReservationID must be specified to identify the target reservation.
1413+
If this value is selected, either CapacityReservationID or CapacityReservationResourceGroupARN must be specified to identify the target reservation.
14091414
If marketType is not specified and spotMarketOptions is provided, the marketType defaults to "Spot".
14101415
enum:
14111416
- OnDemand
@@ -3662,6 +3667,11 @@ spec:
36623667
"None": The instance may not make use of any Capacity Reservations. This is to conserve open reservations for desired workloads
36633668
"CapacityReservationsOnly": The instance will only run if matched or targeted to a Capacity Reservation. Note that this is incompatible with a MarketType of `Spot`
36643669
type: string
3670+
capacityReservationResourceGroupARN:
3671+
description: CapacityReservationResourceGroupARN specifies the
3672+
ARN of the target Capacity Reservation resource group in which
3673+
to launch the instance.
3674+
type: string
36653675
cpuOptions:
36663676
description: |-
36673677
CPUOptions defines CPU-related settings for the instance, including the confidential computing policy.
@@ -3826,7 +3836,7 @@ spec:
38263836
"OnDemand" (default): The instance runs as a standard OnDemand instance.
38273837
"Spot": The instance runs as a Spot instance. When SpotMarketOptions is provided, the marketType defaults to "Spot".
38283838
"CapacityBlock": The instance utilizes pre-purchased compute capacity (capacity blocks) with AWS Capacity Reservations.
3829-
If this value is selected, CapacityReservationID must be specified to identify the target reservation.
3839+
If this value is selected, either CapacityReservationID or CapacityReservationResourceGroupARN must be specified to identify the target reservation.
38303840
If marketType is not specified and spotMarketOptions is provided, the marketType defaults to "Spot".
38313841
enum:
38323842
- OnDemand

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

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2262,6 +2262,11 @@ spec:
22622262
"None": The instance may not make use of any Capacity Reservations. This is to conserve open reservations for desired workloads
22632263
"CapacityReservationsOnly": The instance will only run if matched or targeted to a Capacity Reservation. Note that this is incompatible with a MarketType of `Spot`
22642264
type: string
2265+
capacityReservationResourceGroupARN:
2266+
description: CapacityReservationResourceGroupARN specifies the
2267+
ARN of the target Capacity Reservation resource group in which
2268+
to launch the instance.
2269+
type: string
22652270
cpuOptions:
22662271
description: |-
22672272
CPUOptions defines CPU-related settings for the instance, including the confidential computing policy.
@@ -2426,7 +2431,7 @@ spec:
24262431
"OnDemand" (default): The instance runs as a standard OnDemand instance.
24272432
"Spot": The instance runs as a Spot instance. When SpotMarketOptions is provided, the marketType defaults to "Spot".
24282433
"CapacityBlock": The instance utilizes pre-purchased compute capacity (capacity blocks) with AWS Capacity Reservations.
2429-
If this value is selected, CapacityReservationID must be specified to identify the target reservation.
2434+
If this value is selected, either CapacityReservationID or CapacityReservationResourceGroupARN must be specified to identify the target reservation.
24302435
If marketType is not specified and spotMarketOptions is provided, the marketType defaults to "Spot".
24312436
enum:
24322437
- OnDemand

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

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -662,6 +662,11 @@ spec:
662662
"None": The instance may not make use of any Capacity Reservations. This is to conserve open reservations for desired workloads
663663
"CapacityReservationsOnly": The instance will only run if matched or targeted to a Capacity Reservation
664664
type: string
665+
capacityReservationResourceGroupARN:
666+
description: CapacityReservationResourceGroupARN specifies the
667+
ARN of the target Capacity Reservation resource group in which
668+
to launch the instance.
669+
type: string
665670
enclaveOptions:
666671
description: EnclaveOptions defines the options for Nitro Enclave
667672
support on the instance.
@@ -782,7 +787,7 @@ spec:
782787
"OnDemand" (default): The instance runs as a standard OnDemand instance.
783788
"Spot": The instance runs as a Spot instance. When SpotMarketOptions is provided, the marketType defaults to "Spot".
784789
"CapacityBlock": The instance utilizes pre-purchased compute capacity (capacity blocks) with AWS Capacity Reservations.
785-
If this value is selected, CapacityReservationID must be specified to identify the target reservation.
790+
If this value is selected, either CapacityReservationID or CapacityReservationResourceGroupARN must be specified to identify the target reservation.
786791
If marketType is not specified and spotMarketOptions is provided, the marketType defaults to "Spot".
787792
enum:
788793
- OnDemand
@@ -921,6 +926,18 @@ spec:
921926
format: int64
922927
type: integer
923928
type: object
929+
x-kubernetes-validations:
930+
- message: capacityReservationId and capacityReservationResourceGroupARN
931+
are mutually exclusive
932+
rule: '!has(self.capacityReservationId) || !has(self.capacityReservationResourceGroupARN)'
933+
- message: capacity reservation targets may not be set when marketType
934+
is Spot
935+
rule: '!(has(self.capacityReservationId) || has(self.capacityReservationResourceGroupARN))
936+
|| !has(self.marketType) || self.marketType != ''Spot'''
937+
- message: capacity reservation targets cannot be set when spotMarketOptions
938+
is specified
939+
rule: '!(has(self.capacityReservationId) || has(self.capacityReservationResourceGroupARN))
940+
|| !has(self.spotMarketOptions)'
924941
capacityRebalance:
925942
description: Enable or disable the capacity rebalance autoscaling
926943
group feature

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

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -674,6 +674,11 @@ spec:
674674
"None": The instance may not make use of any Capacity Reservations. This is to conserve open reservations for desired workloads
675675
"CapacityReservationsOnly": The instance will only run if matched or targeted to a Capacity Reservation. Note that this is incompatible with a MarketType of `Spot`
676676
type: string
677+
capacityReservationResourceGroupARN:
678+
description: CapacityReservationResourceGroupARN specifies the ARN
679+
of the target Capacity Reservation resource group in which to launch
680+
the instance.
681+
type: string
677682
cloudInit:
678683
description: |-
679684
CloudInit defines options related to the bootstrapping systems where
@@ -1015,7 +1020,7 @@ spec:
10151020
"OnDemand" (default): The instance runs as a standard OnDemand instance.
10161021
"Spot": The instance runs as a Spot instance. When SpotMarketOptions is provided, the marketType defaults to "Spot".
10171022
"CapacityBlock": The instance utilizes pre-purchased compute capacity (capacity blocks) with AWS Capacity Reservations.
1018-
If this value is selected, CapacityReservationID must be specified to identify the target reservation.
1023+
If this value is selected, either CapacityReservationID or CapacityReservationResourceGroupARN must be specified to identify the target reservation.
10191024
If marketType is not specified and spotMarketOptions is provided, the marketType defaults to "Spot".
10201025
enum:
10211026
- OnDemand
@@ -1240,12 +1245,17 @@ spec:
12401245
- instanceType
12411246
type: object
12421247
x-kubernetes-validations:
1243-
- message: capacityReservationId may not be set when marketType is Spot
1244-
rule: '!has(self.capacityReservationId) || !has(self.marketType) ||
1245-
self.marketType != ''Spot'''
1246-
- message: capacityReservationId cannot be set when spotMarketOptions
1248+
- message: capacityReservationId and capacityReservationResourceGroupARN
1249+
are mutually exclusive
1250+
rule: '!has(self.capacityReservationId) || !has(self.capacityReservationResourceGroupARN)'
1251+
- message: capacity reservation targets may not be set when marketType
1252+
is Spot
1253+
rule: '!(has(self.capacityReservationId) || has(self.capacityReservationResourceGroupARN))
1254+
|| !has(self.marketType) || self.marketType != ''Spot'''
1255+
- message: capacity reservation targets cannot be set when spotMarketOptions
12471256
is specified
1248-
rule: '!has(self.capacityReservationId) || !has(self.spotMarketOptions)'
1257+
rule: '!(has(self.capacityReservationId) || has(self.capacityReservationResourceGroupARN))
1258+
|| !has(self.spotMarketOptions)'
12491259
status:
12501260
description: AWSMachineStatus defines the observed state of AWSMachine.
12511261
properties:

0 commit comments

Comments
 (0)