Improve machine type and image validation

This commit is contained in:
Ciprian Hacman 2021-02-19 09:35:35 +02:00
parent fb1cde0c95
commit dee13cecca
4 changed files with 30 additions and 37 deletions

View File

@ -65,7 +65,7 @@ func awsValidateInstanceGroup(ig *kops.InstanceGroup, cloud awsup.AWSCloud) fiel
allErrs = append(allErrs, awsValidateAdditionalSecurityGroups(field.NewPath("spec", "additionalSecurityGroups"), ig.Spec.AdditionalSecurityGroups)...)
allErrs = append(allErrs, awsValidateInstanceTypeWithImageArch(field.NewPath(ig.GetName(), "spec", "machineType"), ig.Spec.MachineType, ig.Spec.Image, cloud)...)
allErrs = append(allErrs, awsValidateInstanceTypeAndImage(field.NewPath(ig.GetName(), "spec", "machineType"), field.NewPath(ig.GetName(), "spec", "image"), ig.Spec.MachineType, ig.Spec.Image, cloud)...)
allErrs = append(allErrs, awsValidateSpotDurationInMinute(field.NewPath(ig.GetName(), "spec", "spotDurationInMinutes"), ig)...)
@ -121,29 +121,36 @@ func awsValidateAdditionalSecurityGroups(fieldPath *field.Path, groups []string)
return allErrs
}
func awsValidateInstanceTypeWithImageArch(instanceFieldPath *field.Path, instanceType string, image string, cloud awsup.AWSCloud) field.ErrorList {
func awsValidateInstanceTypeAndImage(instanceTypeFieldPath *field.Path, imageFieldPath *field.Path, instanceType string, image string, cloud awsup.AWSCloud) field.ErrorList {
allErrs := field.ErrorList{}
if cloud != nil && instanceType != "" {
imageInfo, err := cloud.ResolveImage(image)
if err != nil {
allErrs = append(allErrs, field.Invalid(field.NewPath("spec", "image"), image, "Image specified is invalid"))
return append(allErrs, field.Invalid(imageFieldPath, image,
fmt.Sprintf("image specified is invalid: %q", image)))
}
if imageInfo != nil {
for _, typ := range strings.Split(instanceType, ",") {
machineInfo, err := cloud.DescribeInstanceType(typ)
if err != nil {
allErrs = append(allErrs, field.Invalid(instanceFieldPath, typ, "machine type specified is invalid"))
}
imageArch := fi.StringValue(imageInfo.Architecture)
if machineInfo != nil {
if invalidMachineArchitecture(imageInfo, machineInfo) {
allErrs = append(allErrs, field.Invalid(instanceFieldPath, typ, "machine type architecture does not match image architecture"))
}
machineInfo, err := cloud.DescribeInstanceType(instanceType)
if err != nil {
return append(allErrs, field.Invalid(instanceTypeFieldPath, instanceType,
fmt.Sprintf("machine type specified is invalid: %q", instanceType)))
}
found := false
if machineInfo.ProcessorInfo != nil {
for _, machineArch := range machineInfo.ProcessorInfo.SupportedArchitectures {
if imageArch == fi.StringValue(machineArch) {
found = true
}
}
}
if !found {
allErrs = append(allErrs, field.Invalid(instanceTypeFieldPath, instanceType,
fmt.Sprintf("machine type architecture does not match image architecture: %+v - %q", machineInfo.ProcessorInfo, imageArch)))
}
}
return allErrs
@ -173,8 +180,8 @@ func awsValidateMixedInstancesPolicy(path *field.Path, spec *kops.MixedInstances
var errs field.ErrorList
// @step: check the instance types are valid
for i, x := range spec.Instances {
errs = append(errs, awsValidateInstanceTypeWithImageArch(path.Child("instances").Index(i), x, ig.Spec.Image, cloud)...)
for i, instanceType := range spec.Instances {
errs = append(errs, awsValidateInstanceTypeAndImage(path.Child("instances").Index(i), path.Child("image"), instanceType, ig.Spec.Image, cloud)...)
}
if spec.OnDemandBase != nil {
@ -260,19 +267,3 @@ func awsValidateLoadBalancerSubnets(fieldPath *field.Path, spec kops.ClusterSpec
return allErrs
}
func invalidMachineArchitecture(imageInfo *ec2.Image, machineInfo *ec2.InstanceTypeInfo) bool {
imageArch := fi.StringValue(imageInfo.Architecture)
if machineInfo.ProcessorInfo == nil {
return false
}
for _, arch := range machineInfo.ProcessorInfo.SupportedArchitectures {
if imageArch == fi.StringValue(arch) {
return false
}
}
return true
}

View File

@ -173,6 +173,7 @@ func (h *IntegrationTestHarness) SetupMockAWS() *awsup.MockAWSCloud {
Name: aws.String("k8s-1.4-debian-jessie-amd64-hvm-ebs-2016-10-21"),
OwnerId: aws.String(awsup.WellKnownAccountKopeio),
RootDeviceName: aws.String("/dev/xvda"),
Architecture: aws.String("x86_64"),
})
mockEC2.Images = append(mockEC2.Images, &ec2.Image{
@ -181,6 +182,7 @@ func (h *IntegrationTestHarness) SetupMockAWS() *awsup.MockAWSCloud {
Name: aws.String("k8s-1.5-debian-jessie-amd64-hvm-ebs-2017-01-09"),
OwnerId: aws.String(awsup.WellKnownAccountKopeio),
RootDeviceName: aws.String("/dev/xvda"),
Architecture: aws.String("x86_64"),
})
mockEC2.Images = append(mockEC2.Images, &ec2.Image{
@ -189,6 +191,7 @@ func (h *IntegrationTestHarness) SetupMockAWS() *awsup.MockAWSCloud {
Name: aws.String("k8s-1.14-debian-stretch-amd64-hvm-ebs-2019-08-16"),
OwnerId: aws.String(awsup.WellKnownAccountKopeio),
RootDeviceName: aws.String("/dev/xvda"),
Architecture: aws.String("x86_64"),
})
mockEC2.CreateVpcWithId(&ec2.CreateVpcInput{

View File

@ -1,3 +1,3 @@
spec.mixedInstancesPolicy.instances=[m5.xlarge,m5.large]
spec.mixedInstancesPolicy.instances=m5.large
---
spec.mixedInstancesPolicy.instances=[m5.xlarge]
spec.mixedInstancesPolicy.instances=m5.xlarge

View File

@ -307,15 +307,14 @@ func (c *MockAWSCloud) DescribeInstanceType(instanceType string) (*ec2.InstanceT
}
}
if instanceType == "m4.large" || instanceType == "c5.large" {
switch instanceType {
case "c5.large", "m3.medium", "m4.large", "m5.large", "m5.xlarge", "t2.micro", "t2.medium", "t3.medium", "t3.large":
info.ProcessorInfo = &ec2.ProcessorInfo{
SupportedArchitectures: []*string{
aws.String("x86_64"),
},
}
}
if instanceType == "a1.large" {
case "a1.large":
info.ProcessorInfo = &ec2.ProcessorInfo{
SupportedArchitectures: []*string{
aws.String("arm64"),