@@ -11,6 +11,7 @@ import (
1111
1212 azdns "github.com/Azure/azure-sdk-for-go/profiles/2018-03-01/dns/mgmt/dns"
1313 aznetwork "github.com/Azure/azure-sdk-for-go/profiles/2018-03-01/network/mgmt/network"
14+ azenc "github.com/Azure/azure-sdk-for-go/profiles/latest/compute/mgmt/compute"
1415 "github.com/Azure/go-autorest/autorest/to"
1516 "github.com/pkg/errors"
1617 "github.com/sirupsen/logrus"
@@ -92,6 +93,60 @@ func ValidateDiskEncryptionSet(client API, ic *types.InstallConfig) field.ErrorL
9293 return allErrs
9394}
9495
96+ func validateConfidentialDiskEncryptionSet (client API , diskEncryptionSet * aztypes.DiskEncryptionSet , desFieldPath * field.Path ) error {
97+ resp , requestErr := client .GetDiskEncryptionSet (context .TODO (), diskEncryptionSet .SubscriptionID , diskEncryptionSet .ResourceGroup , diskEncryptionSet .Name )
98+ if requestErr != nil {
99+ return requestErr
100+ } else if resp == nil || resp .EncryptionSetProperties == nil || resp .EncryptionSetProperties .EncryptionType != azenc .DiskEncryptionSetTypeConfidentialVMEncryptedWithCustomerKey {
101+ return errors .Errorf ("the disk encryption set should be created with type %s" , azenc .DiskEncryptionSetTypeConfidentialVMEncryptedWithCustomerKey )
102+ }
103+ return nil
104+ }
105+
106+ // ValidateSecurityProfileDiskEncryptionSet ensures the security profile disk encryption set exists and is valid.
107+ func ValidateSecurityProfileDiskEncryptionSet (client API , ic * types.InstallConfig ) field.ErrorList {
108+ allErrs := field.ErrorList {}
109+
110+ if ic .Platform .Azure .DefaultMachinePlatform != nil &&
111+ ic .Platform .Azure .DefaultMachinePlatform .OSDisk .SecurityProfile != nil &&
112+ ic .Platform .Azure .DefaultMachinePlatform .OSDisk .SecurityProfile .DiskEncryptionSet != nil {
113+ desFieldPath := field .NewPath ("platform" ).Child ("azure" , "defaultMachinePlatform" , "osDisk" , "securityProfile" , "diskEncryptionSet" )
114+ diskEncryptionSet := ic .Platform .Azure .DefaultMachinePlatform .OSDisk .SecurityProfile .DiskEncryptionSet
115+ err := validateConfidentialDiskEncryptionSet (client , diskEncryptionSet , desFieldPath )
116+ if err != nil {
117+ allErrs = append (allErrs , field .Invalid (desFieldPath , diskEncryptionSet , err .Error ()))
118+ }
119+ }
120+
121+ if ic .ControlPlane != nil &&
122+ ic .ControlPlane .Platform .Azure != nil &&
123+ ic .ControlPlane .Platform .Azure .OSDisk .SecurityProfile != nil &&
124+ ic .ControlPlane .Platform .Azure .OSDisk .SecurityProfile .DiskEncryptionSet != nil {
125+ desFieldPath := field .NewPath ("platform" ).Child ("azure" , "osDisk" , "securityProfile" , "diskEncryptionSet" )
126+ diskEncryptionSet := ic .ControlPlane .Platform .Azure .OSDisk .SecurityProfile .DiskEncryptionSet
127+ err := validateConfidentialDiskEncryptionSet (client , diskEncryptionSet , desFieldPath )
128+ if err != nil {
129+ allErrs = append (allErrs , field .Invalid (desFieldPath , diskEncryptionSet , err .Error ()))
130+ }
131+ }
132+
133+ for idx , compute := range ic .Compute {
134+ fieldPath := field .NewPath ("compute" ).Index (idx )
135+ if compute .Platform .Azure != nil &&
136+ compute .Platform .Azure .OSDisk .SecurityProfile != nil &&
137+ compute .Platform .Azure .OSDisk .SecurityProfile .DiskEncryptionSet != nil {
138+ desFieldPath := fieldPath .Child ("platform" , "azure" , "osDisk" , "securityProfile" , "diskEncryptionSet" )
139+ diskEncryptionSet := compute .Platform .Azure .OSDisk .SecurityProfile .DiskEncryptionSet
140+ err := validateConfidentialDiskEncryptionSet (client , diskEncryptionSet , desFieldPath )
141+ if err != nil {
142+ allErrs = append (allErrs , field .Invalid (desFieldPath , diskEncryptionSet , err .Error ()))
143+ }
144+ }
145+ }
146+
147+ return allErrs
148+ }
149+
95150func validatePremiumDisk (fieldPath * field.Path , diskType string , instanceType string , capabilities map [string ]string ) field.ErrorList {
96151 fldPath := fieldPath .Child ("osDisk" , "diskType" )
97152 val , ok := capabilities ["PremiumIO" ]
@@ -158,6 +213,42 @@ func validateMininumRequirements(fieldPath *field.Path, req resourceRequirements
158213 return allErrs
159214}
160215
216+ func validateSecurityType (fieldPath * field.Path , securityType aztypes.SecurityTypes , instanceType string , capabilities map [string ]string ) field.ErrorList {
217+ allErrs := field.ErrorList {}
218+
219+ _ , hasTrustedLaunchDisabled := capabilities ["TrustedLaunchDisabled" ]
220+ confidentialComputingType , hasConfidentialComputingType := capabilities ["ConfidentialComputingType" ]
221+ isConfidentialComputingTypeSNP := confidentialComputingType == "SNP"
222+
223+ var reason string
224+ supportedSecurityType := true
225+ switch securityType {
226+ case aztypes .SecurityTypesConfidentialVM :
227+ supportedSecurityType = hasConfidentialComputingType && isConfidentialComputingTypeSNP
228+
229+ if ! hasConfidentialComputingType {
230+ reason = "no support for Confidential Computing"
231+ } else if ! isConfidentialComputingTypeSNP {
232+ reason = "no support for AMD-SEV SNP"
233+ }
234+ case aztypes .SecurityTypesTrustedLaunch :
235+ supportedSecurityType = ! (hasTrustedLaunchDisabled || hasConfidentialComputingType )
236+
237+ if hasTrustedLaunchDisabled {
238+ reason = "no support for Trusted Launch"
239+ } else if hasConfidentialComputingType {
240+ reason = "confidential VMs do not support Trusted Launch for VMs"
241+ }
242+ }
243+
244+ if ! supportedSecurityType {
245+ errMsg := fmt .Sprintf ("this security type is not supported for instance type %s, %s" , instanceType , reason )
246+ allErrs = append (allErrs , field .Invalid (fieldPath , securityType , errMsg ))
247+ }
248+
249+ return allErrs
250+ }
251+
161252func validateFamily (fieldPath * field.Path , instanceType , family string ) field.ErrorList {
162253 windowsVMFamilies := sets .NewString (
163254 "standardNVSv4Family" ,
@@ -245,7 +336,7 @@ func validateUltraSSD(client API, fieldPath *field.Path, icZones []string, regio
245336}
246337
247338// ValidateInstanceType ensures the instance type has sufficient Vcpu, Memory, and a valid family type.
248- func ValidateInstanceType (client API , fieldPath * field.Path , region , instanceType , diskType string , req resourceRequirements , ultraSSDEnabled bool , vmNetworkingType string , icZones []string , architecture types.Architecture ) field.ErrorList {
339+ func ValidateInstanceType (client API , fieldPath * field.Path , region , instanceType , diskType string , req resourceRequirements , ultraSSDEnabled bool , vmNetworkingType string , icZones []string , architecture types.Architecture , securityType aztypes. SecurityTypes ) field.ErrorList {
249340 allErrs := field.ErrorList {}
250341
251342 capabilities , err := client .GetVMCapabilities (context .TODO (), instanceType , region )
@@ -255,6 +346,7 @@ func ValidateInstanceType(client API, fieldPath *field.Path, region, instanceTyp
255346
256347 allErrs = append (allErrs , validateMininumRequirements (fieldPath .Child ("type" ), req , instanceType , capabilities )... )
257348 allErrs = append (allErrs , validateVMArchitecture (fieldPath .Child ("type" ), instanceType , architecture , capabilities )... )
349+ allErrs = append (allErrs , validateSecurityType (fieldPath .Child ("settings" , "securityType" ), securityType , instanceType , capabilities )... )
258350
259351 family , _ := client .GetVirtualMachineFamily (context .TODO (), instanceType , region )
260352 if family != "" {
@@ -280,6 +372,8 @@ func ValidateInstanceType(client API, fieldPath *field.Path, region, instanceTyp
280372func validateInstanceTypes (client API , ic * types.InstallConfig ) field.ErrorList {
281373 allErrs := field.ErrorList {}
282374
375+ var securityType aztypes.SecurityTypes
376+
283377 defaultDiskType := aztypes .DefaultDiskType
284378 defaultInstanceType := ""
285379 defaultUltraSSDCapability := "Disabled"
@@ -303,6 +397,9 @@ func validateInstanceTypes(client API, ic *types.InstallConfig) field.ErrorList
303397 if ic .Platform .Azure .DefaultMachinePlatform .Zones != nil {
304398 defaultZones = ic .Platform .Azure .DefaultMachinePlatform .Zones
305399 }
400+ if ic .Platform .Azure .DefaultMachinePlatform .Settings != nil {
401+ securityType = ic .Platform .Azure .DefaultMachinePlatform .Settings .SecurityType
402+ }
306403 }
307404
308405 if ic .ControlPlane != nil && ic .ControlPlane .Platform .Azure != nil {
@@ -314,6 +411,9 @@ func validateInstanceTypes(client API, ic *types.InstallConfig) field.ErrorList
314411 zones := ic .ControlPlane .Platform .Azure .Zones
315412 architecture := ic .ControlPlane .Architecture
316413
414+ if ic .ControlPlane .Platform .Azure .Settings != nil {
415+ securityType = ic .ControlPlane .Platform .Azure .Settings .SecurityType
416+ }
317417 if diskType == "" {
318418 diskType = defaultDiskType
319419 }
@@ -334,7 +434,7 @@ func validateInstanceTypes(client API, ic *types.InstallConfig) field.ErrorList
334434 zones = defaultZones
335435 }
336436 ultraSSDEnabled := strings .EqualFold (ultraSSDCapability , "Enabled" )
337- allErrs = append (allErrs , ValidateInstanceType (client , fieldPath , ic .Azure .Region , instanceType , diskType , controlPlaneReq , ultraSSDEnabled , vmNetworkingType , zones , architecture )... )
437+ allErrs = append (allErrs , ValidateInstanceType (client , fieldPath , ic .Azure .Region , instanceType , diskType , controlPlaneReq , ultraSSDEnabled , vmNetworkingType , zones , architecture , securityType )... )
338438 }
339439
340440 for idx , compute := range ic .Compute {
@@ -347,6 +447,9 @@ func validateInstanceTypes(client API, ic *types.InstallConfig) field.ErrorList
347447 zones := compute .Platform .Azure .Zones
348448 architecture := compute .Architecture
349449
450+ if compute .Platform .Azure .Settings != nil {
451+ securityType = compute .Platform .Azure .Settings .SecurityType
452+ }
350453 if diskType == "" {
351454 diskType = defaultDiskType
352455 }
@@ -368,7 +471,7 @@ func validateInstanceTypes(client API, ic *types.InstallConfig) field.ErrorList
368471 }
369472 ultraSSDEnabled := strings .EqualFold (ultraSSDCapability , "Enabled" )
370473 allErrs = append (allErrs , ValidateInstanceType (client , fieldPath .Child ("platform" , "azure" ),
371- ic .Azure .Region , instanceType , diskType , computeReq , ultraSSDEnabled , vmNetworkingType , zones , architecture )... )
474+ ic .Azure .Region , instanceType , diskType , computeReq , ultraSSDEnabled , vmNetworkingType , zones , architecture , securityType )... )
372475 }
373476 }
374477
@@ -387,7 +490,7 @@ func validateInstanceTypes(client API, ic *types.InstallConfig) field.ErrorList
387490 fieldPath := field .NewPath ("platform" , "azure" , "defaultMachinePlatform" )
388491 ultraSSDEnabled := strings .EqualFold (defaultUltraSSDCapability , "Enabled" )
389492 allErrs = append (allErrs , ValidateInstanceType (client , fieldPath ,
390- ic .Azure .Region , defaultInstanceType , defaultDiskType , minReq , ultraSSDEnabled , defaultVMNetworkingType , defaultZones , architecture )... )
493+ ic .Azure .Region , defaultInstanceType , defaultDiskType , minReq , ultraSSDEnabled , defaultVMNetworkingType , defaultZones , architecture , securityType )... )
391494 }
392495 return allErrs
393496}
@@ -525,6 +628,7 @@ func ValidateForProvisioning(client API, ic *types.InstallConfig) error {
525628 allErrs := field.ErrorList {}
526629 allErrs = append (allErrs , validateResourceGroup (client , field .NewPath ("platform" ).Child ("azure" ), ic .Azure )... )
527630 allErrs = append (allErrs , ValidateDiskEncryptionSet (client , ic )... )
631+ allErrs = append (allErrs , ValidateSecurityProfileDiskEncryptionSet (client , ic )... )
528632 if ic .Azure .CloudName == aztypes .StackCloud {
529633 allErrs = append (allErrs , checkAzureStackClusterOSImageSet (ic .Azure .ClusterOSImage , field .NewPath ("platform" ).Child ("azure" ))... )
530634 }
0 commit comments