Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

config: only allow confidential instances on stackit #3463

Merged
merged 2 commits into from
Oct 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 62 additions & 1 deletion internal/config/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -688,107 +688,168 @@ func TestValidInstanceTypeForProvider(t *testing.T) {
testCases := map[string]struct {
variant variant.Variant
instanceTypes []string
providerConfig ProviderConfig
expectedResult bool
}{
"empty all": {
variant: variant.Dummy{},
instanceTypes: []string{},
expectedResult: false,
providerConfig: ProviderConfig{},
},
"empty aws": {
variant: variant.AWSSEVSNP{},
instanceTypes: []string{},
expectedResult: false,
providerConfig: ProviderConfig{},
},
"empty azure only CVMs": {
variant: variant.AzureSEVSNP{},
instanceTypes: []string{},
expectedResult: false,
providerConfig: ProviderConfig{},
},
"empty azure with non-CVMs": {
variant: variant.AzureTrustedLaunch{},
instanceTypes: []string{},
expectedResult: false,
providerConfig: ProviderConfig{},
},
"empty gcp": {
variant: variant.GCPSEVES{},
instanceTypes: []string{},
expectedResult: false,
providerConfig: ProviderConfig{},
},
"azure only CVMs (SNP)": {
variant: variant.AzureSEVSNP{},
instanceTypes: instancetypes.AzureSNPInstanceTypes,
expectedResult: true,
providerConfig: ProviderConfig{},
},
"azure only CVMs (TDX)": {
variant: variant.AzureTDX{},
instanceTypes: instancetypes.AzureTDXInstanceTypes,
expectedResult: true,
providerConfig: ProviderConfig{},
},
"azure trusted launch VMs": {
variant: variant.AzureTrustedLaunch{},
instanceTypes: instancetypes.AzureTrustedLaunchInstanceTypes,
expectedResult: true,
providerConfig: ProviderConfig{},
},
"gcp": {
variant: variant.GCPSEVES{},
instanceTypes: instancetypes.GCPInstanceTypes,
expectedResult: true,
providerConfig: ProviderConfig{},
},
"gcp sev-snp": {
variant: variant.GCPSEVSNP{},
instanceTypes: instancetypes.GCPInstanceTypes,
expectedResult: true,
providerConfig: ProviderConfig{},
},
"put gcp when azure is set": {
variant: variant.AzureSEVSNP{},
instanceTypes: instancetypes.GCPInstanceTypes,
expectedResult: false,
providerConfig: ProviderConfig{},
},
"put azure when gcp is set": {
variant: variant.GCPSEVES{},
instanceTypes: instancetypes.AzureSNPInstanceTypes,
expectedResult: false,
providerConfig: ProviderConfig{},
},
// 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": {
variant: variant.AWSSEVSNP{},
instanceTypes: []string{"c5.xlarge", "c5a.2xlarge", "c5a.16xlarge", "u-12tb1.112xlarge"},
expectedResult: false, // False because 2 two of the instances are not valid
providerConfig: ProviderConfig{},
},
"aws one valid instance one with too little vCPUs": {
variant: variant.AWSSEVSNP{},
instanceTypes: []string{"c5.medium"},
expectedResult: false,
providerConfig: ProviderConfig{},
},
"aws graviton sub-family unsupported": {
variant: variant.AWSSEVSNP{},
instanceTypes: []string{"m6g.xlarge", "r6g.2xlarge", "x2gd.xlarge", "g5g.8xlarge"},
expectedResult: false,
providerConfig: ProviderConfig{},
},
"aws combined two valid instances as one string": {
variant: variant.AWSSEVSNP{},
instanceTypes: []string{"c5.xlarge, c5a.2xlarge"},
expectedResult: false,
providerConfig: ProviderConfig{},
},
"aws only CVMs": {
variant: variant.AWSSEVSNP{},
instanceTypes: []string{"c6a.xlarge", "m6a.xlarge", "r6a.xlarge"},
expectedResult: true,
providerConfig: ProviderConfig{},
},
"aws nitroTPM VMs": {
variant: variant.AWSNitroTPM{},
instanceTypes: []string{"c5.xlarge", "c5a.2xlarge", "c5a.16xlarge", "u-12tb1.112xlarge"},
expectedResult: true,
providerConfig: ProviderConfig{},
},
"stackit valid flavors": {
variant: variant.QEMUVTPM{},
instanceTypes: []string{
"m1a.2cd",
"m1a.4cd",
"m1a.8cd",
"m1a.16cd",
"m1a.30cd",
},
expectedResult: true,
providerConfig: ProviderConfig{OpenStack: &OpenStackConfig{Cloud: "stackit"}},
},
"stackit not valid flavors": {
variant: variant.QEMUVTPM{},
instanceTypes: []string{
// removed the c which indicates a confidential flavor
"m1a.2d",
"m1a.4d",
"m1a.8d",
"m1a.16d",
"m1a.30d",
},
expectedResult: false,
providerConfig: ProviderConfig{OpenStack: &OpenStackConfig{Cloud: "stackit"}},
},
"openstack cloud named test": {
variant: variant.QEMUVTPM{},
instanceTypes: []string{
"foo.bar",
"foo.bar1",
},
expectedResult: true,
providerConfig: ProviderConfig{OpenStack: &OpenStackConfig{Cloud: "test"}},
},
"Qemutdx valid instance type": {
variant: variant.QEMUTDX{},
instanceTypes: []string{
"foo.bar",
},
expectedResult: true,
providerConfig: ProviderConfig{QEMU: &QEMUConfig{}},
},
}
for name, tc := range testCases {
t.Run(name, func(t *testing.T) {
assert := assert.New(t)
for _, instanceType := range tc.instanceTypes {
assert.Equal(
tc.expectedResult, validInstanceTypeForProvider(instanceType, tc.variant),
tc.expectedResult, validInstanceTypeForProvider(instanceType, tc.variant, tc.providerConfig),
instanceType,
)
}
Expand Down
15 changes: 13 additions & 2 deletions internal/config/validation.go
Original file line number Diff line number Diff line change
Expand Up @@ -520,7 +520,7 @@ func (c *Config) translateMoreThanOneProviderError(ut ut.Translator, fe validato
return t
}

func validInstanceTypeForProvider(insType string, attestation variant.Variant) bool {
func validInstanceTypeForProvider(insType string, attestation variant.Variant, provider ProviderConfig) bool {
switch attestation {
case variant.AWSSEVSNP{}, variant.AWSNitroTPM{}:
return isSupportedAWSInstanceType(insType, attestation.Equal(variant.AWSNitroTPM{}))
Expand Down Expand Up @@ -549,6 +549,17 @@ func validInstanceTypeForProvider(insType string, attestation variant.Variant) b
}
}
case variant.QEMUVTPM{}, variant.QEMUTDX{}:
// only allow confidential instances on stackit cloud using QEMU vTPM
if provider.OpenStack != nil {
if cloud := provider.OpenStack.Cloud; strings.ToLower(cloud) == "stackit" {
for _, instanceType := range instancetypes.STACKITInstanceTypes {
if insType == instanceType {
return true
}
}
return false
}
}
return true
}
return false
Expand Down Expand Up @@ -789,7 +800,7 @@ func (c *Config) validateNodeGroupZoneField(fl validator.FieldLevel) bool {
}

func (c *Config) validateInstanceType(fl validator.FieldLevel) bool {
return validInstanceTypeForProvider(fl.Field().String(), c.GetAttestationConfig().GetVariant())
return validInstanceTypeForProvider(fl.Field().String(), c.GetAttestationConfig().GetVariant(), c.Provider)
}

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