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

Add support for "Active VPC peering connections per VPC" quota. #576

Open
wants to merge 1 commit into
base: develop
Choose a base branch
from
Open
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
38 changes: 38 additions & 0 deletions awslimitchecker/services/vpc.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ def find_usage(self):
self._find_usage_route_tables()
self._find_usage_gateways()
self._find_usage_nat_gateways(subnet_to_az)
self._find_usage_peering_connections()
self._find_usages_vpn_gateways()
self._find_usage_network_interfaces()
self._have_usage = True
Expand Down Expand Up @@ -216,6 +217,33 @@ def _find_usage_nat_gateways(self, subnet_to_az):
'perhaps NAT service does not exist in this region?',
exc_info=1)

def _find_usage_peering_connections(self):
"""find usage of Active VPC Peering Connections"""

peering_connections = self.conn.describe_vpc_peering_connections(
Filters=[{'Name': 'status-code', 'Values': ['active']}]
)['VpcPeeringConnections']

peering_connections_per_vpc = defaultdict(int)
for peering in peering_connections:
for vpc in [peering['AccepterVpcInfo'], peering['RequesterVpcInfo']]:
# Each peering contains 2 VPCs and at least one is in our current account and region. To avoid incorrect alerts about out-of-scope VPCs we need to filter to only VPCs in our account and region.

if vpc['OwnerId'] != self.current_account_id:
continue

if vpc['Region'] != "us-west-2": # TODO: How to get current region?
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TODO: I'm not sure how to get the "active" region. Removing this check would result in VPCs being reported for multiple regions.

Copy link

@kjkuan kjkuan Feb 14, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe it should be self.conn._client_config.region_name ?

continue

peering_connections_per_vpc[vpc['VpcId']] += 1

for vpc_id, peerings in peering_connections_per_vpc.items():
self.limits['Active VPC peering connections per VPC']._add_current_usage(
peerings,
aws_type='AWS::EC2::VPC',
resource_id=vpc_id
)

def _find_usages_vpn_gateways(self):
"""find usage of vpn gateways"""

Expand Down Expand Up @@ -343,6 +371,16 @@ def get_limits(self):
quotas_name='NAT gateways per Availability Zone'
)

limits['Active VPC peering connections per VPC'] = AwsLimit(
'Active VPC peering connections per VPC',
self,
50,
self.warning_threshold,
self.critical_threshold,
limit_type='AWS::EC2::VPCPeeringConnection',
limit_subtype='AWS::EC2::VPC',
)

limits['Virtual private gateways'] = AwsLimit(
'Virtual private gateways',
self,
Expand Down
116 changes: 116 additions & 0 deletions awslimitchecker/tests/services/result_fixtures.py
Original file line number Diff line number Diff line change
Expand Up @@ -617,6 +617,122 @@ class VPC(object):
'subnet3': 'az2'
}

