Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions api/v1beta1/awscluster_conversion.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ func (src *AWSCluster) ConvertTo(dstRaw conversion.Hub) error {
dst.Status.Bastion.MarketType = restored.Status.Bastion.MarketType
dst.Status.Bastion.HostAffinity = restored.Status.Bastion.HostAffinity
dst.Status.Bastion.HostID = restored.Status.Bastion.HostID
dst.Status.Bastion.CapacityReservationPreference = restored.Status.Bastion.CapacityReservationPreference
}
dst.Spec.Partition = restored.Spec.Partition

Expand Down
2 changes: 2 additions & 0 deletions api/v1beta1/awsmachine_conversion.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ func (src *AWSMachine) ConvertTo(dstRaw conversion.Hub) error {
dst.Spec.MarketType = restored.Spec.MarketType
dst.Spec.HostID = restored.Spec.HostID
dst.Spec.HostAffinity = restored.Spec.HostAffinity
dst.Spec.CapacityReservationPreference = restored.Spec.CapacityReservationPreference
dst.Spec.NetworkInterfaceType = restored.Spec.NetworkInterfaceType
if restored.Spec.ElasticIPPool != nil {
if dst.Spec.ElasticIPPool == nil {
Expand Down Expand Up @@ -112,6 +113,7 @@ func (r *AWSMachineTemplate) ConvertTo(dstRaw conversion.Hub) error {
dst.Spec.Template.Spec.MarketType = restored.Spec.Template.Spec.MarketType
dst.Spec.Template.Spec.HostID = restored.Spec.Template.Spec.HostID
dst.Spec.Template.Spec.HostAffinity = restored.Spec.Template.Spec.HostAffinity
dst.Spec.Template.Spec.CapacityReservationPreference = restored.Spec.Template.Spec.CapacityReservationPreference
dst.Spec.Template.Spec.NetworkInterfaceType = restored.Spec.Template.Spec.NetworkInterfaceType
if restored.Spec.Template.Spec.ElasticIPPool != nil {
if dst.Spec.Template.Spec.ElasticIPPool == nil {
Expand Down
2 changes: 2 additions & 0 deletions api/v1beta1/zz_generated.conversion.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 7 additions & 0 deletions api/v1beta2/awsmachine_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,13 @@ type AWSMachineSpec struct {
// +optional
// +kubebuilder:validation:Enum:=default;host
HostAffinity *string `json:"hostAffinity,omitempty"`

// CapacityReservationPreference specifies the preference for use of Capacity Reservations by the instance. Valid values include:
// "Open" (default): The instance may make use of open Capacity Reservations that match its AZ and InstanceType
// "None": The instance may not make use of any Capacity Reservations. This is to conserve open reservations for desired workloads
// "CapacityReservationsOnly": The instance will only run if matched or targeted to a Capacity Reservation
// +optional
CapacityReservationPreference CapacityReservationPreference `json:"capacityReservationPreference,omitempty"`
}

// CloudInit defines options related to the bootstrapping systems where
Expand Down
9 changes: 9 additions & 0 deletions api/v1beta2/awsmachine_webhook.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ func (*awsMachineWebhook) ValidateCreate(_ context.Context, obj runtime.Object)
allErrs = append(allErrs, r.Spec.AdditionalTags.Validate()...)
allErrs = append(allErrs, r.validateNetworkElasticIPPool()...)
allErrs = append(allErrs, r.validateInstanceMarketType()...)
allErrs = append(allErrs, r.validateCapacityReservation()...)

return nil, aggregateObjErrors(r.GroupVersionKind().GroupKind(), r.Name, allErrs)
}
Expand Down Expand Up @@ -380,6 +381,14 @@ func (r *AWSMachine) validateNetworkElasticIPPool() field.ErrorList {
return allErrs
}

func (r *AWSMachine) validateCapacityReservation() field.ErrorList {
var allErrs field.ErrorList
if r.Spec.CapacityReservationID != nil && r.Spec.CapacityReservationPreference != CapacityReservationPreferenceOnly && r.Spec.CapacityReservationPreference != "" {
allErrs = append(allErrs, field.Forbidden(field.NewPath("spec", "capacityReservationPreference"), "when a reservation ID is specified, capacityReservationPreference may only be `capacity-reservations-only` or empty"))
}
return allErrs
}

func (r *AWSMachine) validateInstanceMarketType() field.ErrorList {
var allErrs field.ErrorList
if r.Spec.MarketType == MarketTypeCapacityBlock && r.Spec.SpotMarketOptions != nil {
Expand Down
32 changes: 32 additions & 0 deletions api/v1beta2/awsmachine_webhook_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,38 @@ func TestAWSMachineCreate(t *testing.T) {
},
wantErr: false,
},
{
name: "invalid case, CapacityReservationId is set and CapacityReservationPreference is not `capacity-reservation-only`",
machine: &AWSMachine{
Spec: AWSMachineSpec{
InstanceType: "test",
CapacityReservationID: aws.String("cr-12345678901234567"),
CapacityReservationPreference: CapacityReservationPreferenceNone,
},
},
wantErr: true,
},
{
name: "valid CapacityReservationId is set and CapacityReservationPreference is not specified",
machine: &AWSMachine{
Spec: AWSMachineSpec{
InstanceType: "test",
CapacityReservationID: aws.String("cr-12345678901234567"),
},
},
wantErr: false,
},
{
name: "valid CapacityReservationId is set and CapacityReservationPreference is `capacity-reservation-only`",
machine: &AWSMachine{
Spec: AWSMachineSpec{
InstanceType: "test",
CapacityReservationID: aws.String("cr-12345678901234567"),
CapacityReservationPreference: CapacityReservationPreferenceOnly,
},
},
wantErr: false,
},
{
name: "empty instance type not allowed",
machine: &AWSMachine{
Expand Down
24 changes: 24 additions & 0 deletions api/v1beta2/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -285,8 +285,32 @@ type Instance struct {
// HostID specifies the dedicated host on which the instance should be started.
// +optional
HostID *string `json:"hostID,omitempty"`

// CapacityReservationPreference specifies the preference for use of Capacity Reservations by the instance. Valid values include:
// "Open": The instance may make use of open Capacity Reservations that match its AZ and InstanceType
// "None": The instance may not make use of any Capacity Reservations. This is to conserve open reservations for desired workloads
// "CapacityReservationsOnly": The instance will only run if matched or targeted to a Capacity Reservation
// +kubebuilder:validation:Enum="";None;CapacityReservationsOnly;Open
// +optional
CapacityReservationPreference CapacityReservationPreference `json:"capacityReservationPreference,omitempty"`
}

// CapacityReservationPreference describes the preferred use of capacity reservations
// of an instance
// +kubebuilder:validation:Enum:="";None;CapacityReservationsOnly;Open
type CapacityReservationPreference string

const (
// CapacityReservationPreferenceNone the instance may not make use of any Capacity Reservations. This is to conserve open reservations for desired workloads
CapacityReservationPreferenceNone CapacityReservationPreference = "None"

// CapacityReservationPreferenceOnly the instance will only run if matched or targeted to a Capacity Reservation
CapacityReservationPreferenceOnly CapacityReservationPreference = "CapacityReservationsOnly"

// CapacityReservationPreferenceOpen the instance may make use of open Capacity Reservations that match its AZ and InstanceType.
CapacityReservationPreferenceOpen CapacityReservationPreference = "Open"
)

// MarketType describes the market type of an Instance
// +kubebuilder:validation:Enum:=OnDemand;Spot;CapacityBlock
type MarketType string
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1214,6 +1214,24 @@ spec:
description: CapacityReservationID specifies the target Capacity
Reservation into which the instance should be launched.
type: string
capacityReservationPreference:
allOf:
- enum:
- ""
- None
- CapacityReservationsOnly
- Open
- enum:
- ""
- None
- CapacityReservationsOnly
- Open
description: |-
CapacityReservationPreference specifies the preference for use of Capacity Reservations by the instance. Valid values include:
"Open": The instance may make use of open Capacity Reservations that match its AZ and InstanceType
"None": The instance may not make use of any Capacity Reservations. This is to conserve open reservations for desired workloads
"CapacityReservationsOnly": The instance will only run if matched or targeted to a Capacity Reservation
type: string
ebsOptimized:
description: Indicates whether the instance is optimized for Amazon
EBS I/O.
Expand Down Expand Up @@ -3410,6 +3428,24 @@ spec:
description: CapacityReservationID specifies the target Capacity
Reservation into which the instance should be launched.
type: string
capacityReservationPreference:
allOf:
- enum:
- ""
- None
- CapacityReservationsOnly
- Open
- enum:
- ""
- None
- CapacityReservationsOnly
- Open
description: |-
CapacityReservationPreference specifies the preference for use of Capacity Reservations by the instance. Valid values include:
"Open": The instance may make use of open Capacity Reservations that match its AZ and InstanceType
"None": The instance may not make use of any Capacity Reservations. This is to conserve open reservations for desired workloads
"CapacityReservationsOnly": The instance will only run if matched or targeted to a Capacity Reservation
type: string
ebsOptimized:
description: Indicates whether the instance is optimized for Amazon
EBS I/O.
Expand Down
18 changes: 18 additions & 0 deletions config/crd/bases/infrastructure.cluster.x-k8s.io_awsclusters.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2197,6 +2197,24 @@ spec:
description: CapacityReservationID specifies the target Capacity
Reservation into which the instance should be launched.
type: string
capacityReservationPreference:
allOf:
- enum:
- ""
- None
- CapacityReservationsOnly
- Open
- enum:
- ""
- None
- CapacityReservationsOnly
- Open
description: |-
CapacityReservationPreference specifies the preference for use of Capacity Reservations by the instance. Valid values include:
"Open": The instance may make use of open Capacity Reservations that match its AZ and InstanceType
"None": The instance may not make use of any Capacity Reservations. This is to conserve open reservations for desired workloads
"CapacityReservationsOnly": The instance will only run if matched or targeted to a Capacity Reservation
type: string
ebsOptimized:
description: Indicates whether the instance is optimized for Amazon
EBS I/O.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -644,6 +644,18 @@ spec:
description: CapacityReservationID specifies the target Capacity
Reservation into which the instance should be launched.
type: string
capacityReservationPreference:
description: |-
CapacityReservationPreference specifies the preference for use of Capacity Reservations by the instance. Valid values include:
"Open" (default): The instance may make use of open Capacity Reservations that match its AZ and InstanceType
"None": The instance may not make use of any Capacity Reservations. This is to conserve open reservations for desired workloads
"CapacityReservationsOnly": The instance will only run if matched or targeted to a Capacity Reservation
enum:
- ""
- None
- CapacityReservationsOnly
- Open
type: string
iamInstanceProfile:
description: |-
The name or the Amazon Resource Name (ARN) of the instance profile associated
Expand Down
12 changes: 12 additions & 0 deletions config/crd/bases/infrastructure.cluster.x-k8s.io_awsmachines.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -641,6 +641,18 @@ spec:
description: CapacityReservationID specifies the target Capacity Reservation
into which the instance should be launched.
type: string
capacityReservationPreference:
description: |-
CapacityReservationPreference specifies the preference for use of Capacity Reservations by the instance. Valid values include:
"Open" (default): The instance may make use of open Capacity Reservations that match its AZ and InstanceType
"None": The instance may not make use of any Capacity Reservations. This is to conserve open reservations for desired workloads
"CapacityReservationsOnly": The instance will only run if matched or targeted to a Capacity Reservation
enum:
- ""
- None
- CapacityReservationsOnly
- Open
type: string
cloudInit:
description: |-
CloudInit defines options related to the bootstrapping systems where
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -560,6 +560,18 @@ spec:
description: CapacityReservationID specifies the target Capacity
Reservation into which the instance should be launched.
type: string
capacityReservationPreference:
description: |-
CapacityReservationPreference specifies the preference for use of Capacity Reservations by the instance. Valid values include:
"Open" (default): The instance may make use of open Capacity Reservations that match its AZ and InstanceType
"None": The instance may not make use of any Capacity Reservations. This is to conserve open reservations for desired workloads
"CapacityReservationsOnly": The instance will only run if matched or targeted to a Capacity Reservation
enum:
- ""
- None
- CapacityReservationsOnly
- Open
type: string
cloudInit:
description: |-
CloudInit defines options related to the bootstrapping systems where
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -653,6 +653,18 @@ spec:
description: CapacityReservationID specifies the target Capacity
Reservation into which the instance should be launched.
type: string
capacityReservationPreference:
description: |-
CapacityReservationPreference specifies the preference for use of Capacity Reservations by the instance. Valid values include:
"Open" (default): The instance may make use of open Capacity Reservations that match its AZ and InstanceType
"None": The instance may not make use of any Capacity Reservations. This is to conserve open reservations for desired workloads
"CapacityReservationsOnly": The instance will only run if matched or targeted to a Capacity Reservation
enum:
- ""
- None
- CapacityReservationsOnly
- Open
type: string
iamInstanceProfile:
description: |-
The name or the Amazon Resource Name (ARN) of the instance profile associated
Expand Down
8 changes: 8 additions & 0 deletions exp/api/v1beta1/conversion.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,10 @@ func (src *AWSMachinePool) ConvertTo(dstRaw conversion.Hub) error {
dst.Spec.AWSLaunchTemplate.MarketType = restored.Spec.AWSLaunchTemplate.MarketType
}

if preference := restored.Spec.AWSLaunchTemplate.CapacityReservationPreference; preference != "" {
dst.Spec.AWSLaunchTemplate.CapacityReservationPreference = preference
}

dst.Spec.DefaultInstanceWarmup = restored.Spec.DefaultInstanceWarmup
dst.Spec.AWSLaunchTemplate.NonRootVolumes = restored.Spec.AWSLaunchTemplate.NonRootVolumes
return nil
Expand Down Expand Up @@ -130,6 +134,10 @@ func (src *AWSManagedMachinePool) ConvertTo(dstRaw conversion.Hub) error {
if restored.Spec.AWSLaunchTemplate.MarketType != "" {
dst.Spec.AWSLaunchTemplate.MarketType = restored.Spec.AWSLaunchTemplate.MarketType
}

if preference := restored.Spec.AWSLaunchTemplate.CapacityReservationPreference; preference != "" {
dst.Spec.AWSLaunchTemplate.CapacityReservationPreference = preference
}
}
if restored.Spec.AvailabilityZoneSubnetType != nil {
dst.Spec.AvailabilityZoneSubnetType = restored.Spec.AvailabilityZoneSubnetType
Expand Down
1 change: 1 addition & 0 deletions exp/api/v1beta1/zz_generated.conversion.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

11 changes: 11 additions & 0 deletions exp/api/v1beta2/awsmachinepool_webhook.go
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,7 @@ func (*AWSMachinePoolWebhook) ValidateCreate(_ context.Context, obj runtime.Obje
allErrs = append(allErrs, r.validateSpotInstances()...)
allErrs = append(allErrs, r.validateRefreshPreferences()...)
allErrs = append(allErrs, r.validateInstanceMarketType()...)
allErrs = append(allErrs, r.validateCapacityReservation()...)
allErrs = append(allErrs, r.validateLifecycleHooks()...)
allErrs = append(allErrs, r.validateIgnition()...)

Expand All @@ -225,6 +226,16 @@ func (*AWSMachinePoolWebhook) ValidateCreate(_ context.Context, obj runtime.Obje
)
}

func (r *AWSMachinePool) validateCapacityReservation() field.ErrorList {
var allErrs field.ErrorList
if r.Spec.AWSLaunchTemplate.CapacityReservationID != nil &&
r.Spec.AWSLaunchTemplate.CapacityReservationPreference != infrav1.CapacityReservationPreferenceOnly &&
r.Spec.AWSLaunchTemplate.CapacityReservationPreference != "" {
allErrs = append(allErrs, field.Forbidden(field.NewPath("spec", "capacityReservationPreference"), "when a reservation ID is specified, capacityReservationPreference may only be `capacity-reservations-only` or empty"))
}
return allErrs
}

func (r *AWSMachinePool) validateInstanceMarketType() field.ErrorList {
var allErrs field.ErrorList
if r.Spec.AWSLaunchTemplate.MarketType == infrav1.MarketTypeCapacityBlock && r.Spec.AWSLaunchTemplate.SpotMarketOptions != nil {
Expand Down
Loading