Techdebt: MyPy EC2 (r-models) (#5909)
This commit is contained in:
parent
749a8572ba
commit
2ee5dcea63
@ -220,7 +220,7 @@ class InvalidRouteTableIdError(EC2ClientError):
|
||||
|
||||
|
||||
class InvalidRouteError(EC2ClientError):
|
||||
def __init__(self, route_table_id, cidr):
|
||||
def __init__(self, route_table_id: str, cidr: str):
|
||||
super().__init__(
|
||||
"InvalidRoute.NotFound",
|
||||
f"no route with destination-cidr-block {cidr} in route table {route_table_id}",
|
||||
@ -228,7 +228,7 @@ class InvalidRouteError(EC2ClientError):
|
||||
|
||||
|
||||
class RouteAlreadyExistsError(EC2ClientError):
|
||||
def __init__(self, cidr):
|
||||
def __init__(self, cidr: str):
|
||||
super().__init__(
|
||||
"RouteAlreadyExists", f"The route identified by {cidr} already exists"
|
||||
)
|
||||
@ -593,7 +593,7 @@ class InvalidCIDRBlockParameterError(EC2ClientError):
|
||||
|
||||
|
||||
class InvalidDestinationCIDRBlockParameterError(EC2ClientError):
|
||||
def __init__(self, cidr_block):
|
||||
def __init__(self, cidr_block: str):
|
||||
super().__init__(
|
||||
"InvalidParameterValue",
|
||||
f"Value ({cidr_block}) for parameter destinationCidrBlock is invalid. This is not a valid CIDR block.",
|
||||
|
@ -28,7 +28,7 @@ from .instance_types import InstanceTypeBackend, InstanceTypeOfferingBackend
|
||||
from .nat_gateways import NatGatewayBackend
|
||||
from .network_acls import NetworkAclBackend
|
||||
from .availability_zones_and_regions import RegionsAndZonesBackend
|
||||
from .route_tables import RouteBackend, RouteTableBackend
|
||||
from .route_tables import RouteBackend
|
||||
from .security_groups import SecurityGroupBackend
|
||||
from .spot_requests import (
|
||||
SpotRequestBackend,
|
||||
@ -101,7 +101,6 @@ class EC2Backend(
|
||||
VPNConnectionBackend,
|
||||
VPCServiceConfigurationBackend,
|
||||
VPCPeeringConnectionBackend,
|
||||
RouteTableBackend,
|
||||
RouteBackend,
|
||||
InternetGatewayBackend,
|
||||
EgressOnlyInternetGatewayBackend,
|
||||
|
@ -1,6 +1,16 @@
|
||||
import ipaddress
|
||||
from typing import Any, Dict, List, Optional, Set
|
||||
|
||||
from moto.core import CloudFormationModel
|
||||
from moto.ec2.models.carrier_gateways import CarrierGateway
|
||||
from moto.ec2.models.elastic_network_interfaces import NetworkInterface
|
||||
from moto.ec2.models.internet_gateways import EgressOnlyInternetGateway
|
||||
from moto.ec2.models.instances import Instance
|
||||
from moto.ec2.models.managed_prefixes import ManagedPrefixList
|
||||
from moto.ec2.models.nat_gateways import NatGateway
|
||||
from moto.ec2.models.transit_gateway import TransitGateway
|
||||
from moto.ec2.models.vpc_peering_connections import VPCPeeringConnection
|
||||
from moto.ec2.models.vpn_gateway import VpnGateway
|
||||
from .core import TaggedEC2Resource
|
||||
from ..exceptions import (
|
||||
DependencyViolationError,
|
||||
@ -16,39 +26,42 @@ from ..utils import (
|
||||
generic_filter,
|
||||
random_subnet_association_id,
|
||||
random_route_table_id,
|
||||
split_route_id,
|
||||
)
|
||||
|
||||
|
||||
class RouteTable(TaggedEC2Resource, CloudFormationModel):
|
||||
def __init__(self, ec2_backend, route_table_id, vpc_id, main=False):
|
||||
def __init__(
|
||||
self, ec2_backend: Any, route_table_id: str, vpc_id: str, main: bool = False
|
||||
):
|
||||
self.ec2_backend = ec2_backend
|
||||
self.id = route_table_id
|
||||
self.vpc_id = vpc_id
|
||||
if main:
|
||||
self.main_association_id = random_subnet_association_id()
|
||||
else:
|
||||
self.main_association_id = None
|
||||
self.associations = {}
|
||||
self.routes = {}
|
||||
self.main_association_id = random_subnet_association_id() if main else None
|
||||
self.associations: Dict[str, str] = {}
|
||||
self.routes: Dict[str, Route] = {}
|
||||
|
||||
@property
|
||||
def owner_id(self):
|
||||
def owner_id(self) -> str:
|
||||
return self.ec2_backend.account_id
|
||||
|
||||
@staticmethod
|
||||
def cloudformation_name_type():
|
||||
return None
|
||||
def cloudformation_name_type() -> str:
|
||||
return ""
|
||||
|
||||
@staticmethod
|
||||
def cloudformation_type():
|
||||
def cloudformation_type() -> str:
|
||||
# https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-routetable.html
|
||||
return "AWS::EC2::RouteTable"
|
||||
|
||||
@classmethod
|
||||
def create_from_cloudformation_json(
|
||||
cls, resource_name, cloudformation_json, account_id, region_name, **kwargs
|
||||
):
|
||||
def create_from_cloudformation_json( # type: ignore[misc]
|
||||
cls,
|
||||
resource_name: str,
|
||||
cloudformation_json: Any,
|
||||
account_id: str,
|
||||
region_name: str,
|
||||
**kwargs: Any,
|
||||
) -> "RouteTable":
|
||||
from ..models import ec2_backends
|
||||
|
||||
properties = cloudformation_json["Properties"]
|
||||
@ -59,10 +72,12 @@ class RouteTable(TaggedEC2Resource, CloudFormationModel):
|
||||
return route_table
|
||||
|
||||
@property
|
||||
def physical_resource_id(self):
|
||||
def physical_resource_id(self) -> str:
|
||||
return self.id
|
||||
|
||||
def get_filter_value(self, filter_name):
|
||||
def get_filter_value(
|
||||
self, filter_name: str, method_name: Optional[str] = None
|
||||
) -> Any:
|
||||
if filter_name == "association.main":
|
||||
# Note: Boto only supports 'true'.
|
||||
# https://github.com/boto/boto/issues/1742
|
||||
@ -96,7 +111,7 @@ class RouteTable(TaggedEC2Resource, CloudFormationModel):
|
||||
return super().get_filter_value(filter_name, "DescribeRouteTables")
|
||||
|
||||
@property
|
||||
def all_associations_ids(self):
|
||||
def all_associations_ids(self) -> Set[str]:
|
||||
# NOTE(yoctozepto): Doing an explicit copy to not touch the original.
|
||||
all_associations = set(self.associations)
|
||||
if self.main_association_id is not None:
|
||||
@ -104,16 +119,108 @@ class RouteTable(TaggedEC2Resource, CloudFormationModel):
|
||||
return all_associations
|
||||
|
||||
|
||||
class RouteTableBackend:
|
||||
def __init__(self):
|
||||
self.route_tables = {}
|
||||
class Route(CloudFormationModel):
|
||||
def __init__(
|
||||
self,
|
||||
route_table: RouteTable,
|
||||
destination_cidr_block: Optional[str],
|
||||
destination_ipv6_cidr_block: Optional[str],
|
||||
destination_prefix_list: Optional[ManagedPrefixList] = None,
|
||||
local: bool = False,
|
||||
gateway: Optional[VpnGateway] = None,
|
||||
instance: Optional[Instance] = None,
|
||||
nat_gateway: Optional[NatGateway] = None,
|
||||
egress_only_igw: Optional[EgressOnlyInternetGateway] = None,
|
||||
transit_gateway: Optional[TransitGateway] = None,
|
||||
interface: Optional[NetworkInterface] = None,
|
||||
vpc_pcx: Optional[VPCPeeringConnection] = None,
|
||||
carrier_gateway: Optional[CarrierGateway] = None,
|
||||
):
|
||||
self.id = generate_route_id(
|
||||
route_table.id,
|
||||
destination_cidr_block,
|
||||
destination_ipv6_cidr_block,
|
||||
destination_prefix_list.id if destination_prefix_list else None,
|
||||
)
|
||||
self.route_table = route_table
|
||||
self.destination_cidr_block = destination_cidr_block
|
||||
self.destination_ipv6_cidr_block = destination_ipv6_cidr_block
|
||||
self.destination_prefix_list = destination_prefix_list
|
||||
self.local = local
|
||||
self.gateway = gateway
|
||||
self.instance = instance
|
||||
self.nat_gateway = nat_gateway
|
||||
self.egress_only_igw = egress_only_igw
|
||||
self.transit_gateway = transit_gateway
|
||||
self.interface = interface
|
||||
self.vpc_pcx = vpc_pcx
|
||||
self.carrier_gateway = carrier_gateway
|
||||
|
||||
def create_route_table(self, vpc_id, tags=None, main=False):
|
||||
@property
|
||||
def physical_resource_id(self) -> str:
|
||||
return self.id
|
||||
|
||||
@staticmethod
|
||||
def cloudformation_name_type() -> str:
|
||||
return ""
|
||||
|
||||
@staticmethod
|
||||
def cloudformation_type() -> str:
|
||||
# https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-route.html
|
||||
return "AWS::EC2::Route"
|
||||
|
||||
@classmethod
|
||||
def create_from_cloudformation_json( # type: ignore[misc]
|
||||
cls,
|
||||
resource_name: str,
|
||||
cloudformation_json: Any,
|
||||
account_id: str,
|
||||
region_name: str,
|
||||
**kwargs: str,
|
||||
) -> "Route":
|
||||
from ..models import ec2_backends
|
||||
|
||||
properties = cloudformation_json["Properties"]
|
||||
|
||||
gateway_id = properties.get("GatewayId")
|
||||
instance_id = properties.get("InstanceId")
|
||||
interface_id = properties.get("NetworkInterfaceId")
|
||||
nat_gateway_id = properties.get("NatGatewayId")
|
||||
egress_only_igw_id = properties.get("EgressOnlyInternetGatewayId")
|
||||
transit_gateway_id = properties.get("TransitGatewayId")
|
||||
pcx_id = properties.get("VpcPeeringConnectionId")
|
||||
|
||||
route_table_id = properties["RouteTableId"]
|
||||
ec2_backend = ec2_backends[account_id][region_name]
|
||||
route = ec2_backend.create_route(
|
||||
route_table_id=route_table_id,
|
||||
destination_cidr_block=properties.get("DestinationCidrBlock"),
|
||||
gateway_id=gateway_id,
|
||||
instance_id=instance_id,
|
||||
nat_gateway_id=nat_gateway_id,
|
||||
egress_only_igw_id=egress_only_igw_id,
|
||||
transit_gateway_id=transit_gateway_id,
|
||||
interface_id=interface_id,
|
||||
vpc_peering_connection_id=pcx_id,
|
||||
)
|
||||
return route
|
||||
|
||||
|
||||
class RouteBackend:
|
||||
def __init__(self) -> None:
|
||||
self.route_tables: Dict[str, RouteTable] = {}
|
||||
|
||||
def create_route_table(
|
||||
self,
|
||||
vpc_id: str,
|
||||
tags: Optional[List[Dict[str, str]]] = None,
|
||||
main: bool = False,
|
||||
) -> RouteTable:
|
||||
route_table_id = random_route_table_id()
|
||||
vpc = self.get_vpc(vpc_id) # Validate VPC exists
|
||||
vpc = self.get_vpc(vpc_id) # type: ignore[attr-defined] # Validate VPC exists
|
||||
route_table = RouteTable(self, route_table_id, vpc_id, main=main)
|
||||
for tag in tags or []:
|
||||
route_table.add_tag(tag.get("Key"), tag.get("Value"))
|
||||
route_table.add_tag(tag["Key"], tag["Value"])
|
||||
self.route_tables[route_table_id] = route_table
|
||||
|
||||
# creating default routes for ipv4 cirds
|
||||
@ -133,14 +240,16 @@ class RouteTableBackend:
|
||||
|
||||
return route_table
|
||||
|
||||
def get_route_table(self, route_table_id):
|
||||
def get_route_table(self, route_table_id: str) -> RouteTable:
|
||||
route_table = self.route_tables.get(route_table_id, None)
|
||||
if not route_table:
|
||||
raise InvalidRouteTableIdError(route_table_id)
|
||||
return route_table
|
||||
|
||||
def describe_route_tables(self, route_table_ids=None, filters=None):
|
||||
route_tables = self.route_tables.copy().values()
|
||||
def describe_route_tables(
|
||||
self, route_table_ids: Optional[List[str]] = None, filters: Any = None
|
||||
) -> List[RouteTable]:
|
||||
route_tables = list(self.route_tables.values())
|
||||
|
||||
if route_table_ids:
|
||||
route_tables = [
|
||||
@ -158,16 +267,20 @@ class RouteTableBackend:
|
||||
|
||||
return generic_filter(filters, route_tables)
|
||||
|
||||
def delete_route_table(self, route_table_id):
|
||||
def delete_route_table(self, route_table_id: str) -> None:
|
||||
route_table = self.get_route_table(route_table_id)
|
||||
if route_table.associations:
|
||||
raise DependencyViolationError(
|
||||
f"The routeTable '{route_table_id}' has dependencies and cannot be deleted."
|
||||
)
|
||||
self.route_tables.pop(route_table_id)
|
||||
return True
|
||||
|
||||
def associate_route_table(self, route_table_id, gateway_id=None, subnet_id=None):
|
||||
def associate_route_table(
|
||||
self,
|
||||
route_table_id: str,
|
||||
gateway_id: Optional[str] = None,
|
||||
subnet_id: Optional[str] = None,
|
||||
) -> str:
|
||||
# Idempotent if association already exists.
|
||||
route_tables_by_subnet = self.describe_route_tables(
|
||||
filters={"association.subnet-id": [subnet_id]}
|
||||
@ -182,22 +295,24 @@ class RouteTableBackend:
|
||||
# Association does not yet exist, so create it.
|
||||
route_table = self.get_route_table(route_table_id)
|
||||
if gateway_id is None:
|
||||
self.get_subnet(subnet_id) # Validate subnet exists
|
||||
self.get_subnet(subnet_id) # type: ignore[attr-defined] # Validate subnet exists
|
||||
association_id = random_subnet_association_id()
|
||||
route_table.associations[association_id] = subnet_id
|
||||
route_table.associations[association_id] = subnet_id # type: ignore[assignment]
|
||||
return association_id
|
||||
if subnet_id is None:
|
||||
else:
|
||||
association_id = random_subnet_association_id()
|
||||
route_table.associations[association_id] = gateway_id
|
||||
return association_id
|
||||
|
||||
def disassociate_route_table(self, association_id):
|
||||
def disassociate_route_table(self, association_id: str) -> Optional[str]:
|
||||
for route_table in self.route_tables.values():
|
||||
if association_id in route_table.associations:
|
||||
return route_table.associations.pop(association_id, None)
|
||||
raise InvalidAssociationIdError(association_id)
|
||||
|
||||
def replace_route_table_association(self, association_id, route_table_id):
|
||||
def replace_route_table_association(
|
||||
self, association_id: str, route_table_id: str
|
||||
) -> str:
|
||||
# Idempotent if association already exists.
|
||||
new_route_table = self.get_route_table(route_table_id)
|
||||
if association_id in new_route_table.all_associations_ids:
|
||||
@ -223,107 +338,22 @@ class RouteTableBackend:
|
||||
new_route_table.associations[new_association_id] = association_target_id
|
||||
return new_association_id
|
||||
|
||||
|
||||
# TODO: refractor to isloate class methods from backend logic
|
||||
class Route(CloudFormationModel):
|
||||
def __init__(
|
||||
self,
|
||||
route_table,
|
||||
destination_cidr_block,
|
||||
destination_ipv6_cidr_block,
|
||||
destination_prefix_list=None,
|
||||
local=False,
|
||||
gateway=None,
|
||||
instance=None,
|
||||
nat_gateway=None,
|
||||
egress_only_igw=None,
|
||||
transit_gateway=None,
|
||||
interface=None,
|
||||
vpc_pcx=None,
|
||||
carrier_gateway=None,
|
||||
):
|
||||
self.id = generate_route_id(
|
||||
route_table.id,
|
||||
destination_cidr_block,
|
||||
destination_ipv6_cidr_block,
|
||||
destination_prefix_list.id if destination_prefix_list else None,
|
||||
)
|
||||
self.route_table = route_table
|
||||
self.destination_cidr_block = destination_cidr_block
|
||||
self.destination_ipv6_cidr_block = destination_ipv6_cidr_block
|
||||
self.destination_prefix_list = destination_prefix_list
|
||||
self.local = local
|
||||
self.gateway = gateway
|
||||
self.instance = instance
|
||||
self.nat_gateway = nat_gateway
|
||||
self.egress_only_igw = egress_only_igw
|
||||
self.transit_gateway = transit_gateway
|
||||
self.interface = interface
|
||||
self.vpc_pcx = vpc_pcx
|
||||
self.carrier_gateway = carrier_gateway
|
||||
|
||||
@property
|
||||
def physical_resource_id(self):
|
||||
return self.id
|
||||
|
||||
@staticmethod
|
||||
def cloudformation_name_type():
|
||||
return None
|
||||
|
||||
@staticmethod
|
||||
def cloudformation_type():
|
||||
# https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-route.html
|
||||
return "AWS::EC2::Route"
|
||||
|
||||
@classmethod
|
||||
def create_from_cloudformation_json(
|
||||
cls, resource_name, cloudformation_json, account_id, region_name, **kwargs
|
||||
):
|
||||
from ..models import ec2_backends
|
||||
|
||||
properties = cloudformation_json["Properties"]
|
||||
|
||||
gateway_id = properties.get("GatewayId")
|
||||
instance_id = properties.get("InstanceId")
|
||||
interface_id = properties.get("NetworkInterfaceId")
|
||||
nat_gateway_id = properties.get("NatGatewayId")
|
||||
egress_only_igw_id = properties.get("EgressOnlyInternetGatewayId")
|
||||
transit_gateway_id = properties.get("TransitGatewayId")
|
||||
pcx_id = properties.get("VpcPeeringConnectionId")
|
||||
|
||||
route_table_id = properties["RouteTableId"]
|
||||
ec2_backend = ec2_backends[account_id][region_name]
|
||||
route_table = ec2_backend.create_route(
|
||||
route_table_id=route_table_id,
|
||||
destination_cidr_block=properties.get("DestinationCidrBlock"),
|
||||
gateway_id=gateway_id,
|
||||
instance_id=instance_id,
|
||||
nat_gateway_id=nat_gateway_id,
|
||||
egress_only_igw_id=egress_only_igw_id,
|
||||
transit_gateway_id=transit_gateway_id,
|
||||
interface_id=interface_id,
|
||||
vpc_peering_connection_id=pcx_id,
|
||||
)
|
||||
return route_table
|
||||
|
||||
|
||||
class RouteBackend:
|
||||
def create_route(
|
||||
self,
|
||||
route_table_id,
|
||||
destination_cidr_block,
|
||||
destination_ipv6_cidr_block=None,
|
||||
destination_prefix_list_id=None,
|
||||
local=False,
|
||||
gateway_id=None,
|
||||
instance_id=None,
|
||||
nat_gateway_id=None,
|
||||
egress_only_igw_id=None,
|
||||
transit_gateway_id=None,
|
||||
interface_id=None,
|
||||
vpc_peering_connection_id=None,
|
||||
carrier_gateway_id=None,
|
||||
):
|
||||
route_table_id: str,
|
||||
destination_cidr_block: Optional[str],
|
||||
destination_ipv6_cidr_block: Optional[str] = None,
|
||||
destination_prefix_list_id: Optional[str] = None,
|
||||
local: bool = False,
|
||||
gateway_id: Optional[str] = None,
|
||||
instance_id: Optional[str] = None,
|
||||
nat_gateway_id: Optional[str] = None,
|
||||
egress_only_igw_id: Optional[str] = None,
|
||||
transit_gateway_id: Optional[str] = None,
|
||||
interface_id: Optional[str] = None,
|
||||
vpc_peering_connection_id: Optional[str] = None,
|
||||
carrier_gateway_id: Optional[str] = None,
|
||||
) -> Route:
|
||||
gateway = None
|
||||
nat_gateway = None
|
||||
transit_gateway = None
|
||||
@ -336,16 +366,16 @@ class RouteBackend:
|
||||
|
||||
if interface_id:
|
||||
# for validating interface Id whether it is valid or not.
|
||||
interface = self.get_network_interface(interface_id)
|
||||
interface = self.get_network_interface(interface_id) # type: ignore[attr-defined]
|
||||
|
||||
else:
|
||||
if gateway_id:
|
||||
if EC2_RESOURCE_TO_PREFIX["vpn-gateway"] in gateway_id:
|
||||
gateway = self.get_vpn_gateway(gateway_id)
|
||||
gateway = self.get_vpn_gateway(gateway_id) # type: ignore[attr-defined]
|
||||
elif EC2_RESOURCE_TO_PREFIX["internet-gateway"] in gateway_id:
|
||||
gateway = self.get_internet_gateway(gateway_id)
|
||||
gateway = self.get_internet_gateway(gateway_id) # type: ignore[attr-defined]
|
||||
elif EC2_RESOURCE_TO_PREFIX["vpc-endpoint"] in gateway_id:
|
||||
gateway = self.get_vpc_end_point(gateway_id)
|
||||
gateway = self.get_vpc_end_point(gateway_id) # type: ignore[attr-defined]
|
||||
|
||||
if destination_cidr_block:
|
||||
self.__validate_destination_cidr_block(
|
||||
@ -353,17 +383,17 @@ class RouteBackend:
|
||||
)
|
||||
|
||||
if nat_gateway_id is not None:
|
||||
nat_gateway = self.nat_gateways.get(nat_gateway_id)
|
||||
nat_gateway = self.nat_gateways.get(nat_gateway_id) # type: ignore[attr-defined]
|
||||
if egress_only_igw_id is not None:
|
||||
egress_only_igw = self.get_egress_only_igw(egress_only_igw_id)
|
||||
egress_only_igw = self.get_egress_only_igw(egress_only_igw_id) # type: ignore[attr-defined]
|
||||
if transit_gateway_id is not None:
|
||||
transit_gateway = self.transit_gateways.get(transit_gateway_id)
|
||||
transit_gateway = self.transit_gateways.get(transit_gateway_id) # type: ignore[attr-defined]
|
||||
if destination_prefix_list_id is not None:
|
||||
destination_prefix_list = self.managed_prefix_lists.get(
|
||||
destination_prefix_list = self.managed_prefix_lists.get( # type: ignore[attr-defined]
|
||||
destination_prefix_list_id
|
||||
)
|
||||
if carrier_gateway_id is not None:
|
||||
carrier_gateway = self.carrier_gateways.get(carrier_gateway_id)
|
||||
carrier_gateway = self.carrier_gateways.get(carrier_gateway_id) # type: ignore[attr-defined]
|
||||
|
||||
route = Route(
|
||||
route_table,
|
||||
@ -372,13 +402,13 @@ class RouteBackend:
|
||||
destination_prefix_list,
|
||||
local=local,
|
||||
gateway=gateway,
|
||||
instance=self.get_instance(instance_id) if instance_id else None,
|
||||
instance=self.get_instance(instance_id) if instance_id else None, # type: ignore[attr-defined]
|
||||
nat_gateway=nat_gateway,
|
||||
egress_only_igw=egress_only_igw,
|
||||
transit_gateway=transit_gateway,
|
||||
interface=interface,
|
||||
carrier_gateway=carrier_gateway,
|
||||
vpc_pcx=self.get_vpc_peering_connection(vpc_peering_connection_id)
|
||||
vpc_pcx=self.get_vpc_peering_connection(vpc_peering_connection_id) # type: ignore[attr-defined]
|
||||
if vpc_peering_connection_id
|
||||
else None,
|
||||
)
|
||||
@ -387,18 +417,18 @@ class RouteBackend:
|
||||
|
||||
def replace_route(
|
||||
self,
|
||||
route_table_id,
|
||||
destination_cidr_block,
|
||||
destination_ipv6_cidr_block=None,
|
||||
destination_prefix_list_id=None,
|
||||
nat_gateway_id=None,
|
||||
egress_only_igw_id=None,
|
||||
transit_gateway_id=None,
|
||||
gateway_id=None,
|
||||
instance_id=None,
|
||||
interface_id=None,
|
||||
vpc_peering_connection_id=None,
|
||||
):
|
||||
route_table_id: str,
|
||||
destination_cidr_block: str,
|
||||
destination_ipv6_cidr_block: Optional[str] = None,
|
||||
destination_prefix_list_id: Optional[str] = None,
|
||||
nat_gateway_id: Optional[str] = None,
|
||||
egress_only_igw_id: Optional[str] = None,
|
||||
transit_gateway_id: Optional[str] = None,
|
||||
gateway_id: Optional[str] = None,
|
||||
instance_id: Optional[str] = None,
|
||||
interface_id: Optional[str] = None,
|
||||
vpc_peering_connection_id: Optional[str] = None,
|
||||
) -> Route:
|
||||
route_table = self.get_route_table(route_table_id)
|
||||
route_id = generate_route_id(
|
||||
route_table.id, destination_cidr_block, destination_ipv6_cidr_block
|
||||
@ -406,7 +436,7 @@ class RouteBackend:
|
||||
route = route_table.routes[route_id]
|
||||
|
||||
if interface_id:
|
||||
self.raise_not_implemented_error("ReplaceRoute to NetworkInterfaceId")
|
||||
self.raise_not_implemented_error("ReplaceRoute to NetworkInterfaceId") # type: ignore[attr-defined]
|
||||
|
||||
route.gateway = None
|
||||
route.nat_gateway = None
|
||||
@ -414,25 +444,25 @@ class RouteBackend:
|
||||
route.transit_gateway = None
|
||||
if gateway_id:
|
||||
if EC2_RESOURCE_TO_PREFIX["vpn-gateway"] in gateway_id:
|
||||
route.gateway = self.get_vpn_gateway(gateway_id)
|
||||
route.gateway = self.get_vpn_gateway(gateway_id) # type: ignore[attr-defined]
|
||||
elif EC2_RESOURCE_TO_PREFIX["internet-gateway"] in gateway_id:
|
||||
route.gateway = self.get_internet_gateway(gateway_id)
|
||||
route.gateway = self.get_internet_gateway(gateway_id) # type: ignore[attr-defined]
|
||||
|
||||
if nat_gateway_id is not None:
|
||||
route.nat_gateway = self.nat_gateways.get(nat_gateway_id)
|
||||
route.nat_gateway = self.nat_gateways.get(nat_gateway_id) # type: ignore[attr-defined]
|
||||
if egress_only_igw_id is not None:
|
||||
route.egress_only_igw = self.get_egress_only_igw(egress_only_igw_id)
|
||||
route.egress_only_igw = self.get_egress_only_igw(egress_only_igw_id) # type: ignore[attr-defined]
|
||||
if transit_gateway_id is not None:
|
||||
route.transit_gateway = self.transit_gateways.get(transit_gateway_id)
|
||||
route.transit_gateway = self.transit_gateways.get(transit_gateway_id) # type: ignore[attr-defined]
|
||||
if destination_prefix_list_id is not None:
|
||||
route.prefix_list = self.managed_prefix_lists.get(
|
||||
route.prefix_list = self.managed_prefix_lists.get( # type: ignore[attr-defined]
|
||||
destination_prefix_list_id
|
||||
)
|
||||
|
||||
route.instance = self.get_instance(instance_id) if instance_id else None
|
||||
route.instance = self.get_instance(instance_id) if instance_id else None # type: ignore[attr-defined]
|
||||
route.interface = None
|
||||
route.vpc_pcx = (
|
||||
self.get_vpc_peering_connection(vpc_peering_connection_id)
|
||||
self.get_vpc_peering_connection(vpc_peering_connection_id) # type: ignore[attr-defined]
|
||||
if vpc_peering_connection_id
|
||||
else None
|
||||
)
|
||||
@ -440,18 +470,13 @@ class RouteBackend:
|
||||
route_table.routes[route.id] = route
|
||||
return route
|
||||
|
||||
def get_route(self, route_id):
|
||||
route_table_id, _ = split_route_id(route_id)
|
||||
route_table = self.get_route_table(route_table_id)
|
||||
return route_table.get(route_id)
|
||||
|
||||
def delete_route(
|
||||
self,
|
||||
route_table_id,
|
||||
destination_cidr_block,
|
||||
destination_ipv6_cidr_block=None,
|
||||
destination_prefix_list_id=None,
|
||||
):
|
||||
route_table_id: str,
|
||||
destination_cidr_block: str,
|
||||
destination_ipv6_cidr_block: Optional[str] = None,
|
||||
destination_prefix_list_id: Optional[str] = None,
|
||||
) -> Route:
|
||||
cidr = destination_cidr_block
|
||||
route_table = self.get_route_table(route_table_id)
|
||||
if destination_ipv6_cidr_block:
|
||||
@ -464,7 +489,9 @@ class RouteBackend:
|
||||
raise InvalidRouteError(route_table_id, cidr)
|
||||
return deleted
|
||||
|
||||
def __validate_destination_cidr_block(self, destination_cidr_block, route_table):
|
||||
def __validate_destination_cidr_block(
|
||||
self, destination_cidr_block: str, route_table: RouteTable
|
||||
) -> None:
|
||||
"""
|
||||
Utility function to check the destination CIDR block
|
||||
Will validate the format and check for overlap with existing routes
|
||||
|
@ -7,7 +7,7 @@ from datetime import datetime
|
||||
from cryptography.hazmat.primitives import serialization
|
||||
from cryptography.hazmat.backends import default_backend
|
||||
from cryptography.hazmat.primitives.asymmetric import rsa
|
||||
from typing import Any, Dict, List, TypeVar, Optional
|
||||
from typing import Any, Dict, List, TypeVar, Tuple, Optional
|
||||
|
||||
from moto.iam import iam_backends
|
||||
from moto.moto_api._internal import mock_random as random
|
||||
@ -122,7 +122,7 @@ def random_subnet_ipv6_cidr_block_association_id():
|
||||
)
|
||||
|
||||
|
||||
def random_subnet_association_id():
|
||||
def random_subnet_association_id() -> str:
|
||||
return random_id(prefix=EC2_RESOURCE_TO_PREFIX["route-table-association"])
|
||||
|
||||
|
||||
@ -184,7 +184,7 @@ def random_egress_only_internet_gateway_id() -> str:
|
||||
)
|
||||
|
||||
|
||||
def random_route_table_id():
|
||||
def random_route_table_id() -> str:
|
||||
return random_id(prefix=EC2_RESOURCE_TO_PREFIX["route-table"])
|
||||
|
||||
|
||||
@ -281,7 +281,10 @@ def random_ipv6_cidr():
|
||||
|
||||
|
||||
def generate_route_id(
|
||||
route_table_id, cidr_block, ipv6_cidr_block=None, prefix_list=None
|
||||
route_table_id: str,
|
||||
cidr_block: Optional[str],
|
||||
ipv6_cidr_block: Optional[str] = None,
|
||||
prefix_list: Optional[str] = None,
|
||||
):
|
||||
if ipv6_cidr_block and not cidr_block:
|
||||
cidr_block = ipv6_cidr_block
|
||||
@ -309,7 +312,7 @@ def utc_date_and_time() -> str:
|
||||
return f"{x.year}-{x.month:02d}-{x.day:02d}T{x.hour:02d}:{x.minute:02d}:{x.second:02d}.000Z"
|
||||
|
||||
|
||||
def split_route_id(route_id):
|
||||
def split_route_id(route_id: str) -> Tuple[str, str]:
|
||||
values = route_id.split("~")
|
||||
return values[0], values[1]
|
||||
|
||||
|
@ -229,7 +229,7 @@ disable = W,C,R,E
|
||||
enable = anomalous-backslash-in-string, arguments-renamed, dangerous-default-value, deprecated-module, function-redefined, import-self, redefined-builtin, redefined-outer-name, reimported, pointless-statement, super-with-arguments, unused-argument, unused-import, unused-variable, useless-else-on-loop, wildcard-import
|
||||
|
||||
[mypy]
|
||||
files= moto/a*,moto/b*,moto/c*,moto/d*,moto/ebs/,moto/ec2/models/a*,moto/ec2/models/c*,moto/ec2/models/d*,moto/ec2/models/e*,moto/ec2/models/f*,moto/ec2/models/h*,moto/ec2/models/i*,moto/ec2/models/k*,moto/ec2/models/l*,moto/ec2/models/m*,moto/ec2/models/n*,moto/moto_api
|
||||
files= moto/a*,moto/b*,moto/c*,moto/d*,moto/ebs/,moto/ec2/models/a*,moto/ec2/models/c*,moto/ec2/models/d*,moto/ec2/models/e*,moto/ec2/models/f*,moto/ec2/models/h*,moto/ec2/models/i*,moto/ec2/models/k*,moto/ec2/models/l*,moto/ec2/models/m*,moto/ec2/models/n*,moto/ec2/models/r*,moto/moto_api
|
||||
show_column_numbers=True
|
||||
show_error_codes = True
|
||||
disable_error_code=abstract
|
||||
|
Loading…
Reference in New Issue
Block a user