Skip to content

Commit

Permalink
Fix validation for Azure TDX
Browse files Browse the repository at this point in the history
Signed-off-by: Daniel Weiße <[email protected]>
  • Loading branch information
daniel-weisse committed Jan 23, 2024
1 parent a346e67 commit afcfdff
Show file tree
Hide file tree
Showing 4 changed files with 76 additions and 54 deletions.
2 changes: 2 additions & 0 deletions cli/internal/cmd/configgenerate.go
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,8 @@ func createConfigWithAttestationVariant(provider cloudprovider.Provider, rawProv
return nil, fmt.Errorf("provider %s does not support attestation variant %s", provider, attestationVariant)
}
conf.SetAttestation(attestationVariant)

conf.SetCSPNodeGroupDefaults(provider)
return conf, nil
}

Expand Down
14 changes: 10 additions & 4 deletions internal/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -569,7 +569,7 @@ func (c *Config) RemoveProviderExcept(provider cloudprovider.Provider) {
default:
c.Provider = currentProviderConfigs
}
c.setCSPNodeGroupDefaults(provider)
c.SetCSPNodeGroupDefaults(provider)
}

// SetAttestation sets the attestation config for the given attestation variant and removes all other attestation configs.
Expand Down Expand Up @@ -918,22 +918,28 @@ func (c *Config) WithOpenStackProviderDefaults(openStackProvider string) *Config
return c
}

