Skip to content

Commit a89fa76

Browse files
common: validate capacity reservation options
The capacity reservation options (ID, ARN, or Preference) are all mutually exclusive, only one of the three should be set in a given configuration. The code wasn't enforcing this, leading to cases in which conflicts could be specified in the configuration, and the call to start the instance would then fail during build instead of before it starts. This commit adds some logic to ensure that only valid options are accepted, and some tests are added to make sure these options cannot conflict.
1 parent c585c59 commit a89fa76

2 files changed

Lines changed: 136 additions & 2 deletions

File tree

builder/common/run_config.go

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -887,11 +887,24 @@ func (c *RunConfig) Prepare(ctx *interpolate.Context) []error {
887887

888888
}
889889

890-
if c.CapacityReservationPreference == "" {
890+
capacityReservationTargetSet := false
891+
if c.CapacityReservationId != "" || c.CapacityReservationGroupArn != "" {
892+
capacityReservationTargetSet = true
893+
}
894+
895+
if c.CapacityReservationGroupArn != "" && c.CapacityReservationId != "" {
896+
errs = append(errs, fmt.Errorf("capacity_reservation_id and capacity_reservation_group_arn are mutually exclusive, only one should be used"))
897+
}
898+
899+
if capacityReservationTargetSet && c.CapacityReservationPreference != "" {
900+
errs = append(errs, fmt.Errorf("capacity_reservation_id, capacity_reservation_group_arn and capacity_reservation_preference are mutually exclusive, only one should be set"))
901+
}
902+
903+
if c.CapacityReservationPreference == "" && c.CapacityReservationId == "" && c.CapacityReservationGroupArn == "" {
891904
c.CapacityReservationPreference = "none"
892905
}
893906
switch c.CapacityReservationPreference {
894-
case "none", "open":
907+
case "", "none", "open":
895908
default:
896909
errs = append(errs, fmt.Errorf(`capacity_reservation_preference only accepts 'none' or 'open' values`))
897910
}

builder/common/run_config_test.go

Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -461,3 +461,124 @@ func TestRunConfigPrepare_InvalidTenantForHost(t *testing.T) {
461461
})
462462
}
463463
}
464+
465+
func TestRunConfigPrepare_WithCapacityReservations(t *testing.T) {
466+
tests := []struct {
467+
name string
468+
reservationID string
469+
reservationPreference string
470+
reservationARN string
471+
expectedReservationID string
472+
expectedReservationPreference string
473+
expectedReservationARN string
474+
expectError bool
475+
}{
476+
{
477+
name: "None set, preference should be set to none, no error",
478+
reservationID: "",
479+
reservationPreference: "",
480+
reservationARN: "",
481+
expectedReservationID: "",
482+
expectedReservationPreference: "none",
483+
expectedReservationARN: "",
484+
expectError: false,
485+
},
486+
{
487+
name: "Preference set to none, preference should be set to none, no error",
488+
reservationID: "",
489+
reservationPreference: "none",
490+
reservationARN: "",
491+
expectedReservationID: "",
492+
expectedReservationPreference: "none",
493+
expectedReservationARN: "",
494+
expectError: false,
495+
},
496+
{
497+
name: "Preference set to open, preference should be set to open, no error",
498+
reservationID: "",
499+
reservationPreference: "open",
500+
reservationARN: "",
501+
expectedReservationID: "",
502+
expectedReservationPreference: "open",
503+
expectedReservationARN: "",
504+
expectError: false,
505+
},
506+
{
507+
name: "Preference set to and invalid value, expect an error",
508+
reservationID: "",
509+
reservationPreference: "invalid",
510+
reservationARN: "",
511+
expectedReservationID: "",
512+
expectedReservationPreference: "invalid",
513+
expectedReservationARN: "",
514+
expectError: true,
515+
},
516+
{
517+
name: "ID set to something, no preference, no error, no changes to config",
518+
reservationID: "cr-123456",
519+
reservationPreference: "",
520+
reservationARN: "",
521+
expectedReservationID: "cr-123456",
522+
expectedReservationPreference: "",
523+
expectedReservationARN: "",
524+
expectError: false,
525+
},
526+
{
527+
name: "ARN set to something, no preference, no error, no changes to config",
528+
reservationID: "",
529+
reservationPreference: "",
530+
reservationARN: "arn-asduilovgf",
531+
expectedReservationID: "",
532+
expectedReservationPreference: "",
533+
expectedReservationARN: "arn-asduilovgf",
534+
expectError: false,
535+
},
536+
{
537+
name: "Preference set to none, ID not empty, should error as both are incompatible",
538+
reservationID: "cr-123456",
539+
reservationPreference: "none",
540+
reservationARN: "",
541+
expectedReservationID: "cr-123456",
542+
expectedReservationPreference: "none",
543+
expectedReservationARN: "",
544+
expectError: true,
545+
},
546+
{
547+
name: "ID and ARN not empty, should error as both are incompatible",
548+
reservationID: "cr-123456",
549+
reservationPreference: "",
550+
reservationARN: "arn-aseldigubh",
551+
expectedReservationID: "cr-123456",
552+
expectedReservationPreference: "",
553+
expectedReservationARN: "arn-aseldigubh",
554+
expectError: true,
555+
},
556+
}
557+
558+
for _, tt := range tests {
559+
t.Run(tt.name, func(t *testing.T) {
560+
c := testConfig()
561+
c.CapacityReservationGroupArn = tt.reservationARN
562+
c.CapacityReservationId = tt.reservationID
563+
c.CapacityReservationPreference = tt.reservationPreference
564+
565+
errs := c.Prepare(nil)
566+
if (len(errs) != 0) != tt.expectError {
567+
t.Errorf("expected %t errors, got %t", tt.expectError, len(errs) != 0)
568+
t.Logf("errors: %v", errs)
569+
}
570+
571+
if c.CapacityReservationGroupArn != tt.expectedReservationARN {
572+
t.Errorf("expected Reservation ARN %q, got %q", tt.expectedReservationARN, c.CapacityReservationGroupArn)
573+
}
574+
575+
if c.CapacityReservationId != tt.expectedReservationID {
576+
t.Errorf("expected Reservation ID %q, got %q", tt.expectedReservationARN, c.CapacityReservationId)
577+
}
578+
579+
if c.CapacityReservationPreference != tt.expectedReservationPreference {
580+
t.Errorf("expected Reservation Preference %q, got %q", tt.expectedReservationPreference, c.CapacityReservationPreference)
581+
}
582+
})
583+
}
584+
}

0 commit comments

Comments
 (0)