Skip to content

Commit

Permalink
Merge pull request #1410 from bgartzi/gcp-sev_snp
Browse files Browse the repository at this point in the history
Support SEV_SNP instance type configuration
  • Loading branch information
k8s-ci-robot authored Feb 12, 2025
2 parents be453fe + 081b579 commit a6e7d1a
Show file tree
Hide file tree
Showing 8 changed files with 376 additions and 13 deletions.
21 changes: 16 additions & 5 deletions api/v1beta1/gcpmachine_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -134,11 +134,18 @@ const (
ConfidentialComputePolicyEnabled ConfidentialComputePolicy = "Enabled"
// ConfidentialComputePolicyDisabled disables confidential compute for the GCP machine.
ConfidentialComputePolicyDisabled ConfidentialComputePolicy = "Disabled"
// ConfidentialComputePolicySEV sets AMD SEV as the VM instance's confidential computing technology of choice.
ConfidentialComputePolicySEV ConfidentialComputePolicy = "AMDEncrytedVirtualization"
// ConfidentialComputePolicySEVSNP sets AMD SEV-SNP as the VM instance's confidential computing technology of choice.
ConfidentialComputePolicySEVSNP ConfidentialComputePolicy = "AMDEncrytedVirtualizationNestedPaging"
)

// Confidential VM supports Compute Engine machine types in the following series:
// Confidential VM Technology support depends on the configured machine types.
// reference: https://cloud.google.com/compute/confidential-vm/docs/os-and-machine-type#machine-type
var confidentialComputeSupportedMachineSeries = []string{"n2d", "c2d"}
var (
confidentialMachineSeriesSupportingSev = []string{"n2d", "c2d", "c3d"}
confidentialMachineSeriesSupportingSevsnp = []string{"n2d"}
)

