diff --git a/Makefile b/Makefile index 9c40b373924..2158c66b622 100644 --- a/Makefile +++ b/Makefile @@ -192,10 +192,11 @@ generate: go generate -x ./... $(MAKE) format -# Generate descriptors for supported ENI configurations. +# Generate limit file go code +# Generate eni-max-pods.txt file for EKS AMI generate-limits: GOOS= generate-limits: - go run pkg/awsutils/gen_vpc_ip_limits.go + go run scripts/gen_vpc_ip_limits.go # Fetch the CNI plugins plugins: FETCH_VERSION=0.8.6 diff --git a/misc/eni-max-pods.txt b/misc/eni-max-pods.txt new file mode 100644 index 00000000000..9f39ad0ed96 --- /dev/null +++ b/misc/eni-max-pods.txt @@ -0,0 +1,365 @@ +# Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"). You may +# not use this file except in compliance with the License. A copy of the +# License is located at +# +# http://aws.amazon.com/apache2.0/ +# +# or in the "license" file accompanying this file. This file is distributed +# on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either +# express or implied. See the License for the specific language governing +# permissions and limitations under the License. +# +# This file was generated at 2020-08-04T15:58:40-07:00 +# +# Mapping is calculated from AWS EC2 API using the following formula: +# * First IP on each ENI is not used for pods +# * 2 additional host-networking pods (AWS ENI and kube-proxy) are accounted for +# +# # of ENI * (# of IPv4 per ENI - 1) + 2 +# +# https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-eni.html#AvailableIpPerENI +# +a1.2xlarge 58 +a1.4xlarge 234 +a1.large 29 +a1.medium 8 +a1.metal 234 +a1.xlarge 58 +c1.medium 12 +c1.xlarge 58 +c3.2xlarge 58 +c3.4xlarge 234 +c3.8xlarge 234 +c3.large 29 +c3.xlarge 58 +c4.2xlarge 58 +c4.4xlarge 234 +c4.8xlarge 234 +c4.large 29 +c4.xlarge 58 +c5.12xlarge 234 +c5.18xlarge 737 +c5.24xlarge 737 +c5.2xlarge 58 +c5.4xlarge 234 +c5.9xlarge 234 +c5.large 29 +c5.metal 737 +c5.xlarge 58 +c5a.12xlarge 234 +c5a.16xlarge 737 +c5a.24xlarge 737 +c5a.2xlarge 58 +c5a.4xlarge 234 +c5a.8xlarge 234 +c5a.large 29 +c5a.metal 737 +c5a.xlarge 58 +c5ad.12xlarge 234 +c5ad.16xlarge 737 +c5ad.24xlarge 737 +c5ad.2xlarge 58 +c5ad.4xlarge 234 +c5ad.8xlarge 234 +c5ad.large 29 +c5ad.metal 737 +c5ad.xlarge 58 +c5d.12xlarge 234 +c5d.18xlarge 737 +c5d.24xlarge 737 +c5d.2xlarge 58 +c5d.4xlarge 234 +c5d.9xlarge 234 +c5d.large 29 +c5d.metal 737 +c5d.xlarge 58 +c5n.18xlarge 737 +c5n.2xlarge 58 +c5n.4xlarge 234 +c5n.9xlarge 234 +c5n.large 29 +c5n.metal 737 +c5n.xlarge 58 +c6g.12xlarge 234 +c6g.16xlarge 737 +c6g.2xlarge 58 +c6g.4xlarge 234 +c6g.8xlarge 234 +c6g.large 29 +c6g.medium 8 +c6g.metal 737 +c6g.xlarge 58 +c6gd.12xlarge 234 +c6gd.16xlarge 737 +c6gd.2xlarge 58 +c6gd.4xlarge 234 +c6gd.8xlarge 234 +c6gd.large 29 +c6gd.medium 8 +c6gd.metal 737 +c6gd.xlarge 58 +cc2.8xlarge 234 +cr1.8xlarge 234 +d2.2xlarge 58 +d2.4xlarge 234 +d2.8xlarge 234 +d2.xlarge 58 +f1.16xlarge 394 +f1.2xlarge 58 +f1.4xlarge 234 +g2.2xlarge 58 +g2.8xlarge 234 +g3.16xlarge 737 +g3.4xlarge 234 +g3.8xlarge 234 +g3s.xlarge 58 +g4dn.12xlarge 234 +g4dn.16xlarge 58 +g4dn.2xlarge 29 +g4dn.4xlarge 29 +g4dn.8xlarge 58 +g4dn.metal 737 +g4dn.xlarge 29 +h1.16xlarge 737 +h1.2xlarge 58 +h1.4xlarge 234 +h1.8xlarge 234 +hs1.8xlarge 234 +i2.2xlarge 58 +i2.4xlarge 234 +i2.8xlarge 234 +i2.xlarge 58 +i3.16xlarge 737 +i3.2xlarge 58 +i3.4xlarge 234 +i3.8xlarge 234 +i3.large 29 +i3.metal 737 +i3.xlarge 58 +i3en.12xlarge 234 +i3en.24xlarge 737 +i3en.2xlarge 58 +i3en.3xlarge 58 +i3en.6xlarge 234 +i3en.large 29 +i3en.metal 737 +i3en.xlarge 58 +inf1.24xlarge 437 +inf1.2xlarge 38 +inf1.6xlarge 234 +inf1.xlarge 38 +m1.large 29 +m1.medium 12 +m1.small 8 +m1.xlarge 58 +m2.2xlarge 118 +m2.4xlarge 234 +m2.xlarge 58 +m3.2xlarge 118 +m3.large 29 +m3.medium 12 +m3.xlarge 58 +m4.10xlarge 234 +m4.16xlarge 234 +m4.2xlarge 58 +m4.4xlarge 234 +m4.large 20 +m4.xlarge 58 +m5.12xlarge 234 +m5.16xlarge 737 +m5.24xlarge 737 +m5.2xlarge 58 +m5.4xlarge 234 +m5.8xlarge 234 +m5.large 29 +m5.metal 737 +m5.xlarge 58 +m5a.12xlarge 234 +m5a.16xlarge 737 +m5a.24xlarge 737 +m5a.2xlarge 58 +m5a.4xlarge 234 +m5a.8xlarge 234 +m5a.large 29 +m5a.xlarge 58 +m5ad.12xlarge 234 +m5ad.16xlarge 737 +m5ad.24xlarge 737 +m5ad.2xlarge 58 +m5ad.4xlarge 234 +m5ad.8xlarge 234 +m5ad.large 29 +m5ad.xlarge 58 +m5d.12xlarge 234 +m5d.16xlarge 737 +m5d.24xlarge 737 +m5d.2xlarge 58 +m5d.4xlarge 234 +m5d.8xlarge 234 +m5d.large 29 +m5d.metal 737 +m5d.xlarge 58 +m5dn.12xlarge 234 +m5dn.16xlarge 737 +m5dn.24xlarge 737 +m5dn.2xlarge 58 +m5dn.4xlarge 234 +m5dn.8xlarge 234 +m5dn.large 29 +m5dn.xlarge 58 +m5n.12xlarge 234 +m5n.16xlarge 737 +m5n.24xlarge 737 +m5n.2xlarge 58 +m5n.4xlarge 234 +m5n.8xlarge 234 +m5n.large 29 +m5n.xlarge 58 +m6g.12xlarge 234 +m6g.16xlarge 737 +m6g.2xlarge 58 +m6g.4xlarge 234 +m6g.8xlarge 234 +m6g.large 29 +m6g.medium 8 +m6g.metal 737 +m6g.xlarge 58 +m6gd.12xlarge 234 +m6gd.16xlarge 737 +m6gd.2xlarge 58 +m6gd.4xlarge 234 +m6gd.8xlarge 234 +m6gd.large 29 +m6gd.medium 8 +m6gd.metal 737 +m6gd.xlarge 58 +p2.16xlarge 234 +p2.8xlarge 234 +p2.xlarge 58 +p3.16xlarge 234 +p3.2xlarge 58 +p3.8xlarge 234 +p3dn.24xlarge 737 +r3.2xlarge 58 +r3.4xlarge 234 +r3.8xlarge 234 +r3.large 29 +r3.xlarge 58 +r4.16xlarge 737 +r4.2xlarge 58 +r4.4xlarge 234 +r4.8xlarge 234 +r4.large 29 +r4.xlarge 58 +r5.12xlarge 234 +r5.16xlarge 737 +r5.24xlarge 737 +r5.2xlarge 58 +r5.4xlarge 234 +r5.8xlarge 234 +r5.large 29 +r5.metal 737 +r5.xlarge 58 +r5a.12xlarge 234 +r5a.16xlarge 737 +r5a.24xlarge 737 +r5a.2xlarge 58 +r5a.4xlarge 234 +r5a.8xlarge 234 +r5a.large 29 +r5a.xlarge 58 +r5ad.12xlarge 234 +r5ad.16xlarge 737 +r5ad.24xlarge 737 +r5ad.2xlarge 58 +r5ad.4xlarge 234 +r5ad.8xlarge 234 +r5ad.large 29 +r5ad.xlarge 58 +r5d.12xlarge 234 +r5d.16xlarge 737 +r5d.24xlarge 737 +r5d.2xlarge 58 +r5d.4xlarge 234 +r5d.8xlarge 234 +r5d.large 29 +r5d.metal 737 +r5d.xlarge 58 +r5dn.12xlarge 234 +r5dn.16xlarge 737 +r5dn.24xlarge 737 +r5dn.2xlarge 58 +r5dn.4xlarge 234 +r5dn.8xlarge 234 +r5dn.large 29 +r5dn.xlarge 58 +r5n.12xlarge 234 +r5n.16xlarge 737 +r5n.24xlarge 737 +r5n.2xlarge 58 +r5n.4xlarge 234 +r5n.8xlarge 234 +r5n.large 29 +r5n.xlarge 58 +r6g.12xlarge 234 +r6g.16xlarge 737 +r6g.2xlarge 58 +r6g.4xlarge 234 +r6g.8xlarge 234 +r6g.large 29 +r6g.medium 8 +r6g.metal 737 +r6g.xlarge 58 +r6gd.12xlarge 234 +r6gd.16xlarge 737 +r6gd.2xlarge 58 +r6gd.4xlarge 234 +r6gd.8xlarge 234 +r6gd.large 29 +r6gd.medium 8 +r6gd.metal 737 +r6gd.xlarge 58 +t1.micro 4 +t2.2xlarge 44 +t2.large 35 +t2.medium 17 +t2.micro 4 +t2.nano 4 +t2.small 11 +t2.xlarge 44 +t3.2xlarge 58 +t3.large 35 +t3.medium 17 +t3.micro 4 +t3.nano 4 +t3.small 11 +t3.xlarge 58 +t3a.2xlarge 58 +t3a.large 35 +t3a.medium 17 +t3a.micro 4 +t3a.nano 4 +t3a.small 8 +t3a.xlarge 58 +u-12tb1.metal 147 +u-18tb1.metal 737 +u-24tb1.metal 737 +u-6tb1.metal 147 +u-9tb1.metal 147 +x1.16xlarge 234 +x1.32xlarge 234 +x1e.16xlarge 234 +x1e.2xlarge 58 +x1e.32xlarge 234 +x1e.4xlarge 58 +x1e.8xlarge 58 +x1e.xlarge 29 +z1d.12xlarge 737 +z1d.2xlarge 58 +z1d.3xlarge 234 +z1d.6xlarge 234 +z1d.large 29 +z1d.metal 737 +z1d.xlarge 58 diff --git a/pkg/awsutils/awsutils.go b/pkg/awsutils/awsutils.go index 00b46451902..78bbf9e76a2 100644 --- a/pkg/awsutils/awsutils.go +++ b/pkg/awsutils/awsutils.go @@ -146,8 +146,8 @@ type APIs interface { // GetPrimaryENI returns the primary ENI GetPrimaryENI() string - // GetENIipLimit return IP address limit per ENI based on EC2 instance type - GetENIipLimit() (int, error) + // GetENIIPv4Limit return IP address limit per ENI based on EC2 instance type + GetENIIPv4Limit() (int, error) // GetENILimit returns the number of ENIs that can be attached to an instance GetENILimit() (int, error) @@ -193,6 +193,12 @@ type ENIMetadata struct { IPv4Addresses []*ec2.NetworkInterfacePrivateIpAddress } +// InstanceTypeLimits keeps track of limits for an instance type +type InstanceTypeLimits struct { + ENILimit int + IPv4Limit int +} + func (eni ENIMetadata) PrimaryIPv4Address() string { for _, addr := range eni.IPv4Addresses { if aws.BoolValue(addr.Primary) { @@ -1144,19 +1150,19 @@ func (cache *EC2InstanceMetadataCache) AllocIPAddress(eniID string) error { return nil } -// GetENIipLimit return IP address limit per ENI based on EC2 instance type -func (cache *EC2InstanceMetadataCache) GetENIipLimit() (int, error) { - ipLimit, ok := InstanceIPsAvailable[cache.instanceType] +// GetENIIPv4Limit return IP address limit per ENI based on EC2 instance type +func (cache *EC2InstanceMetadataCache) GetENIIPv4Limit() (int, error) { + eniLimits, ok := InstanceNetworkingLimits[cache.instanceType] if !ok { log.Errorf("Failed to get ENI IP limit due to unknown instance type %s", cache.instanceType) return 0, errors.New(UnknownInstanceType) } - return ipLimit - 1, nil + return eniLimits.IPv4Limit - 1, nil } // GetENILimit returns the number of ENIs can be attached to an instance func (cache *EC2InstanceMetadataCache) GetENILimit() (int, error) { - eniLimit, ok := InstanceENIsAvailable[cache.instanceType] + eniLimits, ok := InstanceNetworkingLimits[cache.instanceType] if !ok { // Fetch from EC2 API describeInstanceTypesInput := &ec2.DescribeInstanceTypesInput{InstanceTypes: []*string{aws.String(cache.instanceType)}} @@ -1168,23 +1174,26 @@ func (cache *EC2InstanceMetadataCache) GetENILimit() (int, error) { info := output.InstanceTypes[0] // Ignore any missing values instanceType := aws.StringValue(info.InstanceType) - eniLimit = int(aws.Int64Value(info.NetworkInfo.MaximumNetworkInterfaces)) - ipLimit := int(aws.Int64Value(info.NetworkInfo.Ipv4AddressesPerInterface)) - if instanceType != "" && eniLimit > 0 && ipLimit > 0 { - InstanceENIsAvailable[instanceType] = eniLimit - InstanceIPsAvailable[instanceType] = ipLimit + eniLimit := int(aws.Int64Value(info.NetworkInfo.MaximumNetworkInterfaces)) + ipv4Limit := int(aws.Int64Value(info.NetworkInfo.Ipv4AddressesPerInterface)) + if instanceType != "" && eniLimit > 0 && ipv4Limit > 0 { + eniLimits = InstanceTypeLimits{ + ENILimit: eniLimit, + IPv4Limit: ipv4Limit, + } + InstanceNetworkingLimits[instanceType] = eniLimits } else { return 0, errors.New(fmt.Sprintf("%s: %s", UnknownInstanceType, cache.instanceType)) } } - return eniLimit, nil + return int(eniLimits.ENILimit), nil } // AllocIPAddresses allocates numIPs of IP address on an ENI func (cache *EC2InstanceMetadataCache) AllocIPAddresses(eniID string, numIPs int) error { var needIPs = numIPs - ipLimit, err := cache.GetENIipLimit() + ipLimit, err := cache.GetENIIPv4Limit() if err != nil { awsUtilsErrInc("UnknownInstanceType", err) return err diff --git a/pkg/awsutils/awsutils_test.go b/pkg/awsutils/awsutils_test.go index 29b3519d85e..d40cabc4149 100644 --- a/pkg/awsutils/awsutils_test.go +++ b/pkg/awsutils/awsutils_test.go @@ -655,7 +655,9 @@ func TestDescribeInstanceTypes(t *testing.T) { value, err := ins.GetENILimit() assert.NoError(t, err) assert.Equal(t, 9, value) - assert.Equal(t, 99, InstanceIPsAvailable[ins.instanceType]) + pv4Limit, err := ins.GetENIIPv4Limit() + assert.NoError(t, err) + assert.Equal(t, 98, pv4Limit) } func TestAllocIPAddress(t *testing.T) { diff --git a/pkg/awsutils/gen_vpc_ip_limits.go b/pkg/awsutils/gen_vpc_ip_limits.go deleted file mode 100644 index 18cf74b9d1a..00000000000 --- a/pkg/awsutils/gen_vpc_ip_limits.go +++ /dev/null @@ -1,178 +0,0 @@ -// Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"). You may -// not use this file except in compliance with the License. A copy of the -// License is located at -// -// http://aws.amazon.com/apache2.0/ -// -// or in the "license" file accompanying this file. This file is distributed -// on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either -// express or implied. See the License for the specific language governing -// permissions and limitations under the License. - -// +build ignore - -// This program generates vpc_ip_resource_limit.go -// It can be invoked by running `go run` -package main - -import ( - "os" - "sort" - "text/template" - "time" - - "github.com/aws/amazon-vpc-cni-k8s/pkg/utils/logger" - - "github.com/aws/aws-sdk-go/aws" - - "github.com/aws/aws-sdk-go/aws/session" - "github.com/aws/aws-sdk-go/service/ec2" -) - -const ipLimitFileName = "pkg/awsutils/vpc_ip_resource_limit.go" - -type ENILimit struct { - InstanceType string - ENILimit int64 - IPLimit int64 -} - -// Helper function to call the EC2 DescribeInstanceTypes API and generate the IP limit file. -func main() { - log := logger.DefaultLogger() - // Get session - sess := session.Must(session.NewSessionWithOptions(session.Options{ - SharedConfigState: session.SharedConfigEnable, - })) - _, err := sess.Config.Credentials.Get() - if err != nil { - log.Fatalf("Failed to get session credentials: %v", err) - } - svc := ec2.New(sess) - describeInstanceTypesInput := &ec2.DescribeInstanceTypesInput{} - - eniLimitMap := make(map[string]ENILimit) - for { - output, err := svc.DescribeInstanceTypes(describeInstanceTypesInput) - if err != nil { - log.Fatalf("Failed to call EC2 DescibeInstanceTypes: %v", err) - } - // We just want the type name, ENI and IP limits - for _, info := range output.InstanceTypes { - // Ignore any missing values - instanceType := aws.StringValue(info.InstanceType) - eniLimit := aws.Int64Value(info.NetworkInfo.MaximumNetworkInterfaces) - ipLimit := aws.Int64Value(info.NetworkInfo.Ipv4AddressesPerInterface) - if instanceType != "" && eniLimit > 0 && ipLimit > 0 { - eniLimitMap[instanceType] = newENILimit(instanceType, eniLimit, ipLimit) - } - } - // Paginate to the next request - if output.NextToken == nil { - break - } - describeInstanceTypesInput = &ec2.DescribeInstanceTypesInput{ - NextToken: output.NextToken, - } - } - - // Override faulty values and add missing instance types - eniLimitMap = addManualLimits(eniLimitMap) - - // Sort the keys - instanceTypes := make([]string, 0) - for k := range eniLimitMap { - instanceTypes = append(instanceTypes, k) - } - sort.Strings(instanceTypes) - eniLimits := make([]ENILimit, 0) - for _, it := range instanceTypes { - eniLimits = append(eniLimits, eniLimitMap[it]) - } - - // Generate the file - f, err := os.Create(ipLimitFileName) - if err != nil { - log.Fatalf("Failed to create file: %v, ", err) - } - limitsTemplate.Execute(f, struct { - Timestamp string - ENILimits []ENILimit - }{ - Timestamp: time.Now().Format(time.RFC3339), - ENILimits: eniLimits, - }) -} - -// addManualLimits has the list of faulty or missing instance types -func addManualLimits(limitMap map[string]ENILimit) map[string]ENILimit { - manuallyAddedLimits := []ENILimit{ - {"cr1.8xlarge", 8, 30}, - {"hs1.8xlarge", 8, 30}, - {"u-12tb1.metal", 5, 30}, - {"u-18tb1.metal", 15, 50}, - {"u-24tb1.metal", 15, 50}, - {"u-6tb1.metal", 5, 30}, - {"u-9tb1.metal", 5, 30}, - {"c5a.metal", 15, 50}, - {"c5ad.12xlarge", 8, 30}, - {"c5ad.16xlarge", 15, 50}, - {"c5ad.24xlarge", 15, 50}, - {"c5ad.2xlarge", 4, 15}, - {"c5ad.4xlarge", 8, 30}, - {"c5ad.8xlarge", 8, 30}, - {"c5ad.large", 3, 10}, - {"c5ad.metal", 15, 50}, - {"c5ad.xlarge", 4, 15}, - } - for _, eniLimit := range manuallyAddedLimits { - limitMap[eniLimit.InstanceType] = newENILimit(eniLimit.InstanceType, eniLimit.ENILimit, eniLimit.IPLimit) - } - return limitMap -} - -// Helper to quote the type in order to print the map correctly -func newENILimit(instanceType string, eniLimit int64, ipLimit int64) ENILimit { - return ENILimit{ - InstanceType: "\"" + instanceType + "\":", - ENILimit: eniLimit, - IPLimit: ipLimit, - } -} - -var limitsTemplate = template.Must(template.New("").Parse(`// Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"). You may -// not use this file except in compliance with the License. A copy of the -// License is located at -// -// http://aws.amazon.com/apache2.0/ -// -// or in the "license" file accompanying this file. This file is distributed -// on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either -// express or implied. See the License for the specific language governing -// permissions and limitations under the License. - -// Code generated by go generate; DO NOT EDIT. -// This file was generated at {{ .Timestamp }} - -package awsutils - -// InstanceENIsAvailable contains a mapping of instance types to the number of ENIs available which is described at -// https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-eni.html#AvailableIpPerENI -var InstanceENIsAvailable = map[string]int{ -{{- range $it := .ENILimits}} - {{ printf "%-17s%d" $it.InstanceType $it.ENILimit }}, -{{- end }} -} - -// InstanceIPsAvailable contains a mapping of instance types to the number of IPs per ENI -// https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-eni.html#AvailableIpPerENI -var InstanceIPsAvailable = map[string]int{ -{{- range $it := .ENILimits}} - {{ printf "%-17s%d" $it.InstanceType $it.IPLimit }}, -{{- end }} -} -`)) diff --git a/pkg/awsutils/mocks/awsutils_mocks.go b/pkg/awsutils/mocks/awsutils_mocks.go index 7a1764ab61d..eb5780d9430 100644 --- a/pkg/awsutils/mocks/awsutils_mocks.go +++ b/pkg/awsutils/mocks/awsutils_mocks.go @@ -166,19 +166,19 @@ func (mr *MockAPIsMockRecorder) GetENILimit() *gomock.Call { return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetENILimit", reflect.TypeOf((*MockAPIs)(nil).GetENILimit)) } -// GetENIipLimit mocks base method -func (m *MockAPIs) GetENIipLimit() (int, error) { +// GetENIIPv4Limit mocks base method +func (m *MockAPIs) GetENIIPv4Limit() (int, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetENIipLimit") + ret := m.ctrl.Call(m, "GetENIIPv4Limit") ret0, _ := ret[0].(int) ret1, _ := ret[1].(error) return ret0, ret1 } -// GetENIipLimit indicates an expected call of GetENIipLimit +// GetENIIPv4Limit indicates an expected call of GetENIIPv4Limit func (mr *MockAPIsMockRecorder) GetENIipLimit() *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetENIipLimit", reflect.TypeOf((*MockAPIs)(nil).GetENIipLimit)) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetENIIPv4Limit", reflect.TypeOf((*MockAPIs)(nil).GetENIIPv4Limit)) } // GetIPv4sFromEC2 mocks base method diff --git a/pkg/awsutils/vpc_ip_resource_limit.go b/pkg/awsutils/vpc_ip_resource_limit.go index b3fd809fc82..02d69f25000 100644 --- a/pkg/awsutils/vpc_ip_resource_limit.go +++ b/pkg/awsutils/vpc_ip_resource_limit.go @@ -12,646 +12,353 @@ // permissions and limitations under the License. // Code generated by go generate; DO NOT EDIT. -// This file was generated at 2020-07-13T11:26:46-07:00 +// This file was generated at 2020-08-04T15:58:40-07:00 package awsutils -// InstanceENIsAvailable contains a mapping of instance types to the number of ENIs available which is described at +// InstanceNetworkingLimits contains a mapping from instance type to networking limits for the type. Documentation found at // https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-eni.html#AvailableIpPerENI -var InstanceENIsAvailable = map[string]int{ - "a1.2xlarge": 4, - "a1.4xlarge": 8, - "a1.large": 3, - "a1.medium": 2, - "a1.metal": 8, - "a1.xlarge": 4, - "c1.medium": 2, - "c1.xlarge": 4, - "c3.2xlarge": 4, - "c3.4xlarge": 8, - "c3.8xlarge": 8, - "c3.large": 3, - "c3.xlarge": 4, - "c4.2xlarge": 4, - "c4.4xlarge": 8, - "c4.8xlarge": 8, - "c4.large": 3, - "c4.xlarge": 4, - "c5.12xlarge": 8, - "c5.18xlarge": 15, - "c5.24xlarge": 15, - "c5.2xlarge": 4, - "c5.4xlarge": 8, - "c5.9xlarge": 8, - "c5.large": 3, - "c5.metal": 15, - "c5.xlarge": 4, - "c5a.12xlarge": 8, - "c5a.16xlarge": 15, - "c5a.24xlarge": 15, - "c5a.2xlarge": 4, - "c5a.4xlarge": 8, - "c5a.8xlarge": 8, - "c5a.large": 3, - "c5a.metal": 15, - "c5a.xlarge": 4, - "c5ad.12xlarge": 8, - "c5ad.16xlarge": 15, - "c5ad.24xlarge": 15, - "c5ad.2xlarge": 4, - "c5ad.4xlarge": 8, - "c5ad.8xlarge": 8, - "c5ad.large": 3, - "c5ad.metal": 15, - "c5ad.xlarge": 4, - "c5d.12xlarge": 8, - "c5d.18xlarge": 15, - "c5d.24xlarge": 15, - "c5d.2xlarge": 4, - "c5d.4xlarge": 8, - "c5d.9xlarge": 8, - "c5d.large": 3, - "c5d.metal": 15, - "c5d.xlarge": 4, - "c5n.18xlarge": 15, - "c5n.2xlarge": 4, - "c5n.4xlarge": 8, - "c5n.9xlarge": 8, - "c5n.large": 3, - "c5n.metal": 15, - "c5n.xlarge": 4, - "c6g.12xlarge": 8, - "c6g.16xlarge": 15, - "c6g.2xlarge": 4, - "c6g.4xlarge": 8, - "c6g.8xlarge": 8, - "c6g.large": 3, - "c6g.medium": 2, - "c6g.metal": 15, - "c6g.xlarge": 4, - "cc2.8xlarge": 8, - "cr1.8xlarge": 8, - "d2.2xlarge": 4, - "d2.4xlarge": 8, - "d2.8xlarge": 8, - "d2.xlarge": 4, - "f1.16xlarge": 8, - "f1.2xlarge": 4, - "f1.4xlarge": 8, - "g2.2xlarge": 4, - "g2.8xlarge": 8, - "g3.16xlarge": 15, - "g3.4xlarge": 8, - "g3.8xlarge": 8, - "g3s.xlarge": 4, - "g4dn.12xlarge": 8, - "g4dn.16xlarge": 4, - "g4dn.2xlarge": 3, - "g4dn.4xlarge": 3, - "g4dn.8xlarge": 4, - "g4dn.metal": 15, - "g4dn.xlarge": 3, - "h1.16xlarge": 15, - "h1.2xlarge": 4, - "h1.4xlarge": 8, - "h1.8xlarge": 8, - "hs1.8xlarge": 8, - "i2.2xlarge": 4, - "i2.4xlarge": 8, - "i2.8xlarge": 8, - "i2.xlarge": 4, - "i3.16xlarge": 15, - "i3.2xlarge": 4, - "i3.4xlarge": 8, - "i3.8xlarge": 8, - "i3.large": 3, - "i3.metal": 15, - "i3.xlarge": 4, - "i3en.12xlarge": 8, - "i3en.24xlarge": 15, - "i3en.2xlarge": 4, - "i3en.3xlarge": 4, - "i3en.6xlarge": 8, - "i3en.large": 3, - "i3en.metal": 15, - "i3en.xlarge": 4, - "inf1.24xlarge": 15, - "inf1.2xlarge": 4, - "inf1.6xlarge": 8, - "inf1.xlarge": 4, - "m1.large": 3, - "m1.medium": 2, - "m1.small": 2, - "m1.xlarge": 4, - "m2.2xlarge": 4, - "m2.4xlarge": 8, - "m2.xlarge": 4, - "m3.2xlarge": 4, - "m3.large": 3, - "m3.medium": 2, - "m3.xlarge": 4, - "m4.10xlarge": 8, - "m4.16xlarge": 8, - "m4.2xlarge": 4, - "m4.4xlarge": 8, - "m4.large": 2, - "m4.xlarge": 4, - "m5.12xlarge": 8, - "m5.16xlarge": 15, - "m5.24xlarge": 15, - "m5.2xlarge": 4, - "m5.4xlarge": 8, - "m5.8xlarge": 8, - "m5.large": 3, - "m5.metal": 15, - "m5.xlarge": 4, - "m5a.12xlarge": 8, - "m5a.16xlarge": 15, - "m5a.24xlarge": 15, - "m5a.2xlarge": 4, - "m5a.4xlarge": 8, - "m5a.8xlarge": 8, - "m5a.large": 3, - "m5a.xlarge": 4, - "m5ad.12xlarge": 8, - "m5ad.16xlarge": 15, - "m5ad.24xlarge": 15, - "m5ad.2xlarge": 4, - "m5ad.4xlarge": 8, - "m5ad.8xlarge": 8, - "m5ad.large": 3, - "m5ad.xlarge": 4, - "m5d.12xlarge": 8, - "m5d.16xlarge": 15, - "m5d.24xlarge": 15, - "m5d.2xlarge": 4, - "m5d.4xlarge": 8, - "m5d.8xlarge": 8, - "m5d.large": 3, - "m5d.metal": 15, - "m5d.xlarge": 4, - "m5dn.12xlarge": 8, - "m5dn.16xlarge": 15, - "m5dn.24xlarge": 15, - "m5dn.2xlarge": 4, - "m5dn.4xlarge": 8, - "m5dn.8xlarge": 8, - "m5dn.large": 3, - "m5dn.xlarge": 4, - "m5n.12xlarge": 8, - "m5n.16xlarge": 15, - "m5n.24xlarge": 15, - "m5n.2xlarge": 4, - "m5n.4xlarge": 8, - "m5n.8xlarge": 8, - "m5n.large": 3, - "m5n.xlarge": 4, - "m6g.12xlarge": 8, - "m6g.16xlarge": 15, - "m6g.2xlarge": 4, - "m6g.4xlarge": 8, - "m6g.8xlarge": 8, - "m6g.large": 3, - "m6g.medium": 2, - "m6g.metal": 15, - "m6g.xlarge": 4, - "p2.16xlarge": 8, - "p2.8xlarge": 8, - "p2.xlarge": 4, - "p3.16xlarge": 8, - "p3.2xlarge": 4, - "p3.8xlarge": 8, - "p3dn.24xlarge": 15, - "r3.2xlarge": 4, - "r3.4xlarge": 8, - "r3.8xlarge": 8, - "r3.large": 3, - "r3.xlarge": 4, - "r4.16xlarge": 15, - "r4.2xlarge": 4, - "r4.4xlarge": 8, - "r4.8xlarge": 8, - "r4.large": 3, - "r4.xlarge": 4, - "r5.12xlarge": 8, - "r5.16xlarge": 15, - "r5.24xlarge": 15, - "r5.2xlarge": 4, - "r5.4xlarge": 8, - "r5.8xlarge": 8, - "r5.large": 3, - "r5.metal": 15, - "r5.xlarge": 4, - "r5a.12xlarge": 8, - "r5a.16xlarge": 15, - "r5a.24xlarge": 15, - "r5a.2xlarge": 4, - "r5a.4xlarge": 8, - "r5a.8xlarge": 8, - "r5a.large": 3, - "r5a.xlarge": 4, - "r5ad.12xlarge": 8, - "r5ad.16xlarge": 15, - "r5ad.24xlarge": 15, - "r5ad.2xlarge": 4, - "r5ad.4xlarge": 8, - "r5ad.8xlarge": 8, - "r5ad.large": 3, - "r5ad.xlarge": 4, - "r5d.12xlarge": 8, - "r5d.16xlarge": 15, - "r5d.24xlarge": 15, - "r5d.2xlarge": 4, - "r5d.4xlarge": 8, - "r5d.8xlarge": 8, - "r5d.large": 3, - "r5d.metal": 15, - "r5d.xlarge": 4, - "r5dn.12xlarge": 8, - "r5dn.16xlarge": 15, - "r5dn.24xlarge": 15, - "r5dn.2xlarge": 4, - "r5dn.4xlarge": 8, - "r5dn.8xlarge": 8, - "r5dn.large": 3, - "r5dn.xlarge": 4, - "r5n.12xlarge": 8, - "r5n.16xlarge": 15, - "r5n.24xlarge": 15, - "r5n.2xlarge": 4, - "r5n.4xlarge": 8, - "r5n.8xlarge": 8, - "r5n.large": 3, - "r5n.xlarge": 4, - "r6g.12xlarge": 8, - "r6g.16xlarge": 15, - "r6g.2xlarge": 4, - "r6g.4xlarge": 8, - "r6g.8xlarge": 8, - "r6g.large": 3, - "r6g.medium": 2, - "r6g.metal": 15, - "r6g.xlarge": 4, - "t1.micro": 2, - "t2.2xlarge": 3, - "t2.large": 3, - "t2.medium": 3, - "t2.micro": 2, - "t2.nano": 2, - "t2.small": 3, - "t2.xlarge": 3, - "t3.2xlarge": 4, - "t3.large": 3, - "t3.medium": 3, - "t3.micro": 2, - "t3.nano": 2, - "t3.small": 3, - "t3.xlarge": 4, - "t3a.2xlarge": 4, - "t3a.large": 3, - "t3a.medium": 3, - "t3a.micro": 2, - "t3a.nano": 2, - "t3a.small": 2, - "t3a.xlarge": 4, - "u-12tb1.metal": 5, - "u-18tb1.metal": 15, - "u-24tb1.metal": 15, - "u-6tb1.metal": 5, - "u-9tb1.metal": 5, - "x1.16xlarge": 8, - "x1.32xlarge": 8, - "x1e.16xlarge": 8, - "x1e.2xlarge": 4, - "x1e.32xlarge": 8, - "x1e.4xlarge": 4, - "x1e.8xlarge": 4, - "x1e.xlarge": 3, - "z1d.12xlarge": 15, - "z1d.2xlarge": 4, - "z1d.3xlarge": 8, - "z1d.6xlarge": 8, - "z1d.large": 3, - "z1d.metal": 15, - "z1d.xlarge": 4, -} - -// InstanceIPsAvailable contains a mapping of instance types to the number of IPs per ENI -// https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-eni.html#AvailableIpPerENI -var InstanceIPsAvailable = map[string]int{ - "a1.2xlarge": 15, - "a1.4xlarge": 30, - "a1.large": 10, - "a1.medium": 4, - "a1.metal": 30, - "a1.xlarge": 15, - "c1.medium": 6, - "c1.xlarge": 15, - "c3.2xlarge": 15, - "c3.4xlarge": 30, - "c3.8xlarge": 30, - "c3.large": 10, - "c3.xlarge": 15, - "c4.2xlarge": 15, - "c4.4xlarge": 30, - "c4.8xlarge": 30, - "c4.large": 10, - "c4.xlarge": 15, - "c5.12xlarge": 30, - "c5.18xlarge": 50, - "c5.24xlarge": 50, - "c5.2xlarge": 15, - "c5.4xlarge": 30, - "c5.9xlarge": 30, - "c5.large": 10, - "c5.metal": 50, - "c5.xlarge": 15, - "c5a.12xlarge": 30, - "c5a.16xlarge": 50, - "c5a.24xlarge": 50, - "c5a.2xlarge": 15, - "c5a.4xlarge": 30, - "c5a.8xlarge": 30, - "c5a.large": 10, - "c5a.metal": 50, - "c5a.xlarge": 15, - "c5ad.12xlarge": 30, - "c5ad.16xlarge": 50, - "c5ad.24xlarge": 50, - "c5ad.2xlarge": 15, - "c5ad.4xlarge": 30, - "c5ad.8xlarge": 30, - "c5ad.large": 10, - "c5ad.metal": 50, - "c5ad.xlarge": 15, - "c5d.12xlarge": 30, - "c5d.18xlarge": 50, - "c5d.24xlarge": 50, - "c5d.2xlarge": 15, - "c5d.4xlarge": 30, - "c5d.9xlarge": 30, - "c5d.large": 10, - "c5d.metal": 50, - "c5d.xlarge": 15, - "c5n.18xlarge": 50, - "c5n.2xlarge": 15, - "c5n.4xlarge": 30, - "c5n.9xlarge": 30, - "c5n.large": 10, - "c5n.metal": 50, - "c5n.xlarge": 15, - "c6g.12xlarge": 30, - "c6g.16xlarge": 50, - "c6g.2xlarge": 15, - "c6g.4xlarge": 30, - "c6g.8xlarge": 30, - "c6g.large": 10, - "c6g.medium": 4, - "c6g.metal": 50, - "c6g.xlarge": 15, - "cc2.8xlarge": 30, - "cr1.8xlarge": 30, - "d2.2xlarge": 15, - "d2.4xlarge": 30, - "d2.8xlarge": 30, - "d2.xlarge": 15, - "f1.16xlarge": 50, - "f1.2xlarge": 15, - "f1.4xlarge": 30, - "g2.2xlarge": 15, - "g2.8xlarge": 30, - "g3.16xlarge": 50, - "g3.4xlarge": 30, - "g3.8xlarge": 30, - "g3s.xlarge": 15, - "g4dn.12xlarge": 30, - "g4dn.16xlarge": 15, - "g4dn.2xlarge": 10, - "g4dn.4xlarge": 10, - "g4dn.8xlarge": 15, - "g4dn.metal": 50, - "g4dn.xlarge": 10, - "h1.16xlarge": 50, - "h1.2xlarge": 15, - "h1.4xlarge": 30, - "h1.8xlarge": 30, - "hs1.8xlarge": 30, - "i2.2xlarge": 15, - "i2.4xlarge": 30, - "i2.8xlarge": 30, - "i2.xlarge": 15, - "i3.16xlarge": 50, - "i3.2xlarge": 15, - "i3.4xlarge": 30, - "i3.8xlarge": 30, - "i3.large": 10, - "i3.metal": 50, - "i3.xlarge": 15, - "i3en.12xlarge": 30, - "i3en.24xlarge": 50, - "i3en.2xlarge": 15, - "i3en.3xlarge": 15, - "i3en.6xlarge": 30, - "i3en.large": 10, - "i3en.metal": 50, - "i3en.xlarge": 15, - "inf1.24xlarge": 30, - "inf1.2xlarge": 10, - "inf1.6xlarge": 30, - "inf1.xlarge": 10, - "m1.large": 10, - "m1.medium": 6, - "m1.small": 4, - "m1.xlarge": 15, - "m2.2xlarge": 30, - "m2.4xlarge": 30, - "m2.xlarge": 15, - "m3.2xlarge": 30, - "m3.large": 10, - "m3.medium": 6, - "m3.xlarge": 15, - "m4.10xlarge": 30, - "m4.16xlarge": 30, - "m4.2xlarge": 15, - "m4.4xlarge": 30, - "m4.large": 10, - "m4.xlarge": 15, - "m5.12xlarge": 30, - "m5.16xlarge": 50, - "m5.24xlarge": 50, - "m5.2xlarge": 15, - "m5.4xlarge": 30, - "m5.8xlarge": 30, - "m5.large": 10, - "m5.metal": 50, - "m5.xlarge": 15, - "m5a.12xlarge": 30, - "m5a.16xlarge": 50, - "m5a.24xlarge": 50, - "m5a.2xlarge": 15, - "m5a.4xlarge": 30, - "m5a.8xlarge": 30, - "m5a.large": 10, - "m5a.xlarge": 15, - "m5ad.12xlarge": 30, - "m5ad.16xlarge": 50, - "m5ad.24xlarge": 50, - "m5ad.2xlarge": 15, - "m5ad.4xlarge": 30, - "m5ad.8xlarge": 30, - "m5ad.large": 10, - "m5ad.xlarge": 15, - "m5d.12xlarge": 30, - "m5d.16xlarge": 50, - "m5d.24xlarge": 50, - "m5d.2xlarge": 15, - "m5d.4xlarge": 30, - "m5d.8xlarge": 30, - "m5d.large": 10, - "m5d.metal": 50, - "m5d.xlarge": 15, - "m5dn.12xlarge": 30, - "m5dn.16xlarge": 50, - "m5dn.24xlarge": 50, - "m5dn.2xlarge": 15, - "m5dn.4xlarge": 30, - "m5dn.8xlarge": 30, - "m5dn.large": 10, - "m5dn.xlarge": 15, - "m5n.12xlarge": 30, - "m5n.16xlarge": 50, - "m5n.24xlarge": 50, - "m5n.2xlarge": 15, - "m5n.4xlarge": 30, - "m5n.8xlarge": 30, - "m5n.large": 10, - "m5n.xlarge": 15, - "m6g.12xlarge": 30, - "m6g.16xlarge": 50, - "m6g.2xlarge": 15, - "m6g.4xlarge": 30, - "m6g.8xlarge": 30, - "m6g.large": 10, - "m6g.medium": 4, - "m6g.metal": 50, - "m6g.xlarge": 15, - "p2.16xlarge": 30, - "p2.8xlarge": 30, - "p2.xlarge": 15, - "p3.16xlarge": 30, - "p3.2xlarge": 15, - "p3.8xlarge": 30, - "p3dn.24xlarge": 50, - "r3.2xlarge": 15, - "r3.4xlarge": 30, - "r3.8xlarge": 30, - "r3.large": 10, - "r3.xlarge": 15, - "r4.16xlarge": 50, - "r4.2xlarge": 15, - "r4.4xlarge": 30, - "r4.8xlarge": 30, - "r4.large": 10, - "r4.xlarge": 15, - "r5.12xlarge": 30, - "r5.16xlarge": 50, - "r5.24xlarge": 50, - "r5.2xlarge": 15, - "r5.4xlarge": 30, - "r5.8xlarge": 30, - "r5.large": 10, - "r5.metal": 50, - "r5.xlarge": 15, - "r5a.12xlarge": 30, - "r5a.16xlarge": 50, - "r5a.24xlarge": 50, - "r5a.2xlarge": 15, - "r5a.4xlarge": 30, - "r5a.8xlarge": 30, - "r5a.large": 10, - "r5a.xlarge": 15, - "r5ad.12xlarge": 30, - "r5ad.16xlarge": 50, - "r5ad.24xlarge": 50, - "r5ad.2xlarge": 15, - "r5ad.4xlarge": 30, - "r5ad.8xlarge": 30, - "r5ad.large": 10, - "r5ad.xlarge": 15, - "r5d.12xlarge": 30, - "r5d.16xlarge": 50, - "r5d.24xlarge": 50, - "r5d.2xlarge": 15, - "r5d.4xlarge": 30, - "r5d.8xlarge": 30, - "r5d.large": 10, - "r5d.metal": 50, - "r5d.xlarge": 15, - "r5dn.12xlarge": 30, - "r5dn.16xlarge": 50, - "r5dn.24xlarge": 50, - "r5dn.2xlarge": 15, - "r5dn.4xlarge": 30, - "r5dn.8xlarge": 30, - "r5dn.large": 10, - "r5dn.xlarge": 15, - "r5n.12xlarge": 30, - "r5n.16xlarge": 50, - "r5n.24xlarge": 50, - "r5n.2xlarge": 15, - "r5n.4xlarge": 30, - "r5n.8xlarge": 30, - "r5n.large": 10, - "r5n.xlarge": 15, - "r6g.12xlarge": 30, - "r6g.16xlarge": 50, - "r6g.2xlarge": 15, - "r6g.4xlarge": 30, - "r6g.8xlarge": 30, - "r6g.large": 10, - "r6g.medium": 4, - "r6g.metal": 50, - "r6g.xlarge": 15, - "t1.micro": 2, - "t2.2xlarge": 15, - "t2.large": 12, - "t2.medium": 6, - "t2.micro": 2, - "t2.nano": 2, - "t2.small": 4, - "t2.xlarge": 15, - "t3.2xlarge": 15, - "t3.large": 12, - "t3.medium": 6, - "t3.micro": 2, - "t3.nano": 2, - "t3.small": 4, - "t3.xlarge": 15, - "t3a.2xlarge": 15, - "t3a.large": 12, - "t3a.medium": 6, - "t3a.micro": 2, - "t3a.nano": 2, - "t3a.small": 4, - "t3a.xlarge": 15, - "u-12tb1.metal": 30, - "u-18tb1.metal": 50, - "u-24tb1.metal": 50, - "u-6tb1.metal": 30, - "u-9tb1.metal": 30, - "x1.16xlarge": 30, - "x1.32xlarge": 30, - "x1e.16xlarge": 30, - "x1e.2xlarge": 15, - "x1e.32xlarge": 30, - "x1e.4xlarge": 15, - "x1e.8xlarge": 15, - "x1e.xlarge": 10, - "z1d.12xlarge": 50, - "z1d.2xlarge": 15, - "z1d.3xlarge": 30, - "z1d.6xlarge": 30, - "z1d.large": 10, - "z1d.metal": 50, - "z1d.xlarge": 15, +var InstanceNetworkingLimits = map[string]InstanceTypeLimits{ + "a1.2xlarge": {ENILimit: 4, IPv4Limit: 15}, + "a1.4xlarge": {ENILimit: 8, IPv4Limit: 30}, + "a1.large": {ENILimit: 3, IPv4Limit: 10}, + "a1.medium": {ENILimit: 2, IPv4Limit: 4}, + "a1.metal": {ENILimit: 8, IPv4Limit: 30}, + "a1.xlarge": {ENILimit: 4, IPv4Limit: 15}, + "c1.medium": {ENILimit: 2, IPv4Limit: 6}, + "c1.xlarge": {ENILimit: 4, IPv4Limit: 15}, + "c3.2xlarge": {ENILimit: 4, IPv4Limit: 15}, + "c3.4xlarge": {ENILimit: 8, IPv4Limit: 30}, + "c3.8xlarge": {ENILimit: 8, IPv4Limit: 30}, + "c3.large": {ENILimit: 3, IPv4Limit: 10}, + "c3.xlarge": {ENILimit: 4, IPv4Limit: 15}, + "c4.2xlarge": {ENILimit: 4, IPv4Limit: 15}, + "c4.4xlarge": {ENILimit: 8, IPv4Limit: 30}, + "c4.8xlarge": {ENILimit: 8, IPv4Limit: 30}, + "c4.large": {ENILimit: 3, IPv4Limit: 10}, + "c4.xlarge": {ENILimit: 4, IPv4Limit: 15}, + "c5.12xlarge": {ENILimit: 8, IPv4Limit: 30}, + "c5.18xlarge": {ENILimit: 15, IPv4Limit: 50}, + "c5.24xlarge": {ENILimit: 15, IPv4Limit: 50}, + "c5.2xlarge": {ENILimit: 4, IPv4Limit: 15}, + "c5.4xlarge": {ENILimit: 8, IPv4Limit: 30}, + "c5.9xlarge": {ENILimit: 8, IPv4Limit: 30}, + "c5.large": {ENILimit: 3, IPv4Limit: 10}, + "c5.metal": {ENILimit: 15, IPv4Limit: 50}, + "c5.xlarge": {ENILimit: 4, IPv4Limit: 15}, + "c5a.12xlarge": {ENILimit: 8, IPv4Limit: 30}, + "c5a.16xlarge": {ENILimit: 15, IPv4Limit: 50}, + "c5a.24xlarge": {ENILimit: 15, IPv4Limit: 50}, + "c5a.2xlarge": {ENILimit: 4, IPv4Limit: 15}, + "c5a.4xlarge": {ENILimit: 8, IPv4Limit: 30}, + "c5a.8xlarge": {ENILimit: 8, IPv4Limit: 30}, + "c5a.large": {ENILimit: 3, IPv4Limit: 10}, + "c5a.metal": {ENILimit: 15, IPv4Limit: 50}, + "c5a.xlarge": {ENILimit: 4, IPv4Limit: 15}, + "c5ad.12xlarge": {ENILimit: 8, IPv4Limit: 30}, + "c5ad.16xlarge": {ENILimit: 15, IPv4Limit: 50}, + "c5ad.24xlarge": {ENILimit: 15, IPv4Limit: 50}, + "c5ad.2xlarge": {ENILimit: 4, IPv4Limit: 15}, + "c5ad.4xlarge": {ENILimit: 8, IPv4Limit: 30}, + "c5ad.8xlarge": {ENILimit: 8, IPv4Limit: 30}, + "c5ad.large": {ENILimit: 3, IPv4Limit: 10}, + "c5ad.metal": {ENILimit: 15, IPv4Limit: 50}, + "c5ad.xlarge": {ENILimit: 4, IPv4Limit: 15}, + "c5d.12xlarge": {ENILimit: 8, IPv4Limit: 30}, + "c5d.18xlarge": {ENILimit: 15, IPv4Limit: 50}, + "c5d.24xlarge": {ENILimit: 15, IPv4Limit: 50}, + "c5d.2xlarge": {ENILimit: 4, IPv4Limit: 15}, + "c5d.4xlarge": {ENILimit: 8, IPv4Limit: 30}, + "c5d.9xlarge": {ENILimit: 8, IPv4Limit: 30}, + "c5d.large": {ENILimit: 3, IPv4Limit: 10}, + "c5d.metal": {ENILimit: 15, IPv4Limit: 50}, + "c5d.xlarge": {ENILimit: 4, IPv4Limit: 15}, + "c5n.18xlarge": {ENILimit: 15, IPv4Limit: 50}, + "c5n.2xlarge": {ENILimit: 4, IPv4Limit: 15}, + "c5n.4xlarge": {ENILimit: 8, IPv4Limit: 30}, + "c5n.9xlarge": {ENILimit: 8, IPv4Limit: 30}, + "c5n.large": {ENILimit: 3, IPv4Limit: 10}, + "c5n.metal": {ENILimit: 15, IPv4Limit: 50}, + "c5n.xlarge": {ENILimit: 4, IPv4Limit: 15}, + "c6g.12xlarge": {ENILimit: 8, IPv4Limit: 30}, + "c6g.16xlarge": {ENILimit: 15, IPv4Limit: 50}, + "c6g.2xlarge": {ENILimit: 4, IPv4Limit: 15}, + "c6g.4xlarge": {ENILimit: 8, IPv4Limit: 30}, + "c6g.8xlarge": {ENILimit: 8, IPv4Limit: 30}, + "c6g.large": {ENILimit: 3, IPv4Limit: 10}, + "c6g.medium": {ENILimit: 2, IPv4Limit: 4}, + "c6g.metal": {ENILimit: 15, IPv4Limit: 50}, + "c6g.xlarge": {ENILimit: 4, IPv4Limit: 15}, + "c6gd.12xlarge": {ENILimit: 8, IPv4Limit: 30}, + "c6gd.16xlarge": {ENILimit: 15, IPv4Limit: 50}, + "c6gd.2xlarge": {ENILimit: 4, IPv4Limit: 15}, + "c6gd.4xlarge": {ENILimit: 8, IPv4Limit: 30}, + "c6gd.8xlarge": {ENILimit: 8, IPv4Limit: 30}, + "c6gd.large": {ENILimit: 3, IPv4Limit: 10}, + "c6gd.medium": {ENILimit: 2, IPv4Limit: 4}, + "c6gd.metal": {ENILimit: 15, IPv4Limit: 50}, + "c6gd.xlarge": {ENILimit: 4, IPv4Limit: 15}, + "cc2.8xlarge": {ENILimit: 8, IPv4Limit: 30}, + "cr1.8xlarge": {ENILimit: 8, IPv4Limit: 30}, + "d2.2xlarge": {ENILimit: 4, IPv4Limit: 15}, + "d2.4xlarge": {ENILimit: 8, IPv4Limit: 30}, + "d2.8xlarge": {ENILimit: 8, IPv4Limit: 30}, + "d2.xlarge": {ENILimit: 4, IPv4Limit: 15}, + "f1.16xlarge": {ENILimit: 8, IPv4Limit: 50}, + "f1.2xlarge": {ENILimit: 4, IPv4Limit: 15}, + "f1.4xlarge": {ENILimit: 8, IPv4Limit: 30}, + "g2.2xlarge": {ENILimit: 4, IPv4Limit: 15}, + "g2.8xlarge": {ENILimit: 8, IPv4Limit: 30}, + "g3.16xlarge": {ENILimit: 15, IPv4Limit: 50}, + "g3.4xlarge": {ENILimit: 8, IPv4Limit: 30}, + "g3.8xlarge": {ENILimit: 8, IPv4Limit: 30}, + "g3s.xlarge": {ENILimit: 4, IPv4Limit: 15}, + "g4dn.12xlarge": {ENILimit: 8, IPv4Limit: 30}, + "g4dn.16xlarge": {ENILimit: 4, IPv4Limit: 15}, + "g4dn.2xlarge": {ENILimit: 3, IPv4Limit: 10}, + "g4dn.4xlarge": {ENILimit: 3, IPv4Limit: 10}, + "g4dn.8xlarge": {ENILimit: 4, IPv4Limit: 15}, + "g4dn.metal": {ENILimit: 15, IPv4Limit: 50}, + "g4dn.xlarge": {ENILimit: 3, IPv4Limit: 10}, + "h1.16xlarge": {ENILimit: 15, IPv4Limit: 50}, + "h1.2xlarge": {ENILimit: 4, IPv4Limit: 15}, + "h1.4xlarge": {ENILimit: 8, IPv4Limit: 30}, + "h1.8xlarge": {ENILimit: 8, IPv4Limit: 30}, + "hs1.8xlarge": {ENILimit: 8, IPv4Limit: 30}, + "i2.2xlarge": {ENILimit: 4, IPv4Limit: 15}, + "i2.4xlarge": {ENILimit: 8, IPv4Limit: 30}, + "i2.8xlarge": {ENILimit: 8, IPv4Limit: 30}, + "i2.xlarge": {ENILimit: 4, IPv4Limit: 15}, + "i3.16xlarge": {ENILimit: 15, IPv4Limit: 50}, + "i3.2xlarge": {ENILimit: 4, IPv4Limit: 15}, + "i3.4xlarge": {ENILimit: 8, IPv4Limit: 30}, + "i3.8xlarge": {ENILimit: 8, IPv4Limit: 30}, + "i3.large": {ENILimit: 3, IPv4Limit: 10}, + "i3.metal": {ENILimit: 15, IPv4Limit: 50}, + "i3.xlarge": {ENILimit: 4, IPv4Limit: 15}, + "i3en.12xlarge": {ENILimit: 8, IPv4Limit: 30}, + "i3en.24xlarge": {ENILimit: 15, IPv4Limit: 50}, + "i3en.2xlarge": {ENILimit: 4, IPv4Limit: 15}, + "i3en.3xlarge": {ENILimit: 4, IPv4Limit: 15}, + "i3en.6xlarge": {ENILimit: 8, IPv4Limit: 30}, + "i3en.large": {ENILimit: 3, IPv4Limit: 10}, + "i3en.metal": {ENILimit: 15, IPv4Limit: 50}, + "i3en.xlarge": {ENILimit: 4, IPv4Limit: 15}, + "inf1.24xlarge": {ENILimit: 15, IPv4Limit: 30}, + "inf1.2xlarge": {ENILimit: 4, IPv4Limit: 10}, + "inf1.6xlarge": {ENILimit: 8, IPv4Limit: 30}, + "inf1.xlarge": {ENILimit: 4, IPv4Limit: 10}, + "m1.large": {ENILimit: 3, IPv4Limit: 10}, + "m1.medium": {ENILimit: 2, IPv4Limit: 6}, + "m1.small": {ENILimit: 2, IPv4Limit: 4}, + "m1.xlarge": {ENILimit: 4, IPv4Limit: 15}, + "m2.2xlarge": {ENILimit: 4, IPv4Limit: 30}, + "m2.4xlarge": {ENILimit: 8, IPv4Limit: 30}, + "m2.xlarge": {ENILimit: 4, IPv4Limit: 15}, + "m3.2xlarge": {ENILimit: 4, IPv4Limit: 30}, + "m3.large": {ENILimit: 3, IPv4Limit: 10}, + "m3.medium": {ENILimit: 2, IPv4Limit: 6}, + "m3.xlarge": {ENILimit: 4, IPv4Limit: 15}, + "m4.10xlarge": {ENILimit: 8, IPv4Limit: 30}, + "m4.16xlarge": {ENILimit: 8, IPv4Limit: 30}, + "m4.2xlarge": {ENILimit: 4, IPv4Limit: 15}, + "m4.4xlarge": {ENILimit: 8, IPv4Limit: 30}, + "m4.large": {ENILimit: 2, IPv4Limit: 10}, + "m4.xlarge": {ENILimit: 4, IPv4Limit: 15}, + "m5.12xlarge": {ENILimit: 8, IPv4Limit: 30}, + "m5.16xlarge": {ENILimit: 15, IPv4Limit: 50}, + "m5.24xlarge": {ENILimit: 15, IPv4Limit: 50}, + "m5.2xlarge": {ENILimit: 4, IPv4Limit: 15}, + "m5.4xlarge": {ENILimit: 8, IPv4Limit: 30}, + "m5.8xlarge": {ENILimit: 8, IPv4Limit: 30}, + "m5.large": {ENILimit: 3, IPv4Limit: 10}, + "m5.metal": {ENILimit: 15, IPv4Limit: 50}, + "m5.xlarge": {ENILimit: 4, IPv4Limit: 15}, + "m5a.12xlarge": {ENILimit: 8, IPv4Limit: 30}, + "m5a.16xlarge": {ENILimit: 15, IPv4Limit: 50}, + "m5a.24xlarge": {ENILimit: 15, IPv4Limit: 50}, + "m5a.2xlarge": {ENILimit: 4, IPv4Limit: 15}, + "m5a.4xlarge": {ENILimit: 8, IPv4Limit: 30}, + "m5a.8xlarge": {ENILimit: 8, IPv4Limit: 30}, + "m5a.large": {ENILimit: 3, IPv4Limit: 10}, + "m5a.xlarge": {ENILimit: 4, IPv4Limit: 15}, + "m5ad.12xlarge": {ENILimit: 8, IPv4Limit: 30}, + "m5ad.16xlarge": {ENILimit: 15, IPv4Limit: 50}, + "m5ad.24xlarge": {ENILimit: 15, IPv4Limit: 50}, + "m5ad.2xlarge": {ENILimit: 4, IPv4Limit: 15}, + "m5ad.4xlarge": {ENILimit: 8, IPv4Limit: 30}, + "m5ad.8xlarge": {ENILimit: 8, IPv4Limit: 30}, + "m5ad.large": {ENILimit: 3, IPv4Limit: 10}, + "m5ad.xlarge": {ENILimit: 4, IPv4Limit: 15}, + "m5d.12xlarge": {ENILimit: 8, IPv4Limit: 30}, + "m5d.16xlarge": {ENILimit: 15, IPv4Limit: 50}, + "m5d.24xlarge": {ENILimit: 15, IPv4Limit: 50}, + "m5d.2xlarge": {ENILimit: 4, IPv4Limit: 15}, + "m5d.4xlarge": {ENILimit: 8, IPv4Limit: 30}, + "m5d.8xlarge": {ENILimit: 8, IPv4Limit: 30}, + "m5d.large": {ENILimit: 3, IPv4Limit: 10}, + "m5d.metal": {ENILimit: 15, IPv4Limit: 50}, + "m5d.xlarge": {ENILimit: 4, IPv4Limit: 15}, + "m5dn.12xlarge": {ENILimit: 8, IPv4Limit: 30}, + "m5dn.16xlarge": {ENILimit: 15, IPv4Limit: 50}, + "m5dn.24xlarge": {ENILimit: 15, IPv4Limit: 50}, + "m5dn.2xlarge": {ENILimit: 4, IPv4Limit: 15}, + "m5dn.4xlarge": {ENILimit: 8, IPv4Limit: 30}, + "m5dn.8xlarge": {ENILimit: 8, IPv4Limit: 30}, + "m5dn.large": {ENILimit: 3, IPv4Limit: 10}, + "m5dn.xlarge": {ENILimit: 4, IPv4Limit: 15}, + "m5n.12xlarge": {ENILimit: 8, IPv4Limit: 30}, + "m5n.16xlarge": {ENILimit: 15, IPv4Limit: 50}, + "m5n.24xlarge": {ENILimit: 15, IPv4Limit: 50}, + "m5n.2xlarge": {ENILimit: 4, IPv4Limit: 15}, + "m5n.4xlarge": {ENILimit: 8, IPv4Limit: 30}, + "m5n.8xlarge": {ENILimit: 8, IPv4Limit: 30}, + "m5n.large": {ENILimit: 3, IPv4Limit: 10}, + "m5n.xlarge": {ENILimit: 4, IPv4Limit: 15}, + "m6g.12xlarge": {ENILimit: 8, IPv4Limit: 30}, + "m6g.16xlarge": {ENILimit: 15, IPv4Limit: 50}, + "m6g.2xlarge": {ENILimit: 4, IPv4Limit: 15}, + "m6g.4xlarge": {ENILimit: 8, IPv4Limit: 30}, + "m6g.8xlarge": {ENILimit: 8, IPv4Limit: 30}, + "m6g.large": {ENILimit: 3, IPv4Limit: 10}, + "m6g.medium": {ENILimit: 2, IPv4Limit: 4}, + "m6g.metal": {ENILimit: 15, IPv4Limit: 50}, + "m6g.xlarge": {ENILimit: 4, IPv4Limit: 15}, + "m6gd.12xlarge": {ENILimit: 8, IPv4Limit: 30}, + "m6gd.16xlarge": {ENILimit: 15, IPv4Limit: 50}, + "m6gd.2xlarge": {ENILimit: 4, IPv4Limit: 15}, + "m6gd.4xlarge": {ENILimit: 8, IPv4Limit: 30}, + "m6gd.8xlarge": {ENILimit: 8, IPv4Limit: 30}, + "m6gd.large": {ENILimit: 3, IPv4Limit: 10}, + "m6gd.medium": {ENILimit: 2, IPv4Limit: 4}, + "m6gd.metal": {ENILimit: 15, IPv4Limit: 50}, + "m6gd.xlarge": {ENILimit: 4, IPv4Limit: 15}, + "p2.16xlarge": {ENILimit: 8, IPv4Limit: 30}, + "p2.8xlarge": {ENILimit: 8, IPv4Limit: 30}, + "p2.xlarge": {ENILimit: 4, IPv4Limit: 15}, + "p3.16xlarge": {ENILimit: 8, IPv4Limit: 30}, + "p3.2xlarge": {ENILimit: 4, IPv4Limit: 15}, + "p3.8xlarge": {ENILimit: 8, IPv4Limit: 30}, + "p3dn.24xlarge": {ENILimit: 15, IPv4Limit: 50}, + "r3.2xlarge": {ENILimit: 4, IPv4Limit: 15}, + "r3.4xlarge": {ENILimit: 8, IPv4Limit: 30}, + "r3.8xlarge": {ENILimit: 8, IPv4Limit: 30}, + "r3.large": {ENILimit: 3, IPv4Limit: 10}, + "r3.xlarge": {ENILimit: 4, IPv4Limit: 15}, + "r4.16xlarge": {ENILimit: 15, IPv4Limit: 50}, + "r4.2xlarge": {ENILimit: 4, IPv4Limit: 15}, + "r4.4xlarge": {ENILimit: 8, IPv4Limit: 30}, + "r4.8xlarge": {ENILimit: 8, IPv4Limit: 30}, + "r4.large": {ENILimit: 3, IPv4Limit: 10}, + "r4.xlarge": {ENILimit: 4, IPv4Limit: 15}, + "r5.12xlarge": {ENILimit: 8, IPv4Limit: 30}, + "r5.16xlarge": {ENILimit: 15, IPv4Limit: 50}, + "r5.24xlarge": {ENILimit: 15, IPv4Limit: 50}, + "r5.2xlarge": {ENILimit: 4, IPv4Limit: 15}, + "r5.4xlarge": {ENILimit: 8, IPv4Limit: 30}, + "r5.8xlarge": {ENILimit: 8, IPv4Limit: 30}, + "r5.large": {ENILimit: 3, IPv4Limit: 10}, + "r5.metal": {ENILimit: 15, IPv4Limit: 50}, + "r5.xlarge": {ENILimit: 4, IPv4Limit: 15}, + "r5a.12xlarge": {ENILimit: 8, IPv4Limit: 30}, + "r5a.16xlarge": {ENILimit: 15, IPv4Limit: 50}, + "r5a.24xlarge": {ENILimit: 15, IPv4Limit: 50}, + "r5a.2xlarge": {ENILimit: 4, IPv4Limit: 15}, + "r5a.4xlarge": {ENILimit: 8, IPv4Limit: 30}, + "r5a.8xlarge": {ENILimit: 8, IPv4Limit: 30}, + "r5a.large": {ENILimit: 3, IPv4Limit: 10}, + "r5a.xlarge": {ENILimit: 4, IPv4Limit: 15}, + "r5ad.12xlarge": {ENILimit: 8, IPv4Limit: 30}, + "r5ad.16xlarge": {ENILimit: 15, IPv4Limit: 50}, + "r5ad.24xlarge": {ENILimit: 15, IPv4Limit: 50}, + "r5ad.2xlarge": {ENILimit: 4, IPv4Limit: 15}, + "r5ad.4xlarge": {ENILimit: 8, IPv4Limit: 30}, + "r5ad.8xlarge": {ENILimit: 8, IPv4Limit: 30}, + "r5ad.large": {ENILimit: 3, IPv4Limit: 10}, + "r5ad.xlarge": {ENILimit: 4, IPv4Limit: 15}, + "r5d.12xlarge": {ENILimit: 8, IPv4Limit: 30}, + "r5d.16xlarge": {ENILimit: 15, IPv4Limit: 50}, + "r5d.24xlarge": {ENILimit: 15, IPv4Limit: 50}, + "r5d.2xlarge": {ENILimit: 4, IPv4Limit: 15}, + "r5d.4xlarge": {ENILimit: 8, IPv4Limit: 30}, + "r5d.8xlarge": {ENILimit: 8, IPv4Limit: 30}, + "r5d.large": {ENILimit: 3, IPv4Limit: 10}, + "r5d.metal": {ENILimit: 15, IPv4Limit: 50}, + "r5d.xlarge": {ENILimit: 4, IPv4Limit: 15}, + "r5dn.12xlarge": {ENILimit: 8, IPv4Limit: 30}, + "r5dn.16xlarge": {ENILimit: 15, IPv4Limit: 50}, + "r5dn.24xlarge": {ENILimit: 15, IPv4Limit: 50}, + "r5dn.2xlarge": {ENILimit: 4, IPv4Limit: 15}, + "r5dn.4xlarge": {ENILimit: 8, IPv4Limit: 30}, + "r5dn.8xlarge": {ENILimit: 8, IPv4Limit: 30}, + "r5dn.large": {ENILimit: 3, IPv4Limit: 10}, + "r5dn.xlarge": {ENILimit: 4, IPv4Limit: 15}, + "r5n.12xlarge": {ENILimit: 8, IPv4Limit: 30}, + "r5n.16xlarge": {ENILimit: 15, IPv4Limit: 50}, + "r5n.24xlarge": {ENILimit: 15, IPv4Limit: 50}, + "r5n.2xlarge": {ENILimit: 4, IPv4Limit: 15}, + "r5n.4xlarge": {ENILimit: 8, IPv4Limit: 30}, + "r5n.8xlarge": {ENILimit: 8, IPv4Limit: 30}, + "r5n.large": {ENILimit: 3, IPv4Limit: 10}, + "r5n.xlarge": {ENILimit: 4, IPv4Limit: 15}, + "r6g.12xlarge": {ENILimit: 8, IPv4Limit: 30}, + "r6g.16xlarge": {ENILimit: 15, IPv4Limit: 50}, + "r6g.2xlarge": {ENILimit: 4, IPv4Limit: 15}, + "r6g.4xlarge": {ENILimit: 8, IPv4Limit: 30}, + "r6g.8xlarge": {ENILimit: 8, IPv4Limit: 30}, + "r6g.large": {ENILimit: 3, IPv4Limit: 10}, + "r6g.medium": {ENILimit: 2, IPv4Limit: 4}, + "r6g.metal": {ENILimit: 15, IPv4Limit: 50}, + "r6g.xlarge": {ENILimit: 4, IPv4Limit: 15}, + "r6gd.12xlarge": {ENILimit: 8, IPv4Limit: 30}, + "r6gd.16xlarge": {ENILimit: 15, IPv4Limit: 50}, + "r6gd.2xlarge": {ENILimit: 4, IPv4Limit: 15}, + "r6gd.4xlarge": {ENILimit: 8, IPv4Limit: 30}, + "r6gd.8xlarge": {ENILimit: 8, IPv4Limit: 30}, + "r6gd.large": {ENILimit: 3, IPv4Limit: 10}, + "r6gd.medium": {ENILimit: 2, IPv4Limit: 4}, + "r6gd.metal": {ENILimit: 15, IPv4Limit: 50}, + "r6gd.xlarge": {ENILimit: 4, IPv4Limit: 15}, + "t1.micro": {ENILimit: 2, IPv4Limit: 2}, + "t2.2xlarge": {ENILimit: 3, IPv4Limit: 15}, + "t2.large": {ENILimit: 3, IPv4Limit: 12}, + "t2.medium": {ENILimit: 3, IPv4Limit: 6}, + "t2.micro": {ENILimit: 2, IPv4Limit: 2}, + "t2.nano": {ENILimit: 2, IPv4Limit: 2}, + "t2.small": {ENILimit: 3, IPv4Limit: 4}, + "t2.xlarge": {ENILimit: 3, IPv4Limit: 15}, + "t3.2xlarge": {ENILimit: 4, IPv4Limit: 15}, + "t3.large": {ENILimit: 3, IPv4Limit: 12}, + "t3.medium": {ENILimit: 3, IPv4Limit: 6}, + "t3.micro": {ENILimit: 2, IPv4Limit: 2}, + "t3.nano": {ENILimit: 2, IPv4Limit: 2}, + "t3.small": {ENILimit: 3, IPv4Limit: 4}, + "t3.xlarge": {ENILimit: 4, IPv4Limit: 15}, + "t3a.2xlarge": {ENILimit: 4, IPv4Limit: 15}, + "t3a.large": {ENILimit: 3, IPv4Limit: 12}, + "t3a.medium": {ENILimit: 3, IPv4Limit: 6}, + "t3a.micro": {ENILimit: 2, IPv4Limit: 2}, + "t3a.nano": {ENILimit: 2, IPv4Limit: 2}, + "t3a.small": {ENILimit: 2, IPv4Limit: 4}, + "t3a.xlarge": {ENILimit: 4, IPv4Limit: 15}, + "u-12tb1.metal": {ENILimit: 5, IPv4Limit: 30}, + "u-18tb1.metal": {ENILimit: 15, IPv4Limit: 50}, + "u-24tb1.metal": {ENILimit: 15, IPv4Limit: 50}, + "u-6tb1.metal": {ENILimit: 5, IPv4Limit: 30}, + "u-9tb1.metal": {ENILimit: 5, IPv4Limit: 30}, + "x1.16xlarge": {ENILimit: 8, IPv4Limit: 30}, + "x1.32xlarge": {ENILimit: 8, IPv4Limit: 30}, + "x1e.16xlarge": {ENILimit: 8, IPv4Limit: 30}, + "x1e.2xlarge": {ENILimit: 4, IPv4Limit: 15}, + "x1e.32xlarge": {ENILimit: 8, IPv4Limit: 30}, + "x1e.4xlarge": {ENILimit: 4, IPv4Limit: 15}, + "x1e.8xlarge": {ENILimit: 4, IPv4Limit: 15}, + "x1e.xlarge": {ENILimit: 3, IPv4Limit: 10}, + "z1d.12xlarge": {ENILimit: 15, IPv4Limit: 50}, + "z1d.2xlarge": {ENILimit: 4, IPv4Limit: 15}, + "z1d.3xlarge": {ENILimit: 8, IPv4Limit: 30}, + "z1d.6xlarge": {ENILimit: 8, IPv4Limit: 30}, + "z1d.large": {ENILimit: 3, IPv4Limit: 10}, + "z1d.metal": {ENILimit: 15, IPv4Limit: 50}, + "z1d.xlarge": {ENILimit: 4, IPv4Limit: 15}, } diff --git a/pkg/ipamd/ipamd.go b/pkg/ipamd/ipamd.go index ffe317065fe..2d1bc8b4be2 100644 --- a/pkg/ipamd/ipamd.go +++ b/pkg/ipamd/ipamd.go @@ -333,7 +333,7 @@ func (c *IPAMContext) nodeInit() error { return err } c.maxENI = nodeMaxENI - c.maxIPsPerENI, err = c.awsClient.GetENIipLimit() + c.maxIPsPerENI, err = c.awsClient.GetENIIPv4Limit() if err != nil { return err } diff --git a/scripts/gen_vpc_ip_limits.go b/scripts/gen_vpc_ip_limits.go new file mode 100644 index 00000000000..f844e91efba --- /dev/null +++ b/scripts/gen_vpc_ip_limits.go @@ -0,0 +1,231 @@ +// Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"). You may +// not use this file except in compliance with the License. A copy of the +// License is located at +// +// http://aws.amazon.com/apache2.0/ +// +// or in the "license" file accompanying this file. This file is distributed +// on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either +// express or implied. See the License for the specific language governing +// permissions and limitations under the License. + +// This program generates vpc_ip_resource_limit.go +// It can be invoked by running `go run` +package main + +import ( + "fmt" + "os" + "reflect" + "sort" + "strings" + "text/template" + "time" + + "github.com/aws/amazon-vpc-cni-k8s/pkg/awsutils" + "github.com/aws/amazon-vpc-cni-k8s/pkg/utils/logger" + + "github.com/aws/aws-sdk-go/aws" + + "github.com/aws/aws-sdk-go/aws/session" + "github.com/aws/aws-sdk-go/service/ec2" +) + +const ipLimitFileName = "pkg/awsutils/vpc_ip_resource_limit.go" +const eniMaxPodsFileName = "misc/eni-max-pods.txt" + +// Helper to quote the type in order to print the map correctly +func printMapLine(instanceType string, l awsutils.InstanceTypeLimits) string { + indentedInstanceType := fmt.Sprintf("\"%s\":", instanceType) + return strings.Replace(fmt.Sprintf("%-17s%# v", indentedInstanceType, l), "awsutils.InstanceTypeLimits", "", 1) +} + +// Helper to calculate the --max-pods to match the ENIs and IPs on the instance +func printPodLimit(instanceType string, l awsutils.InstanceTypeLimits) string { + maxPods := l.ENILimit*(l.IPv4Limit-1) + 2 + return fmt.Sprintf("%s %d", instanceType, maxPods) +} + +// Helper function to call the EC2 DescribeInstanceTypes API and generate the IP limit file. +func main() { + log := logger.DefaultLogger() + + // Get session + sess := session.Must(session.NewSessionWithOptions(session.Options{ + SharedConfigState: session.SharedConfigEnable, + })) + _, err := sess.Config.Credentials.Get() + if err != nil { + log.Fatalf("Failed to get session credentials: %v", err) + } + svc := ec2.New(sess) + describeInstanceTypesInput := &ec2.DescribeInstanceTypesInput{} + + eniLimitMap := make(map[string]awsutils.InstanceTypeLimits) + for { + output, err := svc.DescribeInstanceTypes(describeInstanceTypesInput) + if err != nil { + log.Fatalf("Failed to call EC2 DescibeInstanceTypes: %v", err) + } + // We just want the type name, ENI and IP limits + for _, info := range output.InstanceTypes { + // Ignore any missing values + instanceType := aws.StringValue(info.InstanceType) + eniLimit := int(aws.Int64Value(info.NetworkInfo.MaximumNetworkInterfaces)) + ipv4Limit := int(aws.Int64Value(info.NetworkInfo.Ipv4AddressesPerInterface)) + if instanceType != "" && eniLimit > 0 && ipv4Limit > 0 { + eniLimitMap[instanceType] = awsutils.InstanceTypeLimits{ENILimit: eniLimit, IPv4Limit: ipv4Limit} + } + } + // Paginate to the next request + if output.NextToken == nil { + break + } + describeInstanceTypesInput = &ec2.DescribeInstanceTypesInput{ + NextToken: output.NextToken, + } + } + + // Override faulty values and add missing instance types + eniLimitMap = addManualLimits(eniLimitMap) + + // Sort the keys + instanceTypes := make([]string, 0) + for k := range eniLimitMap { + instanceTypes = append(instanceTypes, k) + } + sort.Strings(instanceTypes) + + // Generate instance ENI limits + eniLimits := make([]string, 0) + for _, it := range instanceTypes { + eniLimits = append(eniLimits, printMapLine(it, eniLimitMap[it])) + } + f, err := os.Create(ipLimitFileName) + if err != nil { + log.Fatalf("Failed to create file: %v\n", err) + } + err = limitsTemplate.Execute(f, struct { + Timestamp string + ENILimits []string + }{ + Timestamp: time.Now().Format(time.RFC3339), + ENILimits: eniLimits, + }) + log.Infof("Generated %s", ipLimitFileName) + + // Generate --max-pods file for awslabs/amazon-eks-ami + eniPods := make([]string, 0) + for _, it := range instanceTypes { + eniPods = append(eniPods, printPodLimit(it, eniLimitMap[it])) + } + f, err = os.Create(eniMaxPodsFileName) + if err != nil { + log.Fatalf("Failed to create file: %s\n", err) + } + err = eksMaxPodsTemplate.Execute(f, struct { + Timestamp string + ENIPods []string + }{ + Timestamp: time.Now().Format(time.RFC3339), + ENIPods: eniPods, + }) + log.Infof("Generated %s", eniMaxPodsFileName) + if err != nil { + log.Fatalf("Failed to generate template: %v\n", err) + } +} + +// addManualLimits has the list of faulty or missing instance types +func addManualLimits(limitMap map[string]awsutils.InstanceTypeLimits) map[string]awsutils.InstanceTypeLimits { + manuallyAddedLimits := map[string]awsutils.InstanceTypeLimits{ + "cr1.8xlarge": {ENILimit: 8, IPv4Limit: 30}, + "hs1.8xlarge": {ENILimit: 8, IPv4Limit: 30}, + "u-12tb1.metal": {ENILimit: 5, IPv4Limit: 30}, + "u-18tb1.metal": {ENILimit: 15, IPv4Limit: 50}, + "u-24tb1.metal": {ENILimit: 15, IPv4Limit: 50}, + "u-6tb1.metal": {ENILimit: 5, IPv4Limit: 30}, + "u-9tb1.metal": {ENILimit: 5, IPv4Limit: 30}, + "c5a.metal": {ENILimit: 15, IPv4Limit: 50}, + "c5ad.12xlarge": {ENILimit: 8, IPv4Limit: 30}, + "c5ad.16xlarge": {ENILimit: 15, IPv4Limit: 50}, + "c5ad.24xlarge": {ENILimit: 15, IPv4Limit: 50}, + "c5ad.2xlarge": {ENILimit: 4, IPv4Limit: 15}, + "c5ad.4xlarge": {ENILimit: 8, IPv4Limit: 30}, + "c5ad.8xlarge": {ENILimit: 8, IPv4Limit: 30}, + "c5ad.large": {ENILimit: 3, IPv4Limit: 10}, + "c5ad.metal": {ENILimit: 15, IPv4Limit: 50}, + "c5ad.xlarge": {ENILimit: 4, IPv4Limit: 15}, + } + for instanceType, instanceLimits := range manuallyAddedLimits { + val, ok := limitMap[instanceType] + if ok { + if reflect.DeepEqual(val, instanceLimits) { + fmt.Printf("Delete %q: %v is already correct in the API\n", instanceType, val) + } else { + fmt.Printf("Replacing API value %v with override %v for %q\n", val, instanceLimits, instanceType) + } + } else { + fmt.Printf("Adding %q: %v since it is missing from the API\n", instanceType, instanceLimits) + } + limitMap[instanceType] = instanceLimits + } + return limitMap +} + +var limitsTemplate = template.Must(template.New("").Parse(`// Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"). You may +// not use this file except in compliance with the License. A copy of the +// License is located at +// +// http://aws.amazon.com/apache2.0/ +// +// or in the "license" file accompanying this file. This file is distributed +// on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either +// express or implied. See the License for the specific language governing +// permissions and limitations under the License. + +// Code generated by go generate; DO NOT EDIT. +// This file was generated at {{ .Timestamp }} + +package awsutils + +// InstanceNetworkingLimits contains a mapping from instance type to networking limits for the type. Documentation found at +// https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-eni.html#AvailableIpPerENI +var InstanceNetworkingLimits = map[string]InstanceTypeLimits{ +{{- range $mapLine := .ENILimits}} + {{ printf "%s" $mapLine }}, +{{- end }} +} +`)) + +var eksMaxPodsTemplate = template.Must(template.New("").Parse(`# Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"). You may +# not use this file except in compliance with the License. A copy of the +# License is located at +# +# http://aws.amazon.com/apache2.0/ +# +# or in the "license" file accompanying this file. This file is distributed +# on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either +# express or implied. See the License for the specific language governing +# permissions and limitations under the License. +# +# This file was generated at {{ .Timestamp }} +# +# Mapping is calculated from AWS EC2 API using the following formula: +# * First IP on each ENI is not used for pods +# * 2 additional host-networking pods (AWS ENI and kube-proxy) are accounted for +# +# # of ENI * (# of IPv4 per ENI - 1) + 2 +# +# https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-eni.html#AvailableIpPerENI +# +{{- range $instanceLimit := .ENIPods}} +{{ printf "%s" $instanceLimit }} +{{- end }} +`))