Skip to content
Merged
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
112 changes: 112 additions & 0 deletions data/data/install.openshift.io_installconfigs.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,34 @@ spec:
AMIID is the AMI that should be used to boot the ec2 instance.
If set, the AMI should belong to the same region as the cluster.
type: string
cpuOptions:
description: |-
CPUOptions defines CPU-related settings for the instance, including the confidential computing policy.
When omitted, this means no opinion and the AWS platform is left to choose a reasonable default.
More info:
https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_CpuOptionsRequest.html,
https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/cpu-options-supported-instances-values.html
minProperties: 1
properties:
confidentialCompute:
description: |-
ConfidentialCompute specifies whether confidential computing should be enabled for the instance,
and, if so, which confidential computing technology to use.
Valid values are: Disabled, AMDEncryptedVirtualizationNestedPaging and omitted.
When set to Disabled, confidential computing will be disabled for the instance.
When set to AMDEncryptedVirtualizationNestedPaging, AMD SEV-SNP will be used as the confidential computing technology for the instance.
In this case, ensure the following conditions are met:
1) The selected instance type supports AMD SEV-SNP.
2) The selected AWS region supports AMD SEV-SNP.
3) The selected AMI supports AMD SEV-SNP.
More details can be checked at https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/sev-snp.html
When omitted, this means no opinion and the AWS platform is left to choose a reasonable default,
which is subject to change without notice. The current default is Disabled.
enum:
- Disabled
- AMDEncryptedVirtualizationNestedPaging
type: string
type: object
iamProfile:
description: |-
IAMProfile is the name of the IAM instance profile to use for the machine.
Expand Down Expand Up @@ -1689,6 +1717,34 @@ spec:
AMIID is the AMI that should be used to boot the ec2 instance.
If set, the AMI should belong to the same region as the cluster.
type: string
cpuOptions:
description: |-
CPUOptions defines CPU-related settings for the instance, including the confidential computing policy.
When omitted, this means no opinion and the AWS platform is left to choose a reasonable default.
More info:
https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_CpuOptionsRequest.html,
https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/cpu-options-supported-instances-values.html
minProperties: 1
properties:
confidentialCompute:
description: |-
ConfidentialCompute specifies whether confidential computing should be enabled for the instance,
and, if so, which confidential computing technology to use.
Valid values are: Disabled, AMDEncryptedVirtualizationNestedPaging and omitted.
When set to Disabled, confidential computing will be disabled for the instance.
When set to AMDEncryptedVirtualizationNestedPaging, AMD SEV-SNP will be used as the confidential computing technology for the instance.
In this case, ensure the following conditions are met:
1) The selected instance type supports AMD SEV-SNP.
2) The selected AWS region supports AMD SEV-SNP.
3) The selected AMI supports AMD SEV-SNP.
More details can be checked at https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/sev-snp.html
When omitted, this means no opinion and the AWS platform is left to choose a reasonable default,
which is subject to change without notice. The current default is Disabled.
enum:
- Disabled
- AMDEncryptedVirtualizationNestedPaging
type: string
type: object
iamProfile:
description: |-
IAMProfile is the name of the IAM instance profile to use for the machine.
Expand Down Expand Up @@ -3147,6 +3203,34 @@ spec:
AMIID is the AMI that should be used to boot the ec2 instance.
If set, the AMI should belong to the same region as the cluster.
type: string
cpuOptions:
description: |-
CPUOptions defines CPU-related settings for the instance, including the confidential computing policy.
When omitted, this means no opinion and the AWS platform is left to choose a reasonable default.
More info:
https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_CpuOptionsRequest.html,
https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/cpu-options-supported-instances-values.html
minProperties: 1
properties:
confidentialCompute:
description: |-
ConfidentialCompute specifies whether confidential computing should be enabled for the instance,
and, if so, which confidential computing technology to use.
Valid values are: Disabled, AMDEncryptedVirtualizationNestedPaging and omitted.
When set to Disabled, confidential computing will be disabled for the instance.
When set to AMDEncryptedVirtualizationNestedPaging, AMD SEV-SNP will be used as the confidential computing technology for the instance.
In this case, ensure the following conditions are met:
1) The selected instance type supports AMD SEV-SNP.
2) The selected AWS region supports AMD SEV-SNP.
3) The selected AMI supports AMD SEV-SNP.
More details can be checked at https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/sev-snp.html
When omitted, this means no opinion and the AWS platform is left to choose a reasonable default,
which is subject to change without notice. The current default is Disabled.
enum:
- Disabled
- AMDEncryptedVirtualizationNestedPaging
type: string
type: object
iamProfile:
description: |-
IAMProfile is the name of the IAM instance profile to use for the machine.
Expand Down Expand Up @@ -4798,6 +4882,34 @@ spec:
AMIID is the AMI that should be used to boot the ec2 instance.
If set, the AMI should belong to the same region as the cluster.
type: string
cpuOptions:
description: |-
CPUOptions defines CPU-related settings for the instance, including the confidential computing policy.
When omitted, this means no opinion and the AWS platform is left to choose a reasonable default.
More info:
https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_CpuOptionsRequest.html,
https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/cpu-options-supported-instances-values.html
minProperties: 1
properties:
confidentialCompute:
description: |-
ConfidentialCompute specifies whether confidential computing should be enabled for the instance,
and, if so, which confidential computing technology to use.
Valid values are: Disabled, AMDEncryptedVirtualizationNestedPaging and omitted.
When set to Disabled, confidential computing will be disabled for the instance.
When set to AMDEncryptedVirtualizationNestedPaging, AMD SEV-SNP will be used as the confidential computing technology for the instance.
In this case, ensure the following conditions are met:
1) The selected instance type supports AMD SEV-SNP.
2) The selected AWS region supports AMD SEV-SNP.
3) The selected AMI supports AMD SEV-SNP.
More details can be checked at https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/sev-snp.html
When omitted, this means no opinion and the AWS platform is left to choose a reasonable default,
which is subject to change without notice. The current default is Disabled.
enum:
- Disabled
- AMDEncryptedVirtualizationNestedPaging
type: string
type: object
iamProfile:
description: |-
IAMProfile is the name of the IAM instance profile to use for the machine.
Expand Down
10 changes: 10 additions & 0 deletions pkg/asset/machines/aws/awsmachines.go
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,16 @@ func GenerateMachines(clusterID string, in *MachineInput) ([]*asset.RuntimeFile,
)
}

