Skip to content

Commit a6e7d1a

Browse files
authored
Merge pull request #1410 from bgartzi/gcp-sev_snp
Support SEV_SNP instance type configuration
2 parents be453fe + 081b579 commit a6e7d1a

File tree

8 files changed

+376
-13
lines changed

8 files changed

+376
-13
lines changed

api/v1beta1/gcpmachine_types.go

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -134,11 +134,18 @@ const (
134134
ConfidentialComputePolicyEnabled ConfidentialComputePolicy = "Enabled"
135135
// ConfidentialComputePolicyDisabled disables confidential compute for the GCP machine.
136136
ConfidentialComputePolicyDisabled ConfidentialComputePolicy = "Disabled"
137+
// ConfidentialComputePolicySEV sets AMD SEV as the VM instance's confidential computing technology of choice.
138+
ConfidentialComputePolicySEV ConfidentialComputePolicy = "AMDEncrytedVirtualization"
139+
// ConfidentialComputePolicySEVSNP sets AMD SEV-SNP as the VM instance's confidential computing technology of choice.
140+
ConfidentialComputePolicySEVSNP ConfidentialComputePolicy = "AMDEncrytedVirtualizationNestedPaging"
137141
)
138142

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

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

338-
// ConfidentialCompute Defines whether the instance should have confidential compute enabled.
339-
// If enabled OnHostMaintenance is required to be set to "Terminate".
345+
// ConfidentialCompute Defines whether the instance should have confidential compute enabled or not, and the confidential computing technology of choice.
346+
// If Disabled, the machine will not be configured to be a confidential computing instance.
347+
// 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.
348+
// If AMDEncryptedVirtualization, it will configure AMD Secure Encrypted Virtualization (AMD SEV) as the confidential computing technology.
349+
// If AMDEncryptedVirtualizationNestedPaging, it will configure AMD Secure Encrypted Virtualization Secure Nested Paging (AMD SEV-SNP) as the confidential computing technology.
350+
// If enabled (any value other than Disabled) OnHostMaintenance is required to be set to "Terminate".
340351
// If omitted, the platform chooses a default, which is subject to change over time, currently that default is false.
341-
// +kubebuilder:validation:Enum=Enabled;Disabled
352+
// +kubebuilder:validation:Enum=Enabled;Disabled;AMDEncrytedVirtualization;AMDEncrytedVirtualizationNestedPaging
342353
// +optional
343354
ConfidentialCompute *ConfidentialComputePolicy `json:"confidentialCompute,omitempty"`
344355

api/v1beta1/gcpmachine_webhook.go

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -109,14 +109,23 @@ func (m *GCPMachine) Default() {
109109
}
110110

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

117117
machineSeries := strings.Split(spec.InstanceType, "-")[0]
118-
if !slices.Contains(confidentialComputeSupportedMachineSeries, machineSeries) {
119-
return fmt.Errorf("ConfidentialCompute require instance type in the following series: %s", confidentialComputeSupportedMachineSeries)
118+
switch *spec.ConfidentialCompute {
119+
case ConfidentialComputePolicyEnabled, ConfidentialComputePolicySEV:
120+
if !slices.Contains(confidentialMachineSeriesSupportingSev, machineSeries) {
121+
return fmt.Errorf("ConfidentialCompute %s requires any of the following machine series: %s. %s was found instead", *spec.ConfidentialCompute, strings.Join(confidentialMachineSeriesSupportingSev, ", "), spec.InstanceType)
122+
}
123+
case ConfidentialComputePolicySEVSNP:
124+
if !slices.Contains(confidentialMachineSeriesSupportingSevsnp, machineSeries) {
125+
return fmt.Errorf("ConfidentialCompute %s requires any of the following machine series: %s. %s was found instead", *spec.ConfidentialCompute, strings.Join(confidentialMachineSeriesSupportingSevsnp, ", "), spec.InstanceType)
126+
}
127+
default:
128+
return fmt.Errorf("invalid ConfidentialCompute %s", *spec.ConfidentialCompute)
120129
}
121130
}
122131
return nil

