diff --git a/api/v1beta2/awsmachine_types.go b/api/v1beta2/awsmachine_types.go index 16f85dbe15..415457485f 100644 --- a/api/v1beta2/awsmachine_types.go +++ b/api/v1beta2/awsmachine_types.go @@ -249,7 +249,7 @@ type AWSMachineSpec struct { // 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 + // "CapacityReservationsOnly": The instance will only run if matched or targeted to a Capacity Reservation. Note that this is incompatible with a MarketType of `Spot` // +kubebuilder:validation:Enum="";None;CapacityReservationsOnly;Open // +optional CapacityReservationPreference CapacityReservationPreference `json:"capacityReservationPreference,omitempty"` diff --git a/api/v1beta2/awsmachine_webhook.go b/api/v1beta2/awsmachine_webhook.go index ae905fcdd2..b5ad5010e9 100644 --- a/api/v1beta2/awsmachine_webhook.go +++ b/api/v1beta2/awsmachine_webhook.go @@ -384,7 +384,13 @@ func (r *AWSMachine) validateNetworkElasticIPPool() field.ErrorList { 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")) + allErrs = append(allErrs, field.Forbidden(field.NewPath("spec", "capacityReservationPreference"), "when a reservation ID is specified, capacityReservationPreference may only be 'CapacityReservationsOnly' or empty")) + } + if r.Spec.CapacityReservationPreference == CapacityReservationPreferenceOnly && r.Spec.MarketType == MarketTypeSpot { + allErrs = append(allErrs, field.Forbidden(field.NewPath("spec", "capacityReservationPreference"), "when MarketType is set to 'Spot', capacityReservationPreference cannot be set to 'CapacityReservationsOnly'")) + } + if r.Spec.CapacityReservationPreference == CapacityReservationPreferenceOnly && r.Spec.SpotMarketOptions != nil { + allErrs = append(allErrs, field.Forbidden(field.NewPath("spec", "capacityReservationPreference"), "when capacityReservationPreference is 'CapacityReservationsOnly', SpotMarketOptions cannot be set (which implies MarketType: 'Spot')")) } return allErrs } diff --git a/api/v1beta2/awsmachine_webhook_test.go b/api/v1beta2/awsmachine_webhook_test.go index c20dd9f30d..66c0919ecb 100644 --- a/api/v1beta2/awsmachine_webhook_test.go +++ b/api/v1beta2/awsmachine_webhook_test.go @@ -241,7 +241,7 @@ func TestAWSMachineCreate(t *testing.T) { wantErr: true, }, { - name: "valid MarketType set to MarketTypeCapacityBlock is specified and CapacityReservationId is not provided", + name: "invalid MarketType set to MarketTypeCapacityBlock is specified and CapacityReservationId is not provided", machine: &AWSMachine{ Spec: AWSMachineSpec{ MarketType: MarketTypeCapacityBlock, @@ -293,6 +293,30 @@ func TestAWSMachineCreate(t *testing.T) { }, wantErr: false, }, + { + name: "invalid CapacityReservationPreference is `CapacityReservationsOnly` and MarketType is `Spot`", + machine: &AWSMachine{ + Spec: AWSMachineSpec{ + InstanceType: "test", + CapacityReservationID: aws.String("cr-12345678901234567"), + CapacityReservationPreference: CapacityReservationPreferenceOnly, + MarketType: MarketTypeSpot, + }, + }, + wantErr: true, + }, + { + name: "invalid CapacityReservationPreference is `CapacityReservationsOnly` and SpotMarketOptions is non-nil", + machine: &AWSMachine{ + Spec: AWSMachineSpec{ + InstanceType: "test", + CapacityReservationID: aws.String("cr-12345678901234567"), + CapacityReservationPreference: CapacityReservationPreferenceOnly, + SpotMarketOptions: &SpotMarketOptions{}, + }, + }, + wantErr: true, + }, { name: "empty instance type not allowed", machine: &AWSMachine{ diff --git a/api/v1beta2/types.go b/api/v1beta2/types.go index 0f8d155515..9fd22efc80 100644 --- a/api/v1beta2/types.go +++ b/api/v1beta2/types.go @@ -289,7 +289,7 @@ type Instance struct { // 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 + // "CapacityReservationsOnly": The instance will only run if matched or targeted to a Capacity Reservation. Note that this is incompatible with a MarketType of `Spot` // +kubebuilder:validation:Enum="";None;CapacityReservationsOnly;Open // +optional CapacityReservationPreference CapacityReservationPreference `json:"capacityReservationPreference,omitempty"` @@ -304,7 +304,7 @@ 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 the instance will only run if matched or targeted to a Capacity Reservation. Note that this is incompatible with a MarketType of `Spot` CapacityReservationPreferenceOnly CapacityReservationPreference = "CapacityReservationsOnly" // CapacityReservationPreferenceOpen the instance may make use of open Capacity Reservations that match its AZ and InstanceType. diff --git a/config/crd/bases/controlplane.cluster.x-k8s.io_awsmanagedcontrolplanes.yaml b/config/crd/bases/controlplane.cluster.x-k8s.io_awsmanagedcontrolplanes.yaml index 4bc4ca8e70..300f619624 100644 --- a/config/crd/bases/controlplane.cluster.x-k8s.io_awsmanagedcontrolplanes.yaml +++ b/config/crd/bases/controlplane.cluster.x-k8s.io_awsmanagedcontrolplanes.yaml @@ -1230,7 +1230,7 @@ spec: 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 + "CapacityReservationsOnly": The instance will only run if matched or targeted to a Capacity Reservation. Note that this is incompatible with a MarketType of `Spot` type: string ebsOptimized: description: Indicates whether the instance is optimized for Amazon @@ -3444,7 +3444,7 @@ spec: 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 + "CapacityReservationsOnly": The instance will only run if matched or targeted to a Capacity Reservation. Note that this is incompatible with a MarketType of `Spot` type: string ebsOptimized: description: Indicates whether the instance is optimized for Amazon diff --git a/config/crd/bases/infrastructure.cluster.x-k8s.io_awsclusters.yaml b/config/crd/bases/infrastructure.cluster.x-k8s.io_awsclusters.yaml index 4e0e03d0bf..f4c9600a69 100644 --- a/config/crd/bases/infrastructure.cluster.x-k8s.io_awsclusters.yaml +++ b/config/crd/bases/infrastructure.cluster.x-k8s.io_awsclusters.yaml @@ -2213,7 +2213,7 @@ spec: 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 + "CapacityReservationsOnly": The instance will only run if matched or targeted to a Capacity Reservation. Note that this is incompatible with a MarketType of `Spot` type: string ebsOptimized: description: Indicates whether the instance is optimized for Amazon diff --git a/config/crd/bases/infrastructure.cluster.x-k8s.io_awsmachines.yaml b/config/crd/bases/infrastructure.cluster.x-k8s.io_awsmachines.yaml index 6ca5ccb7a2..7541a2ee82 100644 --- a/config/crd/bases/infrastructure.cluster.x-k8s.io_awsmachines.yaml +++ b/config/crd/bases/infrastructure.cluster.x-k8s.io_awsmachines.yaml @@ -657,7 +657,7 @@ spec: 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 + "CapacityReservationsOnly": The instance will only run if matched or targeted to a Capacity Reservation. Note that this is incompatible with a MarketType of `Spot` type: string cloudInit: description: |- diff --git a/config/crd/bases/infrastructure.cluster.x-k8s.io_awsmachinetemplates.yaml b/config/crd/bases/infrastructure.cluster.x-k8s.io_awsmachinetemplates.yaml index faff683e2e..6329967619 100644 --- a/config/crd/bases/infrastructure.cluster.x-k8s.io_awsmachinetemplates.yaml +++ b/config/crd/bases/infrastructure.cluster.x-k8s.io_awsmachinetemplates.yaml @@ -576,7 +576,7 @@ spec: 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 + "CapacityReservationsOnly": The instance will only run if matched or targeted to a Capacity Reservation. Note that this is incompatible with a MarketType of `Spot` type: string cloudInit: description: |-