182 lines
6.1 KiB
Python
182 lines
6.1 KiB
Python
from typing import Any, Dict, List, Optional
|
|
|
|
from moto.core.common_models import CloudFormationModel
|
|
|
|
from ..exceptions import (
|
|
DependencyViolationError,
|
|
GatewayNotAttachedError,
|
|
InvalidGatewayIDError,
|
|
InvalidInternetGatewayIdError,
|
|
InvalidVPCIdError,
|
|
ResourceAlreadyAssociatedError,
|
|
)
|
|
from ..utils import (
|
|
filter_internet_gateways,
|
|
random_egress_only_internet_gateway_id,
|
|
random_internet_gateway_id,
|
|
)
|
|
from .core import TaggedEC2Resource
|
|
from .vpn_gateway import VPCGatewayAttachment
|
|
|
|
|
|
class EgressOnlyInternetGateway(TaggedEC2Resource):
|
|
def __init__(
|
|
self, ec2_backend: Any, vpc_id: str, tags: Optional[Dict[str, str]] = None
|
|
):
|
|
self.id = random_egress_only_internet_gateway_id()
|
|
self.ec2_backend = ec2_backend
|
|
self.vpc_id = vpc_id
|
|
self.state = "attached"
|
|
self.add_tags(tags or {})
|
|
|
|
@property
|
|
def physical_resource_id(self) -> str:
|
|
return self.id
|
|
|
|
|
|
class EgressOnlyInternetGatewayBackend:
|
|
def __init__(self) -> None:
|
|
self.egress_only_internet_gateways: Dict[str, EgressOnlyInternetGateway] = {}
|
|
|
|
def create_egress_only_internet_gateway(
|
|
self, vpc_id: str, tags: Optional[Dict[str, str]] = None
|
|
) -> EgressOnlyInternetGateway:
|
|
vpc = self.get_vpc(vpc_id) # type: ignore[attr-defined]
|
|
if not vpc:
|
|
raise InvalidVPCIdError(vpc_id)
|
|
egress_only_igw = EgressOnlyInternetGateway(self, vpc_id, tags)
|
|
self.egress_only_internet_gateways[egress_only_igw.id] = egress_only_igw
|
|
return egress_only_igw
|
|
|
|
def describe_egress_only_internet_gateways(
|
|
self, ids: Optional[List[str]] = None
|
|
) -> List[EgressOnlyInternetGateway]:
|
|
"""
|
|
The Filters-argument is not yet supported
|
|
"""
|
|
egress_only_igws = list(self.egress_only_internet_gateways.values())
|
|
|
|
if ids:
|
|
egress_only_igws = [
|
|
egress_only_igw
|
|
for egress_only_igw in egress_only_igws
|
|
if egress_only_igw.id in ids
|
|
]
|
|
return egress_only_igws
|
|
|
|
def delete_egress_only_internet_gateway(self, gateway_id: str) -> None:
|
|
egress_only_igw = self.egress_only_internet_gateways.get(gateway_id)
|
|
if not egress_only_igw:
|
|
raise InvalidGatewayIDError(gateway_id)
|
|
if egress_only_igw:
|
|
self.egress_only_internet_gateways.pop(gateway_id)
|
|
|
|
def get_egress_only_igw(self, gateway_id: str) -> EgressOnlyInternetGateway:
|
|
igw = self.egress_only_internet_gateways.get(gateway_id)
|
|
if not igw:
|
|
raise InvalidGatewayIDError(gateway_id)
|
|
return igw
|
|
|
|
|
|
class InternetGateway(TaggedEC2Resource, CloudFormationModel):
|
|
def __init__(self, ec2_backend: Any):
|
|
self.ec2_backend = ec2_backend
|
|
self.id = random_internet_gateway_id()
|
|
self.vpc = None
|
|
|
|
@property
|
|
def owner_id(self) -> str:
|
|
return self.ec2_backend.account_id
|
|
|
|
@staticmethod
|
|
def cloudformation_name_type() -> str:
|
|
return ""
|
|
|
|
@staticmethod
|
|
def cloudformation_type() -> str:
|
|
# https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-internetgateway.html
|
|
return "AWS::EC2::InternetGateway"
|
|
|
|
@classmethod
|
|
def create_from_cloudformation_json( # type: ignore[misc]
|
|
cls,
|
|
resource_name: str,
|
|
cloudformation_json: Any,
|
|
account_id: str,
|
|
region_name: str,
|
|
**kwargs: Any,
|
|
) -> "InternetGateway":
|
|
from ..models import ec2_backends
|
|
|
|
ec2_backend = ec2_backends[account_id][region_name]
|
|
return ec2_backend.create_internet_gateway()
|
|
|
|
@property
|
|
def physical_resource_id(self) -> str:
|
|
return self.id
|
|
|
|
@property
|
|
def attachment_state(self) -> str:
|
|
if self.vpc:
|
|
return "available"
|
|
else:
|
|
return "detached"
|
|
|
|
|
|
class InternetGatewayBackend:
|
|
def __init__(self) -> None:
|
|
self.internet_gateways: Dict[str, InternetGateway] = {}
|
|
|
|
def create_internet_gateway(
|
|
self, tags: Optional[List[Dict[str, str]]] = None
|
|
) -> InternetGateway:
|
|
igw = InternetGateway(self)
|
|
for tag in tags or []:
|
|
igw.add_tag(tag["Key"], tag["Value"])
|
|
self.internet_gateways[igw.id] = igw
|
|
return igw
|
|
|
|
def describe_internet_gateways(
|
|
self, internet_gateway_ids: Optional[List[str]] = None, filters: Any = None
|
|
) -> List[InternetGateway]:
|
|
igws = []
|
|
if internet_gateway_ids is None:
|
|
igws = list(self.internet_gateways.values())
|
|
else:
|
|
for igw_id in internet_gateway_ids:
|
|
if igw_id in self.internet_gateways:
|
|
igws.append(self.internet_gateways[igw_id])
|
|
else:
|
|
raise InvalidInternetGatewayIdError(igw_id)
|
|
if filters is not None:
|
|
igws = filter_internet_gateways(igws, filters)
|
|
return igws
|
|
|
|
def delete_internet_gateway(self, internet_gateway_id: str) -> None:
|
|
igw = self.get_internet_gateway(internet_gateway_id)
|
|
if igw.vpc:
|
|
raise DependencyViolationError(
|
|
f"{internet_gateway_id} is being utilized by {igw.vpc.id}"
|
|
)
|
|
self.internet_gateways.pop(internet_gateway_id)
|
|
|
|
def detach_internet_gateway(self, internet_gateway_id: str, vpc_id: str) -> None:
|
|
igw = self.get_internet_gateway(internet_gateway_id)
|
|
if not igw.vpc or igw.vpc.id != vpc_id:
|
|
raise GatewayNotAttachedError(internet_gateway_id, vpc_id)
|
|
igw.vpc = None
|
|
|
|
def attach_internet_gateway(
|
|
self, internet_gateway_id: str, vpc_id: str
|
|
) -> VPCGatewayAttachment:
|
|
igw = self.get_internet_gateway(internet_gateway_id)
|
|
if igw.vpc:
|
|
raise ResourceAlreadyAssociatedError(internet_gateway_id)
|
|
vpc = self.get_vpc(vpc_id) # type: ignore[attr-defined]
|
|
igw.vpc = vpc
|
|
return VPCGatewayAttachment(gateway_id=internet_gateway_id, vpc_id=vpc_id)
|
|
|
|
def get_internet_gateway(self, internet_gateway_id: str) -> InternetGateway:
|
|
igw_ids = [internet_gateway_id]
|
|
return self.describe_internet_gateways(internet_gateway_ids=igw_ids)[0]
|