if mpool.CPUOptions != nil {
cpuOptions := capa.CPUOptions{}

if mpool.CPUOptions.ConfidentialCompute != nil {
cpuOptions.ConfidentialCompute = capa.AWSConfidentialComputePolicy(*mpool.CPUOptions.ConfidentialCompute)
}

awsMachine.Spec.CPUOptions = cpuOptions
}

result = append(result, &asset.RuntimeFile{
File: asset.File{Filename: fmt.Sprintf("10_inframachine_%s.yaml", awsMachine.Name)},
Object: awsMachine,
Expand Down
13 changes: 13 additions & 0 deletions pkg/asset/machines/aws/machines.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/util/sets"
"k8s.io/utils/pointer"
"k8s.io/utils/ptr"

v1 "github.com/openshift/api/config/v1"
machinev1 "github.com/openshift/api/machine/v1"
Expand All @@ -35,6 +36,7 @@ type machineProviderInput struct {
userTags map[string]string
publicSubnet bool
securityGroupIDs []string
cpuOptions *awstypes.CPUOptions
}

// Machines returns a list of machines for a machinepool.
Expand Down Expand Up @@ -77,6 +79,7 @@ func Machines(clusterID string, region string, subnets aws.SubnetsByZone, pool *
userTags: userTags,
publicSubnet: publicSubnet,
securityGroupIDs: pool.Platform.AWS.AdditionalSecurityGroupIDs,
cpuOptions: mpool.CPUOptions,
})
if err != nil {
return nil, nil, errors.Wrap(err, "failed to create provider")
Expand Down Expand Up @@ -291,6 +294,16 @@ func provider(in *machineProviderInput) (*machineapi.AWSMachineProviderConfig, e
config.MetadataServiceOptions.Authentication = machineapi.MetadataServiceAuthentication(in.imds.Authentication)
}

if in.cpuOptions != nil {
cpuOptions := machineapi.CPUOptions{}

if in.cpuOptions.ConfidentialCompute != nil {
cpuOptions.ConfidentialCompute = ptr.To(machineapi.AWSConfidentialComputePolicy(*in.cpuOptions.ConfidentialCompute))
}

config.CPUOptions = &cpuOptions
}

return config, nil
}

Expand Down
1 change: 1 addition & 0 deletions pkg/asset/machines/aws/machinesets.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ func MachineSets(in *MachineSetInput) ([]*machineapi.MachineSet, error) {
userTags: in.InstallConfigPlatformAWS.UserTags,
publicSubnet: publicSubnet,
securityGroupIDs: in.Pool.Platform.AWS.AdditionalSecurityGroupIDs,
cpuOptions: mpool.CPUOptions,
})
if err != nil {
return nil, errors.Wrap(err, "failed to create provider")
Expand Down
43 changes: 43 additions & 0 deletions pkg/types/aws/machinepool.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,14 @@ type MachinePool struct {
// +kubebuilder:validation:MaxItems=10
// +optional
AdditionalSecurityGroupIDs []string `json:"additionalSecurityGroupIDs,omitempty"`

// CPUOptions defines CPU-related settings for the instance, including the confidential computing policy.
// When omitted, this means no opinion and the AWS platform is left to choose a reasonable default.
// More info:
// https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_CpuOptionsRequest.html,
// https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/cpu-options-supported-instances-values.html
// +optional
CPUOptions *CPUOptions `json:"cpuOptions,omitempty,omitzero"`
}

// Set sets the values from `required` to `a`.
Expand Down Expand Up @@ -96,6 +104,10 @@ func (a *MachinePool) Set(required *MachinePool) {
if len(required.AdditionalSecurityGroupIDs) > 0 {
a.AdditionalSecurityGroupIDs = required.AdditionalSecurityGroupIDs
}

if required.CPUOptions != nil {
a.CPUOptions = required.CPUOptions
}
}

// EC2RootVolume defines the storage for an ec2 instance.
Expand Down Expand Up @@ -135,3 +147,34 @@ type EC2Metadata struct {
// +optional
Authentication string `json:"authentication,omitempty"`
}

// ConfidentialComputePolicy represents the confidential compute configuration for the instance.
// +kubebuilder:validation:Enum=Disabled;AMDEncryptedVirtualizationNestedPaging
type ConfidentialComputePolicy string

const (
// ConfidentialComputePolicyDisabled disables confidential computing for the instance.
ConfidentialComputePolicyDisabled ConfidentialComputePolicy = "Disabled"
// ConfidentialComputePolicySEVSNP enables AMD SEV-SNP as the confidential computing technology for the instance.
ConfidentialComputePolicySEVSNP ConfidentialComputePolicy = "AMDEncryptedVirtualizationNestedPaging"
)

// CPUOptions defines CPU-related settings for the instance, including the confidential computing policy.
// If provided, it must not be empty — at least one field must be set.
// +kubebuilder:validation:MinProperties=1
type CPUOptions struct {
// ConfidentialCompute specifies whether confidential computing should be enabled for the instance,
// and, if so, which confidential computing technology to use.
// Valid values are: Disabled, AMDEncryptedVirtualizationNestedPaging and omitted.
// When set to Disabled, confidential computing will be disabled for the instance.
// When set to AMDEncryptedVirtualizationNestedPaging, AMD SEV-SNP will be used as the confidential computing technology for the instance.
// In this case, ensure the following conditions are met:
// 1) The selected instance type supports AMD SEV-SNP.
// 2) The selected AWS region supports AMD SEV-SNP.
// 3) The selected AMI supports AMD SEV-SNP.
// More details can be checked at https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/sev-snp.html
// When omitted, this means no opinion and the AWS platform is left to choose a reasonable default,
// which is subject to change without notice. The current default is Disabled.
// +optional
ConfidentialCompute *ConfidentialComputePolicy `json:"confidentialCompute,omitempty"`
}
44 changes: 44 additions & 0 deletions pkg/types/aws/validation/machinepool.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,11 @@ var (
}()

validMetadataAuthValues = sets.NewString("Required", "Optional")

validConfidentialComputePolicy = []aws.ConfidentialComputePolicy{
aws.ConfidentialComputePolicyDisabled,
aws.ConfidentialComputePolicySEVSNP,
}
)

