From 5fe3a707ed14842567e0e74bc86e95048f57f893 Mon Sep 17 00:00:00 2001 From: tony-dot-sh <11530086+tony-dot-sh@users.noreply.github.com> Date: Tue, 16 Mar 2021 08:15:58 -0600 Subject: [PATCH] fix route table association by internet gateway (#3773) * fix route table association by internet gateway per https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_AssociateRouteTable.html * Route53 - Add test for route table association by internet gateway - Minor test tweak for Main route table values TODO: explicitly set the route table main route association * Route53 - forgot subnet id association test Co-authored-by: Tony Greising-Murschel --- moto/ec2/models.py | 15 +++++++---- moto/ec2/responses/route_tables.py | 5 ++-- tests/test_ec2/test_route_tables.py | 42 ++++++++++++++++++++++++++--- 3 files changed, 52 insertions(+), 10 deletions(-) diff --git a/moto/ec2/models.py b/moto/ec2/models.py index bfb366d67..7e59321ff 100644 --- a/moto/ec2/models.py +++ b/moto/ec2/models.py @@ -4179,7 +4179,7 @@ class RouteTableBackend(object): self.route_tables.pop(route_table_id) return True - def associate_route_table(self, route_table_id, subnet_id): + def associate_route_table(self, route_table_id, gateway_id=None, subnet_id=None): # Idempotent if association already exists. route_tables_by_subnet = self.get_all_route_tables( filters={"association.subnet-id": [subnet_id]} @@ -4193,10 +4193,15 @@ class RouteTableBackend(object): # Association does not yet exist, so create it. route_table = self.get_route_table(route_table_id) - self.get_subnet(subnet_id) # Validate subnet exists - association_id = random_subnet_association_id() - route_table.associations[association_id] = subnet_id - return association_id + if gateway_id is None: + self.get_subnet(subnet_id) # Validate subnet exists + association_id = random_subnet_association_id() + route_table.associations[association_id] = subnet_id + return association_id + if subnet_id is None: + association_id = random_subnet_association_id() + route_table.associations[association_id] = gateway_id + return association_id def disassociate_route_table(self, association_id): for route_table in self.route_tables.values(): diff --git a/moto/ec2/responses/route_tables.py b/moto/ec2/responses/route_tables.py index c929ffb9e..197b01300 100644 --- a/moto/ec2/responses/route_tables.py +++ b/moto/ec2/responses/route_tables.py @@ -6,9 +6,10 @@ from moto.ec2.utils import filters_from_querystring class RouteTables(BaseResponse): def associate_route_table(self): route_table_id = self._get_param("RouteTableId") + gateway_id = self._get_param("GatewayId") subnet_id = self._get_param("SubnetId") association_id = self.ec2_backend.associate_route_table( - route_table_id, subnet_id + route_table_id, gateway_id, subnet_id ) template = self.response_template(ASSOCIATE_ROUTE_TABLE_RESPONSE) return template.render(association_id=association_id) @@ -192,7 +193,7 @@ DESCRIBE_ROUTE_TABLES_RESPONSE = """ {{ association_id }} {{ route_table.id }} -
false
+
true
{{ subnet_id }}
{% endfor %} diff --git a/tests/test_ec2/test_route_tables.py b/tests/test_ec2/test_route_tables.py index 697fedd76..f981ea224 100644 --- a/tests/test_ec2/test_route_tables.py +++ b/tests/test_ec2/test_route_tables.py @@ -187,7 +187,7 @@ def test_route_table_associations(): route_table.associations.should.have.length_of(1) route_table.associations[0].id.should.equal(association_id) - route_table.associations[0].main.should.equal(False) + route_table.associations[0].main.should.equal(True) route_table.associations[0].route_table_id.should.equal(route_table.id) route_table.associations[0].subnet_id.should.equal(subnet.id) @@ -263,7 +263,7 @@ def test_route_table_replace_route_table_association(): route_table2.associations.should.have.length_of(0) route_table1.associations[0].id.should.equal(association_id1) - route_table1.associations[0].main.should.equal(False) + route_table1.associations[0].main.should.equal(True) route_table1.associations[0].route_table_id.should.equal(route_table1.id) route_table1.associations[0].subnet_id.should.equal(subnet.id) @@ -281,7 +281,7 @@ def test_route_table_replace_route_table_association(): route_table2.associations.should.have.length_of(1) route_table2.associations[0].id.should.equal(association_id2) - route_table2.associations[0].main.should.equal(False) + route_table2.associations[0].main.should.equal(True) route_table2.associations[0].route_table_id.should.equal(route_table2.id) route_table2.associations[0].subnet_id.should.equal(subnet.id) @@ -733,3 +733,39 @@ def test_create_route_tables_with_tags(): ) route_table.tags.should.have.length_of(1) + + +@mock_ec2 +def test_associate_route_table_by_gateway(): + ec2 = boto3.client("ec2", region_name="us-west-1") + vpc_id = ec2.create_vpc(CidrBlock="10.0.0.0/16")["Vpc"]["VpcId"] + route_table_id = ec2.create_route_table(VpcId=vpc_id)["RouteTable"]["RouteTableId"] + igw_id = ec2.create_internet_gateway()["InternetGateway"]["InternetGatewayId"] + assoc_id = ec2.associate_route_table( + RouteTableId=route_table_id, GatewayId=igw_id, + )["AssociationId"] + verify = ec2.describe_route_tables( + Filters=[ + {"Name": "association.route-table-association-id", "Values": [assoc_id]} + ] + )["RouteTables"] + verify[0]["Associations"][0]["RouteTableAssociationId"].should.equal(assoc_id) + + +@mock_ec2 +def test_associate_route_table_by_subnet(): + ec2 = boto3.client("ec2", region_name="us-west-1") + vpc_id = ec2.create_vpc(CidrBlock="10.0.0.0/16")["Vpc"]["VpcId"] + route_table_id = ec2.create_route_table(VpcId=vpc_id)["RouteTable"]["RouteTableId"] + subnet_id = ec2.create_subnet(VpcId=vpc_id, CidrBlock="10.0.0.0/24")["Subnet"][ + "SubnetId" + ] + assoc_id = ec2.associate_route_table( + RouteTableId=route_table_id, SubnetId=subnet_id, + )["AssociationId"] + verify = ec2.describe_route_tables( + Filters=[ + {"Name": "association.route-table-association-id", "Values": [assoc_id]} + ] + )["RouteTables"] + verify[0]["Associations"][0]["RouteTableAssociationId"].should.equal(assoc_id)