Skip to content
Open
Show file tree
Hide file tree
Changes from all 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
34 changes: 34 additions & 0 deletions api/hypershift/v1beta1/aws.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,15 @@ type AWSNodePoolPlatform struct {
//
// +optional
Placement *PlacementOptions `json:"placement,omitempty"`

// cpuOptions specifies CPU configuration for EC2 instances.
// Supported on C8i, M8i, and R8i instance families.
Comment thread
jhjaggars marked this conversation as resolved.
// When omitted, AWS defaults are used (nested virtualization is not enabled).
// To revert to default behavior after setting cpuOptions, remove the entire
// cpuOptions field rather than clearing individual sub-fields.
//
// +optional
CPUOptions CPUOptions `json:"cpuOptions,omitzero"`
}

// PlacementOptions specifies the placement options for the EC2 instances.
Expand Down Expand Up @@ -176,6 +185,31 @@ const (
AWSResourceTagOverridePolicyDeny AWSResourceTagOverridePolicy = "Deny"
)

// CPUOptions specifies CPU configuration for EC2 instances.
// At least one field must be specified when cpuOptions is present.
//
// +kubebuilder:validation:MinProperties=1
Comment thread
jhjaggars marked this conversation as resolved.
type CPUOptions struct {
// nestedVirtualizationPolicy indicates whether to enable nested virtualization on the instance.
// Supported on C8i, M8i, and R8i instance families.
// When omitted, nested virtualization is not enabled (AWS default behavior).

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One last godoc change from the API perspective: enums should document possibly values and their usage, for example, something like

  // Valid values are "Enabled" and "Disabled".
  // When set to "Enabled", nested virtualization is enabled on the instance.
  // When set to "Disabled", nested virtualization is explicitly disabled on the instance.

//
// +optional
Comment thread
jhjaggars marked this conversation as resolved.
// +kubebuilder:validation:Enum=Enabled;Disabled
NestedVirtualizationPolicy NestedVirtualizationPolicy `json:"nestedVirtualizationPolicy,omitempty"`
}

// NestedVirtualizationPolicy indicates whether nested virtualization is enabled or disabled.
type NestedVirtualizationPolicy string

const (
// NestedVirtualizationEnabled enables nested virtualization on the instance.
NestedVirtualizationEnabled NestedVirtualizationPolicy = "Enabled"

// NestedVirtualizationDisabled disables nested virtualization on the instance.
NestedVirtualizationDisabled NestedVirtualizationPolicy = "Disabled"
)

// MarketType describes the market type for EC2 instances.
type MarketType string

Expand Down
96 changes: 96 additions & 0 deletions api/hypershift/v1beta1/nodepool_types_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,13 @@ type nodePoolAutoScalingNMinus1 struct {
Max int32 `json:"max"`
}

type awsNodePoolPlatformNMinus1 struct {
// instanceType is the EC2 instance type.
InstanceType string `json:"instanceType"` //nolint:kubeapilinter // test-only N-1 compat struct
// subnet is the subnet reference.
Subnet AWSResourceReference `json:"subnet"` //nolint:kubeapilinter // test-only N-1 compat struct
}

func TestNodePoolAutoScalingSerializationCompatibility(t *testing.T) {
tests := []struct {
name string
Expand Down Expand Up @@ -296,3 +303,92 @@ func TestAWSEndpointServiceResourceTagSerializationCompatibility(t *testing.T) {
})
}
}