func (c *Config) setCSPNodeGroupDefaults(csp cloudprovider.Provider) {
// SetCSPNodeGroupDefaults sets the default values for the node groups based on the configured CSP.
func (c *Config) SetCSPNodeGroupDefaults(csp cloudprovider.Provider) {
var instanceType, stateDiskType, zone string
switch csp {
case cloudprovider.AWS:
instanceType = "m6a.xlarge"
stateDiskType = "gp3"
zone = c.Provider.AWS.Zone
case cloudprovider.Azure:
instanceType = "Standard_DC4as_v5"
// Check attestation variant, and use different default instance type if we have TDX
if c.GetAttestationConfig().GetVariant().Equal(variant.AzureTDX{}) {
instanceType = "Standard_DC4as_v5"
} else {
instanceType = "Standard_DC4es_v5"
}
stateDiskType = "Premium_LRS"
case cloudprovider.GCP:
instanceType = "n2d-standard-4"
stateDiskType = "pd-ssd"
zone = c.Provider.GCP.Zone
case cloudprovider.QEMU, cloudprovider.OpenStack:
// empty. There are now defaults for this CSP
// empty. There are no defaults for this CSP
}

for groupName, group := range c.NodeGroups {
Expand Down
53 changes: 28 additions & 25 deletions internal/config/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -686,135 +686,135 @@ func TestConfig_IsReleaseImage(t *testing.T) {

func TestValidInstanceTypeForProvider(t *testing.T) {
testCases := map[string]struct {
provider cloudprovider.Provider
variant variant.Variant
instanceTypes []string
nonCVMsAllowed bool
expectedResult bool
}{
"empty all": {
provider: cloudprovider.Unknown,
variant: variant.Dummy{},
instanceTypes: []string{},
expectedResult: false,
},
"empty aws": {
provider: cloudprovider.AWS,
variant: variant.AWSSEVSNP{},
instanceTypes: []string{},
expectedResult: false,
},
"empty azure only CVMs": {
provider: cloudprovider.Azure,
variant: variant.AzureSEVSNP{},
instanceTypes: []string{},
expectedResult: false,
},
"empty azure with non-CVMs": {
provider: cloudprovider.Azure,
variant: variant.AzureTrustedLaunch{},
instanceTypes: []string{},
nonCVMsAllowed: true,
expectedResult: false,
},
"empty gcp": {
provider: cloudprovider.GCP,
variant: variant.GCPSEVES{},
instanceTypes: []string{},
expectedResult: false,
},
"azure only CVMs (SNP)": {
provider: cloudprovider.Azure,
variant: variant.AzureSEVSNP{},
instanceTypes: instancetypes.AzureSNPInstanceTypes,
expectedResult: true,
},
"azure only CVMs (TDX)": {
provider: cloudprovider.Azure,
variant: variant.AzureTDX{},
instanceTypes: instancetypes.AzureTDXInstanceTypes,
expectedResult: true,
},
"azure CVMs but CVMs disabled": {
provider: cloudprovider.Azure,
variant: variant.AzureSEVSNP{},
instanceTypes: instancetypes.AzureSNPInstanceTypes,
nonCVMsAllowed: true,
expectedResult: false,
},
"azure trusted launch VMs with CVMs enabled": {
provider: cloudprovider.Azure,
variant: variant.AzureTrustedLaunch{},
instanceTypes: instancetypes.AzureTrustedLaunchInstanceTypes,
expectedResult: false,
},
"azure trusted launch VMs with CVMs disabled": {
provider: cloudprovider.Azure,
variant: variant.AzureTrustedLaunch{},
instanceTypes: instancetypes.AzureTrustedLaunchInstanceTypes,
nonCVMsAllowed: true,
expectedResult: true,
},
"gcp": {
provider: cloudprovider.GCP,
variant: variant.GCPSEVES{},
instanceTypes: instancetypes.GCPInstanceTypes,
expectedResult: true,
},
"put gcp when azure is set": {
provider: cloudprovider.Azure,
variant: variant.AzureSEVSNP{},
instanceTypes: instancetypes.GCPInstanceTypes,
expectedResult: false,
},
"put gcp when azure is set with CVMs disabled": {
provider: cloudprovider.Azure,
variant: variant.AzureSEVSNP{},
instanceTypes: instancetypes.GCPInstanceTypes,
nonCVMsAllowed: true,
expectedResult: false,
},
"put azure when gcp is set": {
provider: cloudprovider.GCP,
variant: variant.GCPSEVES{},
instanceTypes: instancetypes.AzureSNPInstanceTypes,
expectedResult: false,
},
"put azure when gcp is set with CVMs disabled": {
provider: cloudprovider.GCP,
variant: variant.GCPSEVES{},
instanceTypes: instancetypes.AzureTrustedLaunchInstanceTypes,
nonCVMsAllowed: true,
expectedResult: false,
},
// Testing every possible instance type for AWS is not feasible, so we just test a few based on known supported / unsupported families
// Also serves as a test for checkIfInstanceInValidAWSFamilys
"aws two valid instances": {
provider: cloudprovider.AWS,
variant: variant.AWSSEVSNP{},
instanceTypes: []string{"c5.xlarge", "c5a.2xlarge", "c5a.16xlarge", "u-12tb1.112xlarge"},
expectedResult: true,
nonCVMsAllowed: true,
},
"aws one valid instance one with too little vCPUs": {
provider: cloudprovider.AWS,
variant: variant.AWSSEVSNP{},
instanceTypes: []string{"c5.medium"},
expectedResult: false,
nonCVMsAllowed: true,
},
"aws graviton sub-family unsupported": {
provider: cloudprovider.AWS,
variant: variant.AWSSEVSNP{},
instanceTypes: []string{"m6g.xlarge", "r6g.2xlarge", "x2gd.xlarge", "g5g.8xlarge"},
expectedResult: false,
nonCVMsAllowed: true,
},
"aws combined two valid instances as one string": {
provider: cloudprovider.AWS,
variant: variant.AWSSEVSNP{},
instanceTypes: []string{"c5.xlarge, c5a.2xlarge"},
expectedResult: false,
nonCVMsAllowed: true,
},
"aws only CVMs": {
provider: cloudprovider.AWS,
variant: variant.AWSSEVSNP{},
instanceTypes: []string{"c6a.xlarge", "m6a.xlarge", "r6a.xlarge"},
expectedResult: true,
},
"aws CVMs but CVMs disabled": {
provider: cloudprovider.AWS,
variant: variant.AWSSEVSNP{},
instanceTypes: []string{"m6a.xlarge", "c6a.xlarge", "r6a.xlarge"},
nonCVMsAllowed: true,
expectedResult: true,
},
"aws nitroTPM VMs with CVMs enabled": {
provider: cloudprovider.AWS,
variant: variant.AWSSEVSNP{},
instanceTypes: []string{"c5.xlarge", "c5a.2xlarge", "c5a.16xlarge", "u-12tb1.112xlarge"},
expectedResult: false,
},
"aws nitroTPM VMs with CVMs disabled": {
provider: cloudprovider.AWS,
variant: variant.AWSSEVSNP{},
instanceTypes: []string{"c5.xlarge", "c5a.2xlarge", "c5a.16xlarge", "u-12tb1.112xlarge"},
nonCVMsAllowed: true,
expectedResult: true,
Expand All @@ -824,7 +824,10 @@ func TestValidInstanceTypeForProvider(t *testing.T) {
t.Run(name, func(t *testing.T) {
assert := assert.New(t)
for _, instanceType := range tc.instanceTypes {
assert.Equal(tc.expectedResult, validInstanceTypeForProvider(instanceType, tc.nonCVMsAllowed, tc.provider), instanceType)
assert.Equal(
tc.expectedResult, validInstanceTypeForProvider(instanceType, tc.nonCVMsAllowed, tc.variant),
instanceType,
)
}
})
}
Expand Down
61 changes: 36 additions & 25 deletions internal/config/validation.go
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,9 @@ func validateAttestation(sl validator.StructLevel) {
if attestation.AzureSEVSNP != nil {
attestationCount++
}
if attestation.AzureTDX != nil {
attestationCount++
}
if attestation.AzureTrustedLaunch != nil {
attestationCount++
}
Expand Down Expand Up @@ -244,7 +247,7 @@ func translateNoAttestationError(ut ut.Translator, fe validator.FieldError) stri
}

func registerNoAttestationError(ut ut.Translator) error {
return ut.Add("no_attestation", "{0}: No attestation has been defined (requires either awsSEVSNP, awsNitroTPM, azureSEVSNP, azureTrustedLaunch, gcpSEVES, or qemuVTPM)", true)
return ut.Add("no_attestation", "{0}: No attestation has been defined (requires either awsSEVSNP, awsNitroTPM, azureSEVSNP, azureTDX, azureTrustedLaunch, gcpSEVES, or qemuVTPM)", true)
}

func translateNoDefaultControlPlaneGroupError(ut ut.Translator, fe validator.FieldError) string {
Expand Down Expand Up @@ -352,6 +355,9 @@ func (c *Config) translateMoreThanOneAttestationError(ut ut.Translator, fe valid
if c.Attestation.AzureSEVSNP != nil {
definedAttestations = append(definedAttestations, "AzureSEVSNP")
}
if c.Attestation.AzureTDX != nil {
definedAttestations = append(definedAttestations, "AzureTDX")
}
if c.Attestation.AzureTrustedLaunch != nil {
definedAttestations = append(definedAttestations, "AzureTrustedLaunch")
}
Expand Down Expand Up @@ -508,42 +514,47 @@ func (c *Config) translateMoreThanOneProviderError(ut ut.Translator, fe validato
return t
}

func validInstanceTypeForProvider(insType string, acceptNonCVM bool, provider cloudprovider.Provider) bool {
switch provider {
case cloudprovider.AWS:
func validInstanceTypeForProvider(insType string, acceptNonCVM bool, attestation variant.Variant) bool {
switch attestation {
case variant.AWSSEVSNP{}, variant.AWSNitroTPM{}:
return isSupportedAWSInstanceType(insType, acceptNonCVM)
case cloudprovider.Azure:
case variant.AzureSEVSNP{}:
if acceptNonCVM {
for _, instanceType := range instancetypes.AzureTrustedLaunchInstanceTypes {
if insType == instanceType {
return true
}
return false
}
for _, instanceType := range instancetypes.AzureSNPInstanceTypes {
if insType == instanceType {
return true
}
} else {
for _, instanceType := range instancetypes.AzureTDXInstanceTypes {
if insType == instanceType {
return true
}
}
case variant.AzureTDX{}:
if acceptNonCVM {
return false
}
for _, instanceType := range instancetypes.AzureTDXInstanceTypes {
if insType == instanceType {
return true
}
for _, instanceType := range instancetypes.AzureSNPInstanceTypes {
if insType == instanceType {
return true
}
}
case variant.AzureTrustedLaunch{}:
if !acceptNonCVM {
return false
}
for _, instanceType := range instancetypes.AzureTrustedLaunchInstanceTypes {
if insType == instanceType {
return true
}
}
return false
case cloudprovider.GCP:
case variant.GCPSEVES{}:
for _, instanceType := range instancetypes.GCPInstanceTypes {
if insType == instanceType {
return true
}
}
return false
case cloudprovider.OpenStack, cloudprovider.QEMU:
case variant.QEMUVTPM{}, variant.QEMUTDX{}:
return true
default:
return false
}
return false
}

// isSupportedAWSInstanceType checks if an AWS instance type passed as user input is in one of the supported instance types.
Expand Down Expand Up @@ -790,7 +801,7 @@ func (c *Config) validateInstanceType(fl validator.FieldLevel) bool {
acceptNonCVM = true
}

return validInstanceTypeForProvider(fl.Field().String(), acceptNonCVM, c.GetProvider())
return validInstanceTypeForProvider(fl.Field().String(), acceptNonCVM, c.GetAttestationConfig().GetVariant())
}

func (c *Config) validateStateDiskTypeField(fl validator.FieldLevel) bool {
Expand Down

0 comments on commit afcfdff

Please sign in to comment.