// AWS has a limit of 16 security groups. See:
Expand All @@ -53,6 +58,7 @@ func ValidateMachinePool(platform *aws.Platform, p *aws.MachinePool, fldPath *fi
}

allErrs = append(allErrs, validateSecurityGroups(platform, p, fldPath)...)
allErrs = append(allErrs, ValidateCPUOptions(p, fldPath)...)

return allErrs
}
Expand Down Expand Up @@ -133,3 +139,41 @@ func ValidateMachinePoolArchitecture(pool *types.MachinePool, fldPath *field.Pat
}
return allErrs
}

// ValidateCPUOptions checks that valid CPU options are set for a machine pool.
func ValidateCPUOptions(p *aws.MachinePool, fldPath *field.Path) field.ErrorList {
if p.CPUOptions == nil {
return nil
}

allErrs := field.ErrorList{}

if *p.CPUOptions == (aws.CPUOptions{}) {
allErrs = append(
allErrs,
field.Invalid(
fldPath.Child("cpuOptions"),
"{}",
"At least one field must be set if cpuOptions is provided",
),
)
}

if p.CPUOptions.ConfidentialCompute != nil {
switch *p.CPUOptions.ConfidentialCompute {
case aws.ConfidentialComputePolicyDisabled, aws.ConfidentialComputePolicySEVSNP:
// Valid values
default:
allErrs = append(
allErrs,
field.NotSupported(
fldPath.Child("confidentialCompute"),
p.CPUOptions.ConfidentialCompute,
validConfidentialComputePolicy,
),
)
}
}

return allErrs
}
55 changes: 55 additions & 0 deletions pkg/types/aws/validation/machinepool_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (

"github.com/stretchr/testify/assert"
"k8s.io/apimachinery/pkg/util/validation/field"
"k8s.io/utils/ptr"

"github.com/openshift/installer/pkg/types/aws"
)
Expand Down Expand Up @@ -250,3 +251,57 @@ func Test_validateAMIID(t *testing.T) {
})
}
}