api/v1beta1/gcpmachine_webhook_test.go

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,9 @@ import (
2525
func TestGCPMachine_ValidateCreate(t *testing.T) {
2626
g := NewWithT(t)
2727
confidentialComputeEnabled := ConfidentialComputePolicyEnabled
28+
confidentialComputeSEV := ConfidentialComputePolicySEV
29+
confidentialComputeSEVSNP := ConfidentialComputePolicySEVSNP
30+
confidentialComputeFooBar := ConfidentialComputePolicy("foobar")
2831
onHostMaintenanceTerminate := HostMaintenancePolicyTerminate
2932
onHostMaintenanceMigrate := HostMaintenancePolicyMigrate
3033
tests := []struct {
@@ -85,6 +88,83 @@ func TestGCPMachine_ValidateCreate(t *testing.T) {
8588
},
8689
wantErr: true,
8790
},
91+
{
92+
name: "GCPMachine with ConfidentialCompute AMDEncryptedVirtualization and supported instance type - valid",
93+
GCPMachine: &GCPMachine{
94+
Spec: GCPMachineSpec{
95+
InstanceType: "c3d-standard-4",
96+
ConfidentialCompute: &confidentialComputeSEV,
97+
OnHostMaintenance: &onHostMaintenanceTerminate,
98+
},
99+
},
100+
wantErr: false,
101+
},
102+
{
103+
name: "GCPMachine with ConfidentialCompute AMDEncryptedVirtualization and unsupported instance type - invalid",
104+
GCPMachine: &GCPMachine{
105+
Spec: GCPMachineSpec{
106+
InstanceType: "e2-standard-4",
107+
ConfidentialCompute: &confidentialComputeSEV,
108+
OnHostMaintenance: &onHostMaintenanceTerminate,
109+
},
110+
},
111+
wantErr: true,
112+
},
113+
{
114+
name: "GCPMachine with ConfidentialCompute AMDEncryptedVirtualization and OnHostMaintenance Migrate - invalid",
115+
GCPMachine: &GCPMachine{
116+
Spec: GCPMachineSpec{
117+
InstanceType: "c2d-standard-4",
118+
ConfidentialCompute: &confidentialComputeSEV,
119+
OnHostMaintenance: &onHostMaintenanceMigrate,
120+
},
121+
},
122+
wantErr: true,
123+
},
124+
{
125+
name: "GCPMachine with ConfidentialCompute AMDEncryptedVirtualizationNestedPaging and supported instance type - valid",
126+
GCPMachine: &GCPMachine{
127+
Spec: GCPMachineSpec{
128+
InstanceType: "n2d-standard-4",
129+
ConfidentialCompute: &confidentialComputeSEVSNP,
130+
OnHostMaintenance: &onHostMaintenanceTerminate,
131+
},
132+
},
133+
wantErr: false,
134+
},
135+
{
136+
name: "GCPMachine with ConfidentialCompute AMDEncryptedVirtualizationNestedPaging and unsupported instance type - invalid",
137+
GCPMachine: &GCPMachine{
138+
Spec: GCPMachineSpec{
139+
InstanceType: "e2-standard-4",
140+
ConfidentialCompute: &confidentialComputeSEVSNP,
141+
OnHostMaintenance: &onHostMaintenanceTerminate,
142+
},
143+
},
144+
wantErr: true,
145+
},
146+
{
147+
name: "GCPMachine with ConfidentialCompute AMDEncryptedVirtualizationNestedPaging and OnHostMaintenance Migrate - invalid",
148+
GCPMachine: &GCPMachine{
149+
Spec: GCPMachineSpec{
150+
InstanceType: "n2d-standard-4",
151+
ConfidentialCompute: &confidentialComputeSEVSNP,
152+
OnHostMaintenance: &onHostMaintenanceMigrate,
153+
},
154+
},
155+
wantErr: true,
156+
},
157+
{
158+
name: "GCPMachine with ConfidentialCompute foobar - invalid",
159+
GCPMachine: &GCPMachine{
160+
Spec: GCPMachineSpec{
161+
InstanceType: "n2d-standard-4",
162+
ConfidentialCompute: &confidentialComputeFooBar,
163+
OnHostMaintenance: &onHostMaintenanceTerminate,
164+
},
165+
},
166+
wantErr: true,
167+
},
88168
{
89169
name: "GCPMachine with RootDiskEncryptionKey KeyType Managed and Managed field set",
90170
GCPMachine: &GCPMachine{

api/v1beta1/gcpmachinetemplate_webhook_test.go

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ import (
2525
func TestGCPMachineTemplate_ValidateCreate(t *testing.T) {
2626
g := NewWithT(t)
2727
confidentialComputeEnabled := ConfidentialComputePolicyEnabled
28+
confidentialComputeSEV := ConfidentialComputePolicySEV
29+
confidentialComputeSEVSNP := ConfidentialComputePolicySEVSNP
2830
onHostMaintenanceTerminate := HostMaintenancePolicyTerminate
2931
onHostMaintenanceMigrate := HostMaintenancePolicyMigrate
3032
tests := []struct {
@@ -105,6 +107,96 @@ func TestGCPMachineTemplate_ValidateCreate(t *testing.T) {
105107
},
106108
wantErr: true,
107109
},
110+
{
111+
name: "GCPMachineTemplate with ConfidentialCompute AMDEncryptedVirtualization and unsupported instance type - invalid",
112+
template: &GCPMachineTemplate{
113+
Spec: GCPMachineTemplateSpec{
114+
Template: GCPMachineTemplateResource{
115+
Spec: GCPMachineSpec{
116+
InstanceType: "e2-standard-4",
117+
ConfidentialCompute: &confidentialComputeSEV,
118+
OnHostMaintenance: &onHostMaintenanceTerminate,
119+
},
120+
},
121+
},
122+
},
123+
wantErr: true,
124+
},
125+
{
126+
name: "GCPMachineTemplate with ConfidentialCompute AMDEncryptedVirtualization and supported instance type - valid",
127+
template: &GCPMachineTemplate{
128+
Spec: GCPMachineTemplateSpec{
129+
Template: GCPMachineTemplateResource{
130+
Spec: GCPMachineSpec{
131+
InstanceType: "c2d-standard-4",
132+
ConfidentialCompute: &confidentialComputeSEV,
133+
OnHostMaintenance: &onHostMaintenanceTerminate,
134+
},
135+
},
136+
},
137+
},
138+
wantErr: false,
139+
},
140+
{
141+
name: "GCPMachineTemplate with ConfidentialCompute AMDEncryptedVirtualization and OnHostMaintenance Migrate - invalid",
142+
template: &GCPMachineTemplate{
143+
Spec: GCPMachineTemplateSpec{
144+
Template: GCPMachineTemplateResource{
145+
Spec: GCPMachineSpec{
146+
InstanceType: "c2d-standard-4",
147+
ConfidentialCompute: &confidentialComputeSEV,
148+
OnHostMaintenance: &onHostMaintenanceMigrate,
149+
},
150+
},
151+
},
152+
},
153+
wantErr: true,
154+
},
155+
{
156+
name: "GCPMachineTemplate with ConfidentialCompute AMDEncryptedVirtualizationNestedPaging and unsupported instance type - invalid",
157+
template: &GCPMachineTemplate{
158+
Spec: GCPMachineTemplateSpec{
159+
Template: GCPMachineTemplateResource{
160+
Spec: GCPMachineSpec{
161+
InstanceType: "c2d-standard-4",
162+
ConfidentialCompute: &confidentialComputeSEVSNP,
163+
OnHostMaintenance: &onHostMaintenanceTerminate,
164+
},
165+
},
166+
},
167+
},
168+
wantErr: true,
169+
},
170+
{
171+
name: "GCPMachineTemplate with ConfidentialCompute AMDEncryptedVirtualizationNestedPaging and supported instance type - valid",
172+
template: &GCPMachineTemplate{
173+
Spec: GCPMachineTemplateSpec{
174+
Template: GCPMachineTemplateResource{
175+
Spec: GCPMachineSpec{
176+
InstanceType: "n2d-standard-4",
177+
ConfidentialCompute: &confidentialComputeSEVSNP,
178+
OnHostMaintenance: &onHostMaintenanceTerminate,
179+
},
180+
},
181+
},
182+
},
183+
wantErr: false,
184+
},
185+
{
186+
name: "GCPMachineTemplate with ConfidentialCompute AMDEncryptedVirtualizationNestedPaging and OnHostMaintenance Migrate - invalid",
187+
template: &GCPMachineTemplate{
188+
Spec: GCPMachineTemplateSpec{
189+
Template: GCPMachineTemplateResource{
190+
Spec: GCPMachineSpec{
191+
InstanceType: "c2d-standard-4",
192+
ConfidentialCompute: &confidentialComputeSEVSNP,
193+
OnHostMaintenance: &onHostMaintenanceMigrate,
194+
},
195+
},
196+
},
197+
},
198+
wantErr: true,
199+
},
108200
}
109201
for _, test := range tests {
110202
t.Run(test.name, func(t *testing.T) {

cloud/scope/machine.go

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -445,10 +445,17 @@ func (m *MachineScope) InstanceSpec(log logr.Logger) *compute.Instance {
445445
instance.Scheduling.OnHostMaintenance = strings.ToUpper(string(*m.GCPMachine.Spec.OnHostMaintenance))
446446
}
447447
if m.GCPMachine.Spec.ConfidentialCompute != nil {
448-
enabled := *m.GCPMachine.Spec.ConfidentialCompute == infrav1.ConfidentialComputePolicyEnabled
448+
enabled := *m.GCPMachine.Spec.ConfidentialCompute != infrav1.ConfidentialComputePolicyDisabled
449449
instance.ConfidentialInstanceConfig = &compute.ConfidentialInstanceConfig{
450450
EnableConfidentialCompute: enabled,
451451
}
452+
switch *m.GCPMachine.Spec.ConfidentialCompute {
453+
case infrav1.ConfidentialComputePolicySEV:
454+
instance.ConfidentialInstanceConfig.ConfidentialInstanceType = "SEV"
455+
case infrav1.ConfidentialComputePolicySEVSNP:
456+
instance.ConfidentialInstanceConfig.ConfidentialInstanceType = "SEV_SNP"
457+
default:
458+
}
452459
}
453460

454461
instance.Disks = append(instance.Disks, m.InstanceImageSpec())

0 commit comments

Comments
 (0)