github.com/openshift/installer@v1.4.17/pkg/asset/quota/aws/aws.go (about)

     1  package aws
     2  
     3  import (
     4  	"fmt"
     5  	"regexp"
     6  	"sort"
     7  	"strings"
     8  
     9  	"github.com/sirupsen/logrus"
    10  	"k8s.io/apimachinery/pkg/util/sets"
    11  
    12  	machineapi "github.com/openshift/api/machine/v1beta1"
    13  	"github.com/openshift/installer/pkg/quota"
    14  	"github.com/openshift/installer/pkg/types"
    15  )
    16  
    17  // Constraints returns a list of quota constraints based on the InstallConfig.
    18  // These constraints can be used to check if there is enough quota for creating a cluster
    19  // for the isntall config.
    20  func Constraints(config *types.InstallConfig, controlPlanes []machineapi.Machine, computes []machineapi.MachineSet, instanceTypes map[string]InstanceTypeInfo) []quota.Constraint {
    21  	ctrplConfigs := make([]*machineapi.AWSMachineProviderConfig, len(controlPlanes))
    22  	for i, m := range controlPlanes {
    23  		ctrplConfigs[i] = m.Spec.ProviderSpec.Value.Object.(*machineapi.AWSMachineProviderConfig)
    24  	}
    25  	computeReplicas := make([]int64, len(computes))
    26  	computeConfigs := make([]*machineapi.AWSMachineProviderConfig, len(computes))
    27  	for i, w := range computes {
    28  		computeReplicas[i] = int64(*w.Spec.Replicas)
    29  		computeConfigs[i] = w.Spec.Template.Spec.ProviderSpec.Value.Object.(*machineapi.AWSMachineProviderConfig)
    30  	}
    31  
    32  	var ret []quota.Constraint
    33  	for _, gen := range []constraintGenerator{
    34  		network(config, append(ctrplConfigs, computeConfigs...)),
    35  		controlPlane(config, ctrplConfigs, instanceTypes),
    36  		compute(config, computeReplicas, computeConfigs, instanceTypes),
    37  		others,
    38  	} {
    39  		ret = append(ret, gen()...)
    40  	}
    41  	return aggregate(ret)
    42  }
    43  
    44  func aggregate(quotas []quota.Constraint) []quota.Constraint {
    45  	sort.SliceStable(quotas, func(i, j int) bool {
    46  		return quotas[i].Name < quotas[j].Name
    47  	})
    48  
    49  	i := 0
    50  	for j := 1; j < len(quotas); j++ {
    51  		if quotas[i].Name == quotas[j].Name && quotas[i].Region == quotas[j].Region {
    52  			quotas[i].Count += quotas[j].Count
    53  		} else {
    54  			i++
    55  			if i != j {
    56  				quotas[i] = quotas[j]
    57  			}
    58  		}
    59  	}
    60  	return quotas[:i+1]
    61  }
    62  
    63  // constraintGenerator generates a list of constraints.
    64  type constraintGenerator func() []quota.Constraint
    65  
    66  func network(config *types.InstallConfig, machines []*machineapi.AWSMachineProviderConfig) func() []quota.Constraint {
    67  	return func() []quota.Constraint {
    68  		zones := sets.NewString()
    69  		for _, m := range machines {
    70  			zones.Insert(m.Placement.AvailabilityZone)
    71  		}
    72  
    73  		var ret []quota.Constraint
    74  		ret = append(ret, quota.Constraint{
    75  			Name:   "vpc/L-E79EC296", // 2 sg
    76  			Region: config.Platform.AWS.Region,
    77  			Count:  2,
    78  		})
    79  		if len(config.Platform.AWS.Subnets) == 0 {
    80  			ret = append(ret, []quota.Constraint{{
    81  				Name:   "vpc/L-F678F1CE", // 1 vpc
    82  				Region: config.Platform.AWS.Region,
    83  				Count:  1,
    84  			}, {
    85  				Name:   "vpc/L-A4707A72", // 1 ig
    86  				Region: config.Platform.AWS.Region,
    87  				Count:  1,
    88  			}, {
    89  				Name:   "vpc/L-FE5A380F", // 1 nat gw per AZ
    90  				Region: config.Platform.AWS.Region,
    91  				Count:  1,
    92  			}}...)
    93  
    94  			ret = append(ret, quota.Constraint{
    95  				Name:   "ec2/L-0263D0A3", // 1 eip per AZ
    96  				Region: config.Platform.AWS.Region,
    97  				Count:  int64(zones.Len()),
    98  			})
    99  		}
   100  
   101  		return ret
   102  	}
   103  }
   104  
   105  func controlPlane(config *types.InstallConfig, machines []*machineapi.AWSMachineProviderConfig, instanceTypes map[string]InstanceTypeInfo) func() []quota.Constraint {
   106  	return func() []quota.Constraint {
   107  		var ret []quota.Constraint
   108  		for _, m := range machines {
   109  			q := machineTypeToQuota(m.InstanceType, instanceTypes)
   110  			q.Region = config.Platform.AWS.Region
   111  			ret = append(ret, q)
   112  		}
   113  		return ret
   114  	}
   115  }
   116  
   117  func compute(config *types.InstallConfig, replicas []int64, machines []*machineapi.AWSMachineProviderConfig, instanceTypes map[string]InstanceTypeInfo) func() []quota.Constraint {
   118  	return func() []quota.Constraint {
   119  		var ret []quota.Constraint
   120  		for idx, m := range machines {
   121  			q := machineTypeToQuota(m.InstanceType, instanceTypes)
   122  			q.Count = q.Count * replicas[idx]
   123  			q.Region = config.Platform.AWS.Region
   124  			ret = append(ret, q)
   125  		}
   126  		return ret
   127  	}
   128  }
   129  
   130  func others() []quota.Constraint {
   131  	return []quota.Constraint{}
   132  }
   133  
   134  func machineTypeToQuota(t string, instanceTypes map[string]InstanceTypeInfo) quota.Constraint {
   135  	info, ok := instanceTypes[t]
   136  	warnMessage := fmt.Sprintf("The instance class is unknown for the instance type %q. The vCPU quota check will be skipped.", t)
   137  	if !ok {
   138  		logrus.Warnf(warnMessage)
   139  		return quota.Constraint{Name: "ec2/L-7295265B", Count: 0}
   140  	}
   141  	r := regexp.MustCompile(`^([A-Za-z]+)[0-9]`)
   142  	match := r.FindStringSubmatch(strings.ToLower(t))
   143  	if match == nil {
   144  		logrus.Warnf(warnMessage)
   145  		return quota.Constraint{Name: "ec2/L-7295265B", Count: 0}
   146  	}
   147  	switch match[1] {
   148  	case "a", "c", "d", "h", "i", "is", "im", "m", "r", "t", "z":
   149  		return quota.Constraint{Name: "ec2/L-1216C47A", Count: info.vCPU}
   150  	case "g", "vt":
   151  		return quota.Constraint{Name: "ec2/L-DB2E81BA", Count: info.vCPU}
   152  	case "x":
   153  		return quota.Constraint{Name: "ec2/L-7295265B", Count: info.vCPU}
   154  	default:
   155  		logrus.Warnf(warnMessage)
   156  		return quota.Constraint{Name: "ec2/L-7295265B", Count: 0}
   157  	}
   158  }