func Test_validateCPUOptions(t *testing.T) {
cases := []struct {
name string
pool *aws.MachinePool
err string
}{{
name: "confidential compute policy set to AMD SEV-SNP",
pool: &aws.MachinePool{
CPUOptions: &aws.CPUOptions{
ConfidentialCompute: ptr.To(aws.ConfidentialComputePolicySEVSNP),
},
},
}, {
name: "confidential compute disabled",
pool: &aws.MachinePool{
CPUOptions: &aws.CPUOptions{
ConfidentialCompute: ptr.To(aws.ConfidentialComputePolicyDisabled),
},
},
}, {
name: "empty confidential compute policy",
pool: &aws.MachinePool{
CPUOptions: &aws.CPUOptions{
ConfidentialCompute: ptr.To(aws.ConfidentialComputePolicy("")),
},
},
err: `^test-path.confidentialCompute: Unsupported value: "": supported values: "Disabled", "AMDEncryptedVirtualizationNestedPaging"$`,
}, {
name: "invalid confidential compute policy",
pool: &aws.MachinePool{
CPUOptions: &aws.CPUOptions{
ConfidentialCompute: ptr.To(aws.ConfidentialComputePolicy("invalid")),
},
},
err: `^test-path.confidentialCompute: Unsupported value: "invalid": supported values: "Disabled", "AMDEncryptedVirtualizationNestedPaging"$`,
}, {
name: "empty cpu options",
pool: &aws.MachinePool{
CPUOptions: &aws.CPUOptions{},
},
err: `^test-path.cpuOptions: Invalid value: "{}": At least one field must be set if cpuOptions is provided$`,
}}
for _, tc := range cases {
t.Run(tc.name, func(t *testing.T) {
err := ValidateCPUOptions(tc.pool, field.NewPath("test-path")).ToAggregate()
if tc.err == "" {
assert.NoError(t, err)
} else {
assert.Regexp(t, tc.err, err)
}
})
}
}
Loading