Skip to content

Commit dd02e5a

Browse files
committed
Add support for confidential VMs
Signed-off-by: Michail Resvanis <[email protected]>
1 parent 1437f81 commit dd02e5a

File tree

84 files changed

+5936
-193
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

84 files changed

+5936
-193
lines changed

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ require (
1515
github.com/mitchellh/mapstructure v1.5.0
1616
github.com/onsi/ginkgo/v2 v2.9.5
1717
github.com/onsi/gomega v1.27.7
18-
github.com/openshift/api v0.0.0-20230509100629-894b49f57a15
18+
github.com/openshift/api v0.0.0-20230707123100-21c0ce73add5
1919
github.com/openshift/machine-api-operator v0.2.1-0.20230531233206-931f6f67c1c7
2020
github.com/pkg/errors v0.9.1
2121
github.com/spf13/cobra v1.7.0

go.sum

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -449,6 +449,8 @@ github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9G
449449
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
450450
github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 h1:n6/2gBQ3RWajuToeY6ZtZTIKv2v7ThUy5KKusIT0yc0=
451451
github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00/go.mod h1:Pm3mSP3c5uWn86xMLZ5Sa7JB9GsEZySvHYXCTK4E9q4=
452+
github.com/mresvanis/api v0.0.0-20230706123929-dd9b8275a496 h1:OsDBTmU3l2/HwWVIQfUlv0DEZvFVxO8Bi6F6+W7OLRo=
453+
github.com/mresvanis/api v0.0.0-20230706123929-dd9b8275a496/go.mod h1:4VWG+W22wrB4HfBL88P40DxLEpSOaiBVxUnfalfJo9k=
452454
github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
453455
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
454456
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
@@ -467,8 +469,8 @@ github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGV
467469
github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
468470
github.com/onsi/gomega v1.27.7 h1:fVih9JD6ogIiHUN6ePK7HJidyEDpWGVB5mzM7cWNXoU=
469471
github.com/onsi/gomega v1.27.7/go.mod h1:1p8OOlwo2iUUDsHnOrjE5UKYJ+e3W8eQ3qSlRahPmr4=
470-
github.com/openshift/api v0.0.0-20230509100629-894b49f57a15 h1:0aKQixYOtjKB3NKhNzFeQ1t0oDOkacpaAN1ztfZufB8=
471-
github.com/openshift/api v0.0.0-20230509100629-894b49f57a15/go.mod h1:4VWG+W22wrB4HfBL88P40DxLEpSOaiBVxUnfalfJo9k=
472+
github.com/openshift/api v0.0.0-20230707123100-21c0ce73add5 h1:htabZ4P4mMAPTaTU0H0p++o/fmowJD5lnHR16ZBq3Js=
473+
github.com/openshift/api v0.0.0-20230707123100-21c0ce73add5/go.mod h1:yimSGmjsI+XF1mr+AKBs2//fSXIOhhetHGbMlBEfXbs=
472474
github.com/openshift/client-go v0.0.0-20230503144108-75015d2347cb h1:Nij5OnaECrkmcRQMAE9LMbQXPo95aqFnf+12B7SyFVI=
473475
github.com/openshift/client-go v0.0.0-20230503144108-75015d2347cb/go.mod h1:Rhb3moCqeiTuGHAbXBOlwPubUMlOZEkrEWTRjIF3jzs=
474476
github.com/openshift/library-go v0.0.0-20230508110756-9b7abe2c9cbf h1:ZpFAN2qprgp7jEhGPrOAwP8mmuYC9BRYzvDefg+k4GM=

pkg/cloud/azure/services/virtualmachines/virtualmachines.go

Lines changed: 126 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ import (
3636

3737
"golang.org/x/crypto/ssh"
3838
"k8s.io/klog/v2"
39+
"k8s.io/utils/pointer"
3940
)
4041

4142
const (
@@ -235,16 +236,11 @@ func (s *Service) deriveVirtualMachineParameters(vmSpec *Spec, nic network.Inter
235236
}
236237
}
237238

238-
var diskEncryptionSet *compute.DiskEncryptionSetParameters
239-
if vmSpec.OSDisk.ManagedDisk.DiskEncryptionSet != nil {
240-
diskEncryptionSet = &compute.DiskEncryptionSetParameters{ID: to.StringPtr(vmSpec.OSDisk.ManagedDisk.DiskEncryptionSet.ID)}
241-
}
239+
osDisk := generateOSDisk(vmSpec)
242240

243-
var securityProfile *compute.SecurityProfile
244-
if vmSpec.SecurityProfile != nil {
245-
securityProfile = &compute.SecurityProfile{
246-
EncryptionAtHost: vmSpec.SecurityProfile.EncryptionAtHost,
247-
}
241+
securityProfile, err := generateSecurityProfile(vmSpec, osDisk)
242+
if err != nil {
243+
return nil, err
248244
}
249245

250246
priority, evictionPolicy, billingProfile, err := getSpotVMOptions(s.Scope.MachineConfig.SpotVMOptions)
@@ -267,17 +263,8 @@ func (s *Service) deriveVirtualMachineParameters(vmSpec *Spec, nic network.Inter
267263
},
268264
StorageProfile: &compute.StorageProfile{
269265
ImageReference: imageReference,
270-
OsDisk: &compute.OSDisk{
271-
Name: to.StringPtr(fmt.Sprintf("%s_OSDisk", vmSpec.Name)),
272-
OsType: compute.OperatingSystemTypes(vmSpec.OSDisk.OSType),
273-
CreateOption: compute.DiskCreateOptionTypesFromImage,
274-
DiskSizeGB: to.Int32Ptr(vmSpec.OSDisk.DiskSizeGB),
275-
ManagedDisk: &compute.ManagedDiskParameters{
276-
StorageAccountType: compute.StorageAccountTypes(vmSpec.OSDisk.ManagedDisk.StorageAccountType),
277-
DiskEncryptionSet: diskEncryptionSet,
278-
},
279-
},
280-
DataDisks: &dataDisks,
266+
OsDisk: osDisk,
267+
DataDisks: &dataDisks,
281268
},
282269
SecurityProfile: securityProfile,
283270
OsProfile: osProfile,
@@ -436,6 +423,125 @@ func generateImagePlan(image machinev1.Image) *compute.Plan {
436423
}
437424
}
438425

426+
func generateOSDisk(vmSpec *Spec) *compute.OSDisk {
427+
osDisk := &compute.OSDisk{
428+
Name: to.StringPtr(fmt.Sprintf("%s_OSDisk", vmSpec.Name)),
429+
OsType: compute.OperatingSystemTypes(vmSpec.OSDisk.OSType),
430+
CreateOption: compute.DiskCreateOptionTypesFromImage,
431+
ManagedDisk: &compute.ManagedDiskParameters{},
432+
DiskSizeGB: to.Int32Ptr(vmSpec.OSDisk.DiskSizeGB),
433+
}
434+
435+
if vmSpec.OSDisk.ManagedDisk.StorageAccountType != "" {
436+
osDisk.ManagedDisk.StorageAccountType = compute.StorageAccountTypes(vmSpec.OSDisk.ManagedDisk.StorageAccountType)
437+
}
438+
if vmSpec.OSDisk.ManagedDisk.DiskEncryptionSet != nil {
439+
osDisk.ManagedDisk.DiskEncryptionSet = &compute.DiskEncryptionSetParameters{ID: to.StringPtr(vmSpec.OSDisk.ManagedDisk.DiskEncryptionSet.ID)}
440+
}
441+
if vmSpec.OSDisk.ManagedDisk.SecurityProfile.SecurityEncryptionType != "" {
442+
osDisk.ManagedDisk.SecurityProfile = &compute.VMDiskSecurityProfile{}
443+
444+
osDisk.ManagedDisk.SecurityProfile.SecurityEncryptionType = compute.SecurityEncryptionTypes(string(vmSpec.OSDisk.ManagedDisk.SecurityProfile.SecurityEncryptionType))
445+
446+
if vmSpec.OSDisk.ManagedDisk.SecurityProfile.DiskEncryptionSet.ID != "" {
447+
osDisk.ManagedDisk.SecurityProfile.DiskEncryptionSet = &compute.DiskEncryptionSetParameters{ID: pointer.String(vmSpec.OSDisk.ManagedDisk.SecurityProfile.DiskEncryptionSet.ID)}
448+
}
449+
}
450+
451+
return osDisk
452+
}
453+
454+
func generateSecurityProfile(vmSpec *Spec, osDisk *compute.OSDisk) (*compute.SecurityProfile, error) {
455+
if vmSpec.SecurityProfile == nil {
456+
return nil, nil
457+
}
458+
459+
securityProfile := &compute.SecurityProfile{
460+
EncryptionAtHost: vmSpec.SecurityProfile.EncryptionAtHost,
461+
}
462+
463+
if osDisk.ManagedDisk != nil &&
464+
osDisk.ManagedDisk.SecurityProfile != nil &&
465+
osDisk.ManagedDisk.SecurityProfile.SecurityEncryptionType != "" {
466+
467+
if vmSpec.SecurityProfile.Settings.SecurityType != machinev1.SecurityTypesConfidentialVM {
468+
return nil, apierrors.InvalidMachineConfiguration("failed to generate security profile for vm %s. "+
469+
"SecurityType should be set to %s when SecurityEncryptionType is defined.",
470+
vmSpec.Name, compute.SecurityTypesConfidentialVM)
471+
}
472+
473+
if vmSpec.SecurityProfile.Settings.ConfidentialVM == nil {
474+
return nil, apierrors.InvalidMachineConfiguration("failed to generate security profile for vm %s. "+
475+
"UEFISettings should be set when SecurityEncryptionType is defined.", vmSpec.Name)
476+
}
477+
478+
if vmSpec.SecurityProfile.Settings.ConfidentialVM.UEFISettings.VirtualizedTrustedPlatformModule != machinev1.VirtualizedTrustedPlatformModulePolicyEnabled {
479+
return nil, apierrors.InvalidMachineConfiguration("failed to generate security profile for vm %s. "+
480+
"VirtualizedTrustedPlatformModule should be enabled when SecurityEncryptionType is defined.", vmSpec.Name)
481+
}
482+
483+
if osDisk.ManagedDisk.SecurityProfile.SecurityEncryptionType == compute.SecurityEncryptionTypesDiskWithVMGuestState {
484+
if vmSpec.SecurityProfile.EncryptionAtHost != nil && *vmSpec.SecurityProfile.EncryptionAtHost {
485+
return nil, apierrors.InvalidMachineConfiguration("failed to generate security profile for vm %s. "+
486+
"EncryptionAtHost cannot be set to true when SecurityEncryptionType is set to %s.",
487+
vmSpec.Name, compute.SecurityEncryptionTypesDiskWithVMGuestState)
488+
}
489+
if vmSpec.SecurityProfile.Settings.ConfidentialVM.UEFISettings.SecureBoot != machinev1.SecureBootPolicyEnabled {
490+
return nil, apierrors.InvalidMachineConfiguration("failed to generate security profile for vm %s. "+
491+
"SecureBoot should be enabled when SecurityEncryptionType is set to %s.",
492+
vmSpec.Name, compute.SecurityEncryptionTypesDiskWithVMGuestState)
493+
}
494+
}
495+
496+
securityProfile.SecurityType = compute.SecurityTypesConfidentialVM
497+
498+
securityProfile.UefiSettings = &compute.UefiSettings{
499+
SecureBootEnabled: pointer.Bool(false),
500+
VTpmEnabled: pointer.Bool(true),
501+
}
502+
503+
if vmSpec.SecurityProfile.Settings.ConfidentialVM.UEFISettings.SecureBoot == machinev1.SecureBootPolicyEnabled {
504+
securityProfile.UefiSettings.SecureBootEnabled = pointer.Bool(true)
505+
}
506+
507+
return securityProfile, nil
508+
}
509+
510+
if vmSpec.SecurityProfile.Settings.SecurityType == machinev1.SecurityTypesTrustedLaunch && vmSpec.SecurityProfile.Settings.TrustedLaunch == nil {
511+
return nil, apierrors.InvalidMachineConfiguration("failed to generate security profile for vm %s. "+
512+
"UEFISettings should be set when SecurityType is set to %s.",
513+
vmSpec.Name, compute.SecurityTypesTrustedLaunch)
514+
}
515+
516+
if vmSpec.SecurityProfile.Settings.TrustedLaunch != nil &&
517+
(vmSpec.SecurityProfile.Settings.TrustedLaunch.UEFISettings.SecureBoot == machinev1.SecureBootPolicyEnabled ||
518+
vmSpec.SecurityProfile.Settings.TrustedLaunch.UEFISettings.VirtualizedTrustedPlatformModule == machinev1.VirtualizedTrustedPlatformModulePolicyEnabled) {
519+
520+
if vmSpec.SecurityProfile.Settings.SecurityType != machinev1.SecurityTypesTrustedLaunch {
521+
return nil, apierrors.InvalidMachineConfiguration("failed to generate security profile for vm %s. "+
522+
"SecurityType should be set to %s when UEFISettings are defined.",
523+
vmSpec.Name, compute.SecurityTypesTrustedLaunch)
524+
}
525+
526+
securityProfile.SecurityType = compute.SecurityTypesTrustedLaunch
527+
528+
securityProfile.UefiSettings = &compute.UefiSettings{
529+
SecureBootEnabled: pointer.Bool(false),
530+
VTpmEnabled: pointer.Bool(false),
531+
}
532+
533+
if vmSpec.SecurityProfile.Settings.TrustedLaunch.UEFISettings.SecureBoot == machinev1.SecureBootPolicyEnabled {
534+
securityProfile.UefiSettings.SecureBootEnabled = pointer.Bool(true)
535+
}
536+
537+
if vmSpec.SecurityProfile.Settings.TrustedLaunch.UEFISettings.VirtualizedTrustedPlatformModule == machinev1.VirtualizedTrustedPlatformModulePolicyEnabled {
538+
securityProfile.UefiSettings.VTpmEnabled = pointer.Bool(true)
539+
}
540+
}
541+
542+
return securityProfile, nil
543+
}
544+
439545
func generateDataDisks(vmSpec *Spec) ([]compute.DataDisk, error) {
440546
seenDataDiskLuns := make(map[int32]struct{})
441547
seenDataDiskNames := make(map[string]struct{})

0 commit comments

Comments
 (0)