Skip to content

Commit 33a4fb8

Browse files
committed
Support SEV_SNP instance type configuration
Only SEV machines could be configured by using the former confidentialCompute Enabled/Disabled. GCP allows now to also configure the confidential instance type as well by using the appropriate parameter, see [0]. This commit introduces confidentialInstanceType, which lets users choose between sev or sev-snp as their confidential computing technology of choice. The reason confidentialInstanceType will preceed confidentialCompute is to mimic GCP's behavior, and ensuring backwards compatibility. Meanwhile, add c3d as a machine that supports AMD SEV. [0] https://cloud.google.com/confidential-computing/confidential-vm/docs/create-a-confidential-vm-instance#rest
1 parent f24b413 commit 33a4fb8

File tree

9 files changed

+341
-4
lines changed

9 files changed

+341
-4
lines changed

api/v1beta1/gcpmachine_types.go

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,9 +137,22 @@ const (
137137
ConfidentialComputePolicyDisabled ConfidentialComputePolicy = "Disabled"
138138
)
139139

140+
// ConfidentialVMTechnology represents the confidential computing technology used by a GCP confidential machine.
141+
type ConfidentialVMTechnology string
142+
143+
const (
144+
// ConfidentialVMTechSEV sets AMD SEV as the VM instance's confidential computing technology of choice.
145+
ConfidentialVMTechSEV ConfidentialVMTechnology = "sev"
146+
// ConfidentialVMTechSEVSNP sets AMD SEV-SNP as the VM instance's confidential computing technology of choice.
147+
ConfidentialVMTechSEVSNP ConfidentialVMTechnology = "sev-snp"
148+
)
149+
140150
// Confidential VM supports Compute Engine machine types in the following series:
141151
// reference: https://cloud.google.com/compute/confidential-vm/docs/os-and-machine-type#machine-type
142-
var confidentialComputeSupportedMachineSeries = []string{"n2d", "c2d"}
152+
var confidentialComputeSupportedMachineSeries = map[ConfidentialVMTechnology][]string{
153+
ConfidentialVMTechSEV: {"n2d", "c2d", "c3d"},
154+
ConfidentialVMTechSEVSNP: {"n2d"},
155+
}
143156