// HostMaintenancePolicy represents the desired behavior ase of a host maintenance event.
type HostMaintenancePolicy string
Expand Down Expand Up @@ -335,10 +342,14 @@ type GCPMachineSpec struct {
// +optional
OnHostMaintenance *HostMaintenancePolicy `json:"onHostMaintenance,omitempty"`

// ConfidentialCompute Defines whether the instance should have confidential compute enabled.
// If enabled OnHostMaintenance is required to be set to "Terminate".
// ConfidentialCompute Defines whether the instance should have confidential compute enabled or not, and the confidential computing technology of choice.
// If Disabled, the machine will not be configured to be a confidential computing instance.
// If Enabled, confidential computing will be configured and AMD Secure Encrypted Virtualization will be configured by default. That is subject to change over time. If using AMD Secure Encrypted Virtualization is vital, use AMDEncryptedVirtualization explicitly instead.
// If AMDEncryptedVirtualization, it will configure AMD Secure Encrypted Virtualization (AMD SEV) as the confidential computing technology.
// If AMDEncryptedVirtualizationNestedPaging, it will configure AMD Secure Encrypted Virtualization Secure Nested Paging (AMD SEV-SNP) as the confidential computing technology.
// If enabled (any value other than Disabled) OnHostMaintenance is required to be set to "Terminate".
// If omitted, the platform chooses a default, which is subject to change over time, currently that default is false.
// +kubebuilder:validation:Enum=Enabled;Disabled
// +kubebuilder:validation:Enum=Enabled;Disabled;AMDEncrytedVirtualization;AMDEncrytedVirtualizationNestedPaging
// +optional
ConfidentialCompute *ConfidentialComputePolicy `json:"confidentialCompute,omitempty"`

Expand Down
15 changes: 12 additions & 3 deletions api/v1beta1/gcpmachine_webhook.go
Original file line number Diff line number Diff line change
Expand Up @@ -109,14 +109,23 @@ func (m *GCPMachine) Default() {
}

func validateConfidentialCompute(spec GCPMachineSpec) error {
if spec.ConfidentialCompute != nil && *spec.ConfidentialCompute == ConfidentialComputePolicyEnabled {
if spec.ConfidentialCompute != nil && *spec.ConfidentialCompute != ConfidentialComputePolicyDisabled {
if spec.OnHostMaintenance == nil || *spec.OnHostMaintenance == HostMaintenancePolicyMigrate {
return fmt.Errorf("ConfidentialCompute require OnHostMaintenance to be set to %s, the current value is: %s", HostMaintenancePolicyTerminate, HostMaintenancePolicyMigrate)
}

machineSeries := strings.Split(spec.InstanceType, "-")[0]
if !slices.Contains(confidentialComputeSupportedMachineSeries, machineSeries) {
return fmt.Errorf("ConfidentialCompute require instance type in the following series: %s", confidentialComputeSupportedMachineSeries)
switch *spec.ConfidentialCompute {
case ConfidentialComputePolicyEnabled, ConfidentialComputePolicySEV:
if !slices.Contains(confidentialMachineSeriesSupportingSev, machineSeries) {
return fmt.Errorf("ConfidentialCompute %s requires any of the following machine series: %s. %s was found instead", *spec.ConfidentialCompute, strings.Join(confidentialMachineSeriesSupportingSev, ", "), spec.InstanceType)
}
case ConfidentialComputePolicySEVSNP:
if !slices.Contains(confidentialMachineSeriesSupportingSevsnp, machineSeries) {
return fmt.Errorf("ConfidentialCompute %s requires any of the following machine series: %s. %s was found instead", *spec.ConfidentialCompute, strings.Join(confidentialMachineSeriesSupportingSevsnp, ", "), spec.InstanceType)
}
default:
return fmt.Errorf("invalid ConfidentialCompute %s", *spec.ConfidentialCompute)
}
}
return nil
Expand Down
80 changes: 80 additions & 0 deletions api/v1beta1/gcpmachine_webhook_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ import (
func TestGCPMachine_ValidateCreate(t *testing.T) {
g := NewWithT(t)
confidentialComputeEnabled := ConfidentialComputePolicyEnabled
confidentialComputeSEV := ConfidentialComputePolicySEV
confidentialComputeSEVSNP := ConfidentialComputePolicySEVSNP
confidentialComputeFooBar := ConfidentialComputePolicy("foobar")
onHostMaintenanceTerminate := HostMaintenancePolicyTerminate
onHostMaintenanceMigrate := HostMaintenancePolicyMigrate
tests := []struct {
Expand Down Expand Up @@ -85,6 +88,83 @@ func TestGCPMachine_ValidateCreate(t *testing.T) {
},
wantErr: true,
},
{
name: "GCPMachine with ConfidentialCompute AMDEncryptedVirtualization and supported instance type - valid",
GCPMachine: &GCPMachine{
Spec: GCPMachineSpec{
InstanceType: "c3d-standard-4",
ConfidentialCompute: &confidentialComputeSEV,
OnHostMaintenance: &onHostMaintenanceTerminate,
},
},
wantErr: false,
},
{
name: "GCPMachine with ConfidentialCompute AMDEncryptedVirtualization and unsupported instance type - invalid",
GCPMachine: &GCPMachine{
Spec: GCPMachineSpec{
InstanceType: "e2-standard-4",
ConfidentialCompute: &confidentialComputeSEV,
OnHostMaintenance: &onHostMaintenanceTerminate,
},
},
wantErr: true,
},
{
name: "GCPMachine with ConfidentialCompute AMDEncryptedVirtualization and OnHostMaintenance Migrate - invalid",
GCPMachine: &GCPMachine{
Spec: GCPMachineSpec{
InstanceType: "c2d-standard-4",
ConfidentialCompute: &confidentialComputeSEV,
OnHostMaintenance: &onHostMaintenanceMigrate,
},
},
wantErr: true,
},
{
name: "GCPMachine with ConfidentialCompute AMDEncryptedVirtualizationNestedPaging and supported instance type - valid",
GCPMachine: &GCPMachine{
Spec: GCPMachineSpec{
InstanceType: "n2d-standard-4",
ConfidentialCompute: &confidentialComputeSEVSNP,
OnHostMaintenance: &onHostMaintenanceTerminate,
},
},
wantErr: false,
},
{
name: "GCPMachine with ConfidentialCompute AMDEncryptedVirtualizationNestedPaging and unsupported instance type - invalid",
GCPMachine: &GCPMachine{
Spec: GCPMachineSpec{
InstanceType: "e2-standard-4",
ConfidentialCompute: &confidentialComputeSEVSNP,
OnHostMaintenance: &onHostMaintenanceTerminate,
},
},
wantErr: true,
},
{
name: "GCPMachine with ConfidentialCompute AMDEncryptedVirtualizationNestedPaging and OnHostMaintenance Migrate - invalid",
GCPMachine: &GCPMachine{
Spec: GCPMachineSpec{
InstanceType: "n2d-standard-4",
ConfidentialCompute: &confidentialComputeSEVSNP,
OnHostMaintenance: &onHostMaintenanceMigrate,
},
},
wantErr: true,
},
{
name: "GCPMachine with ConfidentialCompute foobar - invalid",
GCPMachine: &GCPMachine{
Spec: GCPMachineSpec{
InstanceType: "n2d-standard-4",
ConfidentialCompute: &confidentialComputeFooBar,
OnHostMaintenance: &onHostMaintenanceTerminate,
},
},
wantErr: true,
},
{
name: "GCPMachine with RootDiskEncryptionKey KeyType Managed and Managed field set",
GCPMachine: &GCPMachine{
Expand Down
92 changes: 92 additions & 0 deletions api/v1beta1/gcpmachinetemplate_webhook_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ import (
func TestGCPMachineTemplate_ValidateCreate(t *testing.T) {
g := NewWithT(t)
confidentialComputeEnabled := ConfidentialComputePolicyEnabled
confidentialComputeSEV := ConfidentialComputePolicySEV
confidentialComputeSEVSNP := ConfidentialComputePolicySEVSNP
onHostMaintenanceTerminate := HostMaintenancePolicyTerminate
onHostMaintenanceMigrate := HostMaintenancePolicyMigrate
tests := []struct {
Expand Down Expand Up @@ -105,6 +107,96 @@ func TestGCPMachineTemplate_ValidateCreate(t *testing.T) {
},
wantErr: true,
},
{
name: "GCPMachineTemplate with ConfidentialCompute AMDEncryptedVirtualization and unsupported instance type - invalid",
template: &GCPMachineTemplate{
Spec: GCPMachineTemplateSpec{
Template: GCPMachineTemplateResource{
Spec: GCPMachineSpec{
InstanceType: "e2-standard-4",
ConfidentialCompute: &confidentialComputeSEV,
OnHostMaintenance: &onHostMaintenanceTerminate,
},
},
},
},
wantErr: true,
},
{
name: "GCPMachineTemplate with ConfidentialCompute AMDEncryptedVirtualization and supported instance type - valid",
template: &GCPMachineTemplate{
Spec: GCPMachineTemplateSpec{
Template: GCPMachineTemplateResource{
Spec: GCPMachineSpec{
InstanceType: "c2d-standard-4",
ConfidentialCompute: &confidentialComputeSEV,
OnHostMaintenance: &onHostMaintenanceTerminate,
},
},
},
},
wantErr: false,
},
{
name: "GCPMachineTemplate with ConfidentialCompute AMDEncryptedVirtualization and OnHostMaintenance Migrate - invalid",
template: &GCPMachineTemplate{
Spec: GCPMachineTemplateSpec{
Template: GCPMachineTemplateResource{
Spec: GCPMachineSpec{
InstanceType: "c2d-standard-4",
ConfidentialCompute: &confidentialComputeSEV,
OnHostMaintenance: &onHostMaintenanceMigrate,
},
},
},
},
wantErr: true,
},
{
name: "GCPMachineTemplate with ConfidentialCompute AMDEncryptedVirtualizationNestedPaging and unsupported instance type - invalid",
template: &GCPMachineTemplate{
Spec: GCPMachineTemplateSpec{
Template: GCPMachineTemplateResource{
Spec: GCPMachineSpec{
InstanceType: "c2d-standard-4",
ConfidentialCompute: &confidentialComputeSEVSNP,
OnHostMaintenance: &onHostMaintenanceTerminate,
},
},
},
},
wantErr: true,
},
{
name: "GCPMachineTemplate with ConfidentialCompute AMDEncryptedVirtualizationNestedPaging and supported instance type - valid",
template: &GCPMachineTemplate{
Spec: GCPMachineTemplateSpec{
Template: GCPMachineTemplateResource{
Spec: GCPMachineSpec{
InstanceType: "n2d-standard-4",
ConfidentialCompute: &confidentialComputeSEVSNP,
OnHostMaintenance: &onHostMaintenanceTerminate,
},
},
},
},
wantErr: false,
},
{
name: "GCPMachineTemplate with ConfidentialCompute AMDEncryptedVirtualizationNestedPaging and OnHostMaintenance Migrate - invalid",
template: &GCPMachineTemplate{
Spec: GCPMachineTemplateSpec{
Template: GCPMachineTemplateResource{
Spec: GCPMachineSpec{
InstanceType: "c2d-standard-4",
ConfidentialCompute: &confidentialComputeSEVSNP,
OnHostMaintenance: &onHostMaintenanceMigrate,
},
},
},
},
wantErr: true,
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
Expand Down
9 changes: 8 additions & 1 deletion cloud/scope/machine.go
Original file line number Diff line number Diff line change
Expand Up @@ -445,10 +445,17 @@ func (m *MachineScope) InstanceSpec(log logr.Logger) *compute.Instance {
instance.Scheduling.OnHostMaintenance = strings.ToUpper(string(*m.GCPMachine.Spec.OnHostMaintenance))
}
if m.GCPMachine.Spec.ConfidentialCompute != nil {
enabled := *m.GCPMachine.Spec.ConfidentialCompute == infrav1.ConfidentialComputePolicyEnabled
enabled := *m.GCPMachine.Spec.ConfidentialCompute != infrav1.ConfidentialComputePolicyDisabled
instance.ConfidentialInstanceConfig = &compute.ConfidentialInstanceConfig{
EnableConfidentialCompute: enabled,
}
switch *m.GCPMachine.Spec.ConfidentialCompute {
case infrav1.ConfidentialComputePolicySEV:
instance.ConfidentialInstanceConfig.ConfidentialInstanceType = "SEV"
case infrav1.ConfidentialComputePolicySEVSNP:
instance.ConfidentialInstanceConfig.ConfidentialInstanceType = "SEV_SNP"
default:
}
}

instance.Disks = append(instance.Disks, m.InstanceImageSpec())
Expand Down
Loading

0 comments on commit a6e7d1a

Please sign in to comment.