test_find_usage_peering_connections = {
'VpcPeeringConnections': [
{
'AccepterVpcInfo': {
'CidrBlock': '10.3.128.0/18',
'CidrBlockSet': [{'CidrBlock': '10.3.128.0/18'}],
'OwnerId': '123456789012',
'PeeringOptions': {
'AllowDnsResolutionFromRemoteVpc': False,
'AllowEgressFromLocalClassicLinkToRemoteVpc': False,
'AllowEgressFromLocalVpcToRemoteClassicLink': False,
},
'Region': 'us-west-2',
'VpcId': 'vpc-1',
},
'RequesterVpcInfo': {
'CidrBlock': '10.8.72.0/21',
'CidrBlockSet': [{'CidrBlock': '10.8.72.0/21'}],
'OwnerId': '123456789012',
'PeeringOptions': {
'AllowDnsResolutionFromRemoteVpc': False,
'AllowEgressFromLocalClassicLinkToRemoteVpc': False,
'AllowEgressFromLocalVpcToRemoteClassicLink': False,
},
'Region': 'ap-south-1',
'VpcId': 'vpc-2',
},
'Status': {
'Code': 'active',
'Message': 'Active',
},
'Tags': [
{
'Key': 'a key',
'Value': 'a value',
},
],
'VpcPeeringConnectionId': 'pcx-1',
},
{
'AccepterVpcInfo': {
'CidrBlock': '10.3.128.0/18',
'CidrBlockSet': [{'CidrBlock': '10.3.128.0/18'}],
'OwnerId': '99999',
'PeeringOptions': {
'AllowDnsResolutionFromRemoteVpc': False,
'AllowEgressFromLocalClassicLinkToRemoteVpc': False,
'AllowEgressFromLocalVpcToRemoteClassicLink': False,
},
'Region': 'us-west-2',
'VpcId': 'vpc-3',
},
'RequesterVpcInfo': {
'CidrBlock': '10.8.72.0/21',
'CidrBlockSet': [{'CidrBlock': '10.8.72.0/21'}],
'OwnerId': '123456789012',
'PeeringOptions': {
'AllowDnsResolutionFromRemoteVpc': False,
'AllowEgressFromLocalClassicLinkToRemoteVpc': False,
'AllowEgressFromLocalVpcToRemoteClassicLink': False,
},
'Region': 'us-west-2',
'VpcId': 'vpc-1',
},
'Status': {
'Code': 'active',
'Message': 'Active',
},
'Tags': [
{
'Key': 'foo',
'Value': 'bar',
},
],
'VpcPeeringConnectionId': 'pcx-2',
},
{
'AccepterVpcInfo': {
'CidrBlock': '10.3.128.0/18',
'CidrBlockSet': [{'CidrBlock': '10.3.128.0/18'}],
'OwnerId': '123456789012',
'PeeringOptions': {
'AllowDnsResolutionFromRemoteVpc': False,
'AllowEgressFromLocalClassicLinkToRemoteVpc': False,
'AllowEgressFromLocalVpcToRemoteClassicLink': False,
},
'Region': 'us-west-2',
'VpcId': 'vpc-4',
},
'RequesterVpcInfo': {
'CidrBlock': '10.8.72.0/21',
'CidrBlockSet': [{'CidrBlock': '10.8.72.0/21'}],
'OwnerId': '123456789012',
'PeeringOptions': {
'AllowDnsResolutionFromRemoteVpc': False,
'AllowEgressFromLocalClassicLinkToRemoteVpc': False,
'AllowEgressFromLocalVpcToRemoteClassicLink': False,
},
'Region': 'ap-south-1',
'VpcId': 'vpc-5',
},
'Status': {
'Code': 'active',
'Message': 'Active',
},
'Tags': [
{
'Key': 'out',
'Value': 'of ideas',
},
],
'VpcPeeringConnectionId': 'pcx-3',
},
]
}

test_find_usages_vpn_gateways = {
'VpnGateways': [
{
Expand Down
24 changes: 24 additions & 0 deletions awslimitchecker/tests/services/test_vpc.py
Original file line number Diff line number Diff line change
Expand Up @@ -334,6 +334,30 @@ def se_exc(*args, **kwargs):
exc_info=1)
]

def test_find_usage_peering_connections(self):
response = result_fixtures.VPC.test_find_usage_peering_connections

mock_conn = Mock()
mock_conn.describe_vpc_peering_connections.return_value = response
cls = _VpcService(21, 43, {}, None)
cls._current_account_id = '0123456789'
cls.conn = mock_conn

res = cls._find_usage_peering_connections()

usage = sorted(cls.limits['Active VPC peering connections per VPC'].get_current_usage())
print(usage)
assert len(usage) == 2
assert usage[0].resource_id == 'vpc-4'
assert usage[0].get_value() == 1
assert usage[1].resource_id == 'vpc-3'
assert usage[1].get_value() == 3
assert mock_conn.mock_calls == [
call.describe_subnets(Filters=[{
'Name': 'status-code', 'Values': ['active']
}])
]

def test_find_usages_vpn_gateways(self):
response = result_fixtures.VPC.test_find_usages_vpn_gateways

Expand Down
9 changes: 5 additions & 4 deletions docs/source/limits.rst
Original file line number Diff line number Diff line change
Expand Up @@ -777,9 +777,9 @@ Daily sending quota |check| 200
VPC
----

============================= =============== ======== ======= ====
Limit Trusted Advisor Quotas API Default
============================= =============== ======== ======= ====
===================================== =============== ======== ======= ====
Limit Trusted Advisor Quotas API Default
===================================== =============== ======== ======= ====
Entries per route table |check| 50
Internet gateways |check| 5
NAT Gateways per AZ |check| 5
Expand All @@ -788,9 +788,10 @@ Network interfaces per Region |check| 5000
Route tables per VPC |check| 200
Rules per network ACL |check| 20
Subnets per VPC |check| 200
Active VPC peering connections per VPC |check| 50
VPCs |check| 5
Virtual private gateways 5
============================= =============== ======== ======= ====
====================================== =============== ======== ======= ====



Expand Down