144157
// HostMaintenancePolicy represents the desired behavior ase of a host maintenance event.
145158
type HostMaintenancePolicy string
@@ -339,10 +352,18 @@ type GCPMachineSpec struct {
339352
// ConfidentialCompute Defines whether the instance should have confidential compute enabled.
340353
// If enabled OnHostMaintenance is required to be set to "Terminate".
341354
// If omitted, the platform chooses a default, which is subject to change over time, currently that default is false.
355+
// If ConfidentialInstanceType is configured, even if ConfidentialCompute is Disabled, a confidential compute instance will be configured.
342356
// +kubebuilder:validation:Enum=Enabled;Disabled
343357
// +optional
344358
ConfidentialCompute *ConfidentialComputePolicy `json:"confidentialCompute,omitempty"`
345359

360+
// confidentialInstanceType determines the required type of confidential computing technology.
361+
// confidentialInstanceType will preceed confidentialCompute. That is, if confidentialCompute is "Disabled" but a valid confidentialInstanceType is specified, a confidential instance will be configured.
362+
// If confidentialInstanceType isn't set and confidentialCompute is "Enabled" the platform will set the default, which is subject to change over time. Currently the default is "sev" for "c2d", "c3d", and "n2d" machineTypes. For the other machine cases, a valid confidentialInstanceType must be specified.
363+
// +kubebuilder:validation:Enum=sev;sev-snp;
364+
// +optional
365+
ConfidentialInstanceType *ConfidentialVMTechnology `json:"confidentialInstanceType,omitempty"`
366+
346367
// RootDiskEncryptionKey defines the KMS key to be used to encrypt the root disk.
347368
// +optional
348369
RootDiskEncryptionKey *CustomerEncryptionKey `json:"rootDiskEncryptionKey,omitempty"`

api/v1beta1/gcpmachine_webhook.go

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -108,15 +108,32 @@ func (m *GCPMachine) Default() {
108108
clusterlog.Info("default", "name", m.Name)
109109
}
110110

111+
func targetConfidentialType(tech *ConfidentialVMTechnology) (ConfidentialVMTechnology, error) {
112+
if tech == nil || tech != nil && *tech == "" {
113+
return ConfidentialVMTechSEV, nil
114+
}
115+
_, ok := confidentialComputeSupportedMachineSeries[*tech]
116+
if !ok {
117+
return "", fmt.Errorf("Invalid ConfidentialInstanceType %s", *tech)
118+
}
119+
return *tech, nil
120+
}
121+
111122
func validateConfidentialCompute(spec GCPMachineSpec) error {
112-
if spec.ConfidentialCompute != nil && *spec.ConfidentialCompute == ConfidentialComputePolicyEnabled {
123+
if spec.ConfidentialCompute != nil && *spec.ConfidentialCompute == ConfidentialComputePolicyEnabled || spec.ConfidentialInstanceType != nil && *spec.ConfidentialInstanceType != "" {
113124
if spec.OnHostMaintenance == nil || *spec.OnHostMaintenance == HostMaintenancePolicyMigrate {
114125
return fmt.Errorf("ConfidentialCompute require OnHostMaintenance to be set to %s, the current value is: %s", HostMaintenancePolicyTerminate, HostMaintenancePolicyMigrate)
115126
}
116127

128+
confidentialType, err := targetConfidentialType(spec.ConfidentialInstanceType)
129+
if err != nil {
130+
return err
131+
}
132+
supportedMachines := confidentialComputeSupportedMachineSeries[confidentialType]
133+
117134
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)
135+
if !slices.Contains(supportedMachines, machineSeries) {
136+
return fmt.Errorf("ConfidentialInstanceType %s requires an instance type in the following series: %s", confidentialType, supportedMachines)
120137
}
121138
}
122139
return nil

api/v1beta1/gcpmachine_webhook_test.go

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ func TestGCPMachine_ValidateCreate(t *testing.T) {
2727
confidentialComputeEnabled := ConfidentialComputePolicyEnabled
2828
onHostMaintenanceTerminate := HostMaintenancePolicyTerminate
2929
onHostMaintenanceMigrate := HostMaintenancePolicyMigrate
30+
confidentialInstanceTypeSEV := ConfidentialVMTechSEV
31+
confidentialInstanceTypeSEVSNP := ConfidentialVMTechSEVSNP
3032
tests := []struct {
3133
name string
3234
*GCPMachine
@@ -85,6 +87,50 @@ func TestGCPMachine_ValidateCreate(t *testing.T) {
8587
},
8688
wantErr: true,
8789
},
90+
{
91+
name: "GCPMachine with explicit ConfidentialInstanceType and OnHostMaintenance Migrate - invalid",
92+
GCPMachine: &GCPMachine{
93+
Spec: GCPMachineSpec{
94+
InstanceType: "n2d-standard-4",
95+
ConfidentialInstanceType: &confidentialInstanceTypeSEVSNP,
96+
OnHostMaintenance: &onHostMaintenanceMigrate,
97+
},
98+
},
99+
wantErr: true,
100+
},
101+
{
102+
name: "GCPMachine with SEVSNP ConfidentialInstanceType and unsupported machine type - invalid",
103+
GCPMachine: &GCPMachine{
104+
Spec: GCPMachineSpec{
105+
InstanceType: "c2d-standard-4",
106+
ConfidentialInstanceType: &confidentialInstanceTypeSEVSNP,
107+
OnHostMaintenance: &onHostMaintenanceTerminate,
108+
},
109+
},
110+
wantErr: true,
111+
},
112+
{
113+
name: "GCPMachine with SEVSNP ConfidentialInstanceType and supported machine type - valid",
114+
GCPMachine: &GCPMachine{
115+
Spec: GCPMachineSpec{
116+
InstanceType: "n2d-standard-4",
117+
ConfidentialInstanceType: &confidentialInstanceTypeSEVSNP,
118+
OnHostMaintenance: &onHostMaintenanceTerminate,
119+
},
120+
},
121+
wantErr: false,
122+
},
123+
{
124+
name: "GCPMachine with explicit SEV ConfidentialInstanceType and supported machine type - valid",
125+
GCPMachine: &GCPMachine{
126+
Spec: GCPMachineSpec{
127+
InstanceType: "c3d-standard-4",
128+
ConfidentialInstanceType: &confidentialInstanceTypeSEV,
129+
OnHostMaintenance: &onHostMaintenanceTerminate,
130+
},
131+
},
132+
wantErr: false,
133+
},
88134
{
89135
name: "GCPMachine with RootDiskEncryptionKey KeyType Managed and Managed field set",
90136
GCPMachine: &GCPMachine{

api/v1beta1/gcpmachinetemplate_webhook_test.go

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ func TestGCPMachineTemplate_ValidateCreate(t *testing.T) {
2727
confidentialComputeEnabled := ConfidentialComputePolicyEnabled
2828
onHostMaintenanceTerminate := HostMaintenancePolicyTerminate
2929
onHostMaintenanceMigrate := HostMaintenancePolicyMigrate
30+
confidentialInstanceTypeSEV := ConfidentialVMTechSEV
31+
confidentialInstanceTypeSEVSNP := ConfidentialVMTechSEVSNP
3032
tests := []struct {
3133
name string
3234
template *GCPMachineTemplate
@@ -105,6 +107,66 @@ func TestGCPMachineTemplate_ValidateCreate(t *testing.T) {
105107
},
106108
wantErr: true,
107109
},
110+
{
111+
name: "GCPMachine with explicit ConfidentialInstanceType and OnHostMaintenance Migrate - invalid",
112+
template: &GCPMachineTemplate{
113+
Spec: GCPMachineTemplateSpec{
114+
Template: GCPMachineTemplateResource{
115+
Spec: GCPMachineSpec{
116+
InstanceType: "n2d-standard-4",
117+
ConfidentialInstanceType: &confidentialInstanceTypeSEVSNP,
118+
OnHostMaintenance: &onHostMaintenanceMigrate,
119+
},
120+
},
121+
},
122+
},
123+
wantErr: true,
124+
},
125+
{
126+
name: "GCPMachine with SEVSNP ConfidentialInstanceType and unsupported machine type - invalid",
127+
template: &GCPMachineTemplate{
128+
Spec: GCPMachineTemplateSpec{
129+
Template: GCPMachineTemplateResource{
130+
Spec: GCPMachineSpec{
131+
InstanceType: "c3d-standard-4",
132+
ConfidentialInstanceType: &confidentialInstanceTypeSEVSNP,
133+
OnHostMaintenance: &onHostMaintenanceTerminate,
134+
},
135+
},
136+
},
137+
},
138+
wantErr: true,
139+
},
140+
{
141+
name: "GCPMachine with SEVSNP ConfidentialInstanceType and supported machine type - valid",
142+
template: &GCPMachineTemplate{
143+
Spec: GCPMachineTemplateSpec{
144+
Template: GCPMachineTemplateResource{
145+
Spec: GCPMachineSpec{
146+
InstanceType: "n2d-standard-4",
147+
ConfidentialInstanceType: &confidentialInstanceTypeSEVSNP,
148+
OnHostMaintenance: &onHostMaintenanceTerminate,
149+
},
150+
},
151+
},
152+
},
153+
wantErr: false,
154+
},
155+
{
156+
name: "GCPMachine with explicit SEV ConfidentialInstanceType and supported machine type - valid",
157+
template: &GCPMachineTemplate{
158+
Spec: GCPMachineTemplateSpec{
159+
Template: GCPMachineTemplateResource{
160+
Spec: GCPMachineSpec{
161+
InstanceType: "c3d-standard-4",
162+
ConfidentialInstanceType: &confidentialInstanceTypeSEV,
163+
OnHostMaintenance: &onHostMaintenanceTerminate,
164+
},
165+
},
166+
},
167+
},
168+
wantErr: false,
169+
},
108170
}
109171
for _, test := range tests {
110172
t.Run(test.name, func(t *testing.T) {

api/v1beta1/zz_generated.deepcopy.go

Lines changed: 5 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

cloud/scope/machine.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -451,6 +451,19 @@ func (m *MachineScope) InstanceSpec(log logr.Logger) *compute.Instance {
451451
EnableConfidentialCompute: enabled,
452452
}
453453
}
454+
if m.GCPMachine.Spec.ConfidentialInstanceType != nil {
455+
if instance.ConfidentialInstanceConfig == nil {
456+
instance.ConfidentialInstanceConfig = &compute.ConfidentialInstanceConfig{}
457+
}
458+
switch *m.GCPMachine.Spec.ConfidentialInstanceType {
459+
case infrav1.ConfidentialVMTechSEV:
460+
instance.ConfidentialInstanceConfig.ConfidentialInstanceType = "SEV"
461+
case infrav1.ConfidentialVMTechSEVSNP:
462+
instance.ConfidentialInstanceConfig.ConfidentialInstanceType = "SEV_SNP"
463+
default:
464+
log.Error(errors.New("Invalid value"), "Unknown ConfidentialInstanceType value", "Spec.ConfidentialInstanceType", *m.GCPMachine.Spec.ConfidentialInstanceType)
465+
}
466+
}
454467

455468
instance.Disks = append(instance.Disks, m.InstanceImageSpec())
456469
instance.Disks = append(instance.Disks, m.InstanceAdditionalDiskSpec()...)

0 commit comments

Comments
 (0)