func TestAWSNodePoolPlatformSerializationCompatibility(t *testing.T) {
tests := []struct {
name string
// current is the N (current) version of the struct
current AWSNodePoolPlatform
// expectedJSON is the expected JSON output from marshalling current
expectedJSON string
// nMinus1Result is the expected result when unmarshalling into the N-1 struct
nMinus1Result awsNodePoolPlatformNMinus1
}{
{
name: "When cpuOptions are set it should round-trip to N-1",
current: AWSNodePoolPlatform{
InstanceType: "m6i.large",
Subnet: AWSResourceReference{
ID: ptr.To("subnet-1234567890abcdef0"),
},
CPUOptions: CPUOptions{
NestedVirtualizationPolicy: NestedVirtualizationEnabled,
},
},
expectedJSON: `{"instanceType":"m6i.large","subnet":{"id":"subnet-1234567890abcdef0"},"cpuOptions":{"nestedVirtualizationPolicy":"Enabled"}}`,
nMinus1Result: awsNodePoolPlatformNMinus1{
InstanceType: "m6i.large",
Subnet: AWSResourceReference{
ID: ptr.To("subnet-1234567890abcdef0"),
},
},
},
{
name: "When cpuOptions are omitted it should preserve N-1 JSON shape",
current: AWSNodePoolPlatform{
InstanceType: "m6i.large",
Subnet: AWSResourceReference{
ID: ptr.To("subnet-1234567890abcdef0"),
},
},
expectedJSON: `{"instanceType":"m6i.large","subnet":{"id":"subnet-1234567890abcdef0"}}`,
nMinus1Result: awsNodePoolPlatformNMinus1{
InstanceType: "m6i.large",
Subnet: AWSResourceReference{
ID: ptr.To("subnet-1234567890abcdef0"),
},
},
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
data, err := json.Marshal(tt.current)
if err != nil {
t.Fatalf("failed to marshal current struct: %v", err)
}
if string(data) != tt.expectedJSON {
t.Errorf("unexpected JSON output: got %s, want %s", string(data), tt.expectedJSON)
}

var nMinus1 awsNodePoolPlatformNMinus1
if err := json.Unmarshal(data, &nMinus1); err != nil {
t.Fatalf("N-1 failed to unmarshal JSON from N: %v", err)
}
if nMinus1.InstanceType != tt.nMinus1Result.InstanceType {
t.Errorf("N-1 instanceType mismatch: got %s, want %s", nMinus1.InstanceType, tt.nMinus1Result.InstanceType)
}
if ptr.Deref(nMinus1.Subnet.ID, "") != ptr.Deref(tt.nMinus1Result.Subnet.ID, "") {
t.Errorf("N-1 subnet ID mismatch: got %q, want %q", ptr.Deref(nMinus1.Subnet.ID, ""), ptr.Deref(tt.nMinus1Result.Subnet.ID, ""))
}

nMinus1Data, err := json.Marshal(tt.nMinus1Result)
if err != nil {
t.Fatalf("failed to marshal N-1 struct: %v", err)
}
var roundTripped AWSNodePoolPlatform
if err := json.Unmarshal(nMinus1Data, &roundTripped); err != nil {
t.Fatalf("N failed to unmarshal JSON from N-1: %v", err)
}
if roundTripped.InstanceType != tt.nMinus1Result.InstanceType {
t.Errorf("InstanceType mismatch after N-1 round-trip: got %s, want %s", roundTripped.InstanceType, tt.nMinus1Result.InstanceType)
}
if ptr.Deref(roundTripped.Subnet.ID, "") != ptr.Deref(tt.nMinus1Result.Subnet.ID, "") {
t.Errorf("Subnet ID mismatch after N-1 round-trip: got %q, want %q", ptr.Deref(roundTripped.Subnet.ID, ""), ptr.Deref(tt.nMinus1Result.Subnet.ID, ""))
}
if roundTripped.CPUOptions != (CPUOptions{}) {
t.Errorf("CPUOptions mismatch after N-1 round-trip: got %+v, want zero value", roundTripped.CPUOptions)
}
})
}
}
16 changes: 16 additions & 0 deletions api/hypershift/v1beta1/zz_generated.deepcopy.go

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

Original file line number Diff line number Diff line change
Expand Up @@ -409,6 +409,25 @@ spec:
is chosen based on the NodePool release payload image.
maxLength: 255
type: string
cpuOptions:
description: |-
cpuOptions specifies CPU configuration for EC2 instances.
Supported on C8i, M8i, and R8i instance families.
When omitted, AWS defaults are used (nested virtualization is not enabled).
To revert to default behavior after setting cpuOptions, remove the entire
cpuOptions field rather than clearing individual sub-fields.
minProperties: 1
properties:
nestedVirtualizationPolicy:
description: |-
nestedVirtualizationPolicy indicates whether to enable nested virtualization on the instance.
Supported on C8i, M8i, and R8i instance families.
When omitted, nested virtualization is not enabled (AWS default behavior).
enum:
- Enabled
- Disabled
type: string
type: object
imageType:
description: |-
imageType specifies the type of image to use for node instances.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -409,6 +409,25 @@ spec:
is chosen based on the NodePool release payload image.
maxLength: 255
type: string
cpuOptions:
description: |-
cpuOptions specifies CPU configuration for EC2 instances.
Supported on C8i, M8i, and R8i instance families.
When omitted, AWS defaults are used (nested virtualization is not enabled).
To revert to default behavior after setting cpuOptions, remove the entire
cpuOptions field rather than clearing individual sub-fields.
minProperties: 1
properties:
nestedVirtualizationPolicy:
description: |-
nestedVirtualizationPolicy indicates whether to enable nested virtualization on the instance.
Supported on C8i, M8i, and R8i instance families.
When omitted, nested virtualization is not enabled (AWS default behavior).
enum:
- Enabled
- Disabled
type: string
type: object
imageType:
description: |-
imageType specifies the type of image to use for node instances.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -442,6 +442,25 @@ spec:
is chosen based on the NodePool release payload image.
maxLength: 255
type: string
cpuOptions:
description: |-
cpuOptions specifies CPU configuration for EC2 instances.
Supported on C8i, M8i, and R8i instance families.
When omitted, AWS defaults are used (nested virtualization is not enabled).
To revert to default behavior after setting cpuOptions, remove the entire
cpuOptions field rather than clearing individual sub-fields.
minProperties: 1
properties:
nestedVirtualizationPolicy:
description: |-
nestedVirtualizationPolicy indicates whether to enable nested virtualization on the instance.
Supported on C8i, M8i, and R8i instance families.
When omitted, nested virtualization is not enabled (AWS default behavior).
enum:
- Enabled
- Disabled
type: string
type: object
imageType:
description: |-
imageType specifies the type of image to use for node instances.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -409,6 +409,25 @@ spec:
is chosen based on the NodePool release payload image.
maxLength: 255
type: string
cpuOptions:
description: |-
cpuOptions specifies CPU configuration for EC2 instances.
Supported on C8i, M8i, and R8i instance families.
When omitted, AWS defaults are used (nested virtualization is not enabled).
To revert to default behavior after setting cpuOptions, remove the entire
cpuOptions field rather than clearing individual sub-fields.
minProperties: 1
properties:
nestedVirtualizationPolicy:
description: |-
nestedVirtualizationPolicy indicates whether to enable nested virtualization on the instance.
Supported on C8i, M8i, and R8i instance families.
When omitted, nested virtualization is not enabled (AWS default behavior).
enum:
- Enabled
- Disabled
type: string
type: object
imageType:
description: |-
imageType specifies the type of image to use for node instances.
Expand Down

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

42 changes: 42 additions & 0 deletions client/applyconfiguration/hypershift/v1beta1/cpuoptions.go

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

2 changes: 2 additions & 0 deletions client/applyconfiguration/utils.go

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

1 change: 0 additions & 1 deletion cmd/cluster/aws/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -511,7 +511,6 @@ func bindCoreOptions(opts *RawCreateOptions, flags *flag.FlagSet) {
flags.BoolVar(&opts.PublicOnly, "public-only", opts.PublicOnly, "If true, creates a cluster that does not have private subnets or NAT gateway and assigns public IPs to all instances.")
flags.BoolVar(&opts.UseROSAManagedPolicies, "use-rosa-managed-policies", opts.UseROSAManagedPolicies, "Use ROSA managed policies for the operator roles and worker instance profile")
flags.BoolVar(&opts.SharedRole, "shared-role", opts.SharedRole, "Create a single shared role with all role policies instead of individual component roles")

Comment thread
jhjaggars marked this conversation as resolved.
_ = flags.MarkDeprecated("multi-arch", "Multi-arch validation is now performed automatically based on the release image and signaled in the HostedCluster.Status.PayloadArch.")
}

Expand Down
Loading
Loading