in ec2config/validate-defaults.go [290:431]
func (cfg *Config) validateASGs() error {
n := len(cfg.ASGs)
if n == 0 {
return errors.New("empty ASGs")
}
if n > ASGsMaxLimit {
return fmt.Errorf("ASGs %d exceeds maximum number of ASGs which is %d", n, ASGsMaxLimit)
}
names, processed := make(map[string]struct{}), make(map[string]ASG)
total := int32(0)
for k, cur := range cfg.ASGs {
k = strings.ReplaceAll(k, "GetRef.Name", cfg.Name)
cur.Name = strings.ReplaceAll(cur.Name, "GetRef.Name", cfg.Name)
if cur.Name == "" {
return fmt.Errorf("ASGs[%q].Name is empty", k)
}
if k != cur.Name {
return fmt.Errorf("ASGs[%q].Name has different Name field %q", k, cur.Name)
}
_, ok := names[cur.Name]
if !ok {
names[cur.Name] = struct{}{}
} else {
return fmt.Errorf("ASGs[%q].Name %q is redundant", k, cur.Name)
}
if cur.VolumeSize == 0 {
cur.VolumeSize = DefaultNodeVolumeSize
}
if cur.RemoteAccessUserName == "" {
cur.RemoteAccessUserName = "ec2-user"
}
if cur.ImageID == "" && cur.ImageIDSSMParameter == "" {
return fmt.Errorf("%q both ImageID and ImageIDSSMParameter are empty", cur.Name)
}
// prefer "ImageIDSSMParameter"
if cur.ImageID != "" && cur.ImageIDSSMParameter != "" {
cur.ImageID = ""
}
if cur.LaunchTemplateName == "" {
cur.LaunchTemplateName = cur.Name + "-launch-template"
}
switch cur.AMIType {
case AMITypeAL2ARM64:
if cur.RemoteAccessUserName != "ec2-user" {
return fmt.Errorf("AMIType %q but unexpected RemoteAccessUserName %q", cur.AMIType, cur.RemoteAccessUserName)
}
case AMITypeBottleRocketCPU:
if cur.RemoteAccessUserName != "ec2-user" {
return fmt.Errorf("AMIType %q but unexpected RemoteAccessUserName %q", cur.AMIType, cur.RemoteAccessUserName)
}
case AMITypeAL2X8664:
if cur.RemoteAccessUserName != "ec2-user" {
return fmt.Errorf("AMIType %q but unexpected RemoteAccessUserName %q", cur.AMIType, cur.RemoteAccessUserName)
}
case AMITypeAL2X8664GPU:
if cur.RemoteAccessUserName != "ec2-user" {
return fmt.Errorf("AMIType %q but unexpected RemoteAccessUserName %q", cur.AMIType, cur.RemoteAccessUserName)
}
case AMITypeOther:
default:
return fmt.Errorf("unknown ASGs[%q].AMIType %q", k, cur.AMIType)
}
switch cur.AMIType {
case AMITypeAL2ARM64:
if cur.InstanceType == "" {
cur.InstanceType = DefaultNodeInstanceTypeCPUARM
}
case AMITypeBottleRocketCPU:
if cur.InstanceType == "" {
cur.InstanceType = DefaultNodeInstanceTypeCPU
}
case AMITypeAL2X8664:
if cur.InstanceType == "" {
cur.InstanceType = DefaultNodeInstanceTypeCPU
}
case AMITypeAL2X8664GPU:
if cur.InstanceType == "" {
cur.InstanceType = DefaultNodeInstanceTypeGPU
}
case AMITypeOther:
default:
return fmt.Errorf("unknown ASGs[%q].AMIType %q", k, cur.AMIType)
}
if cur.ASGMinSize == 0 {
return fmt.Errorf("ASGs[%q].ASGMinSize must be >0", k)
}
if cur.ASGDesiredCapacity == 0 {
return fmt.Errorf("ASGs[%q].ASGDesiredCapacity must be >0", k)
}
if cur.ASGMaxSize == 0 {
return fmt.Errorf("ASGs[%q].ASGMaxSize must be >0", k)
}
if cur.ASGMinSize > cur.ASGMaxSize {
return fmt.Errorf("ASGs[%q].ASGMinSize %d > ASGMaxSize %d", k, cur.ASGMinSize, cur.ASGMaxSize)
}
if cur.ASGDesiredCapacity > cur.ASGMaxSize {
return fmt.Errorf("ASGs[%q].ASGDesiredCapacity %d > ASGMaxSize %d", k, cur.ASGDesiredCapacity, cur.ASGMaxSize)
}
if cur.ASGMaxSize > ASGMaxLimit {
return fmt.Errorf("ASGs[%q].ASGMaxSize %d > ASGMaxLimit %d", k, cur.ASGMaxSize, ASGMaxLimit)
}
if cur.ASGDesiredCapacity > ASGMaxLimit {
return fmt.Errorf("ASGs[%q].ASGDesiredCapacity %d > ASGMaxLimit %d", k, cur.ASGDesiredCapacity, ASGMaxLimit)
}
if cur.SSM != nil {
switch cur.SSM.DocumentCreate {
case true: // need create one, or already created
if cur.SSM.DocumentName == "" {
cur.SSM.DocumentName = cur.Name + "SSMDocument"
}
cur.SSM.DocumentName = strings.ReplaceAll(cur.SSM.DocumentName, "GetRef.Name", cfg.Name)
cur.SSM.DocumentName = ssmDocNameRegex.ReplaceAllString(cur.SSM.DocumentName, "")
if cur.SSM.DocumentExecutionTimeoutSeconds == 0 {
cur.SSM.DocumentExecutionTimeoutSeconds = 3600
}
if cur.SSM.DocumentCommands == "" {
return errors.New("empty SSM.DocumentCommands")
}
case false: // use existing one, or don't run any SSM
}
}
expectedN := cur.ASGDesiredCapacity
if expectedN == 0 {
expectedN = cur.ASGMinSize
}
total += expectedN
processed[k] = cur
}
cfg.ASGs = processed
cfg.TotalNodes = total
return nil
}