added support for egress-only-internet-gateway (#4196)
This commit is contained in:
parent
b4f02f3436
commit
a93756c69a
@ -398,6 +398,14 @@ class InvalidParameterValueErrorUnknownAttribute(EC2ClientError):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class InvalidGatewayIDError(EC2ClientError):
|
||||||
|
def __init__(self, gateway_id):
|
||||||
|
super(InvalidGatewayIDError, self).__init__(
|
||||||
|
"InvalidGatewayID.NotFound",
|
||||||
|
"The eigw ID '{0}' does not exist".format(gateway_id),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class InvalidInternetGatewayIdError(EC2ClientError):
|
class InvalidInternetGatewayIdError(EC2ClientError):
|
||||||
def __init__(self, internet_gateway_id):
|
def __init__(self, internet_gateway_id):
|
||||||
super(InvalidInternetGatewayIdError, self).__init__(
|
super(InvalidInternetGatewayIdError, self).__init__(
|
||||||
|
@ -111,6 +111,7 @@ from .exceptions import (
|
|||||||
InvalidAssociationIDIamProfileAssociationError,
|
InvalidAssociationIDIamProfileAssociationError,
|
||||||
InvalidVpcEndPointIdError,
|
InvalidVpcEndPointIdError,
|
||||||
InvalidTaggableResourceType,
|
InvalidTaggableResourceType,
|
||||||
|
InvalidGatewayIDError,
|
||||||
)
|
)
|
||||||
from .utils import (
|
from .utils import (
|
||||||
EC2_RESOURCE_TO_PREFIX,
|
EC2_RESOURCE_TO_PREFIX,
|
||||||
@ -123,6 +124,7 @@ from .utils import (
|
|||||||
random_eni_id,
|
random_eni_id,
|
||||||
random_instance_id,
|
random_instance_id,
|
||||||
random_internet_gateway_id,
|
random_internet_gateway_id,
|
||||||
|
random_egress_only_internet_gateway_id,
|
||||||
random_ip,
|
random_ip,
|
||||||
random_ipv6_cidr,
|
random_ipv6_cidr,
|
||||||
random_transit_gateway_attachment_id,
|
random_transit_gateway_attachment_id,
|
||||||
@ -4792,6 +4794,52 @@ class InternetGatewayBackend(object):
|
|||||||
return self.describe_internet_gateways(internet_gateway_ids=igw_ids)[0]
|
return self.describe_internet_gateways(internet_gateway_ids=igw_ids)[0]
|
||||||
|
|
||||||
|
|
||||||
|
class EgressOnlyInternetGateway(TaggedEC2Resource):
|
||||||
|
def __init__(self, ec2_backend, vpc_id, tags=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):
|
||||||
|
return self.id
|
||||||
|
|
||||||
|
|
||||||
|
class EgressOnlyInternetGatewayBackend(object):
|
||||||
|
def __init__(self):
|
||||||
|
self.egress_only_internet_gateway_backend = {}
|
||||||
|
super(EgressOnlyInternetGatewayBackend, self).__init__()
|
||||||
|
|
||||||
|
def create_egress_only_internet_gateway(self, vpc_id, tags=None):
|
||||||
|
vpc = self.get_vpc(vpc_id)
|
||||||
|
if not vpc:
|
||||||
|
raise InvalidVPCIdError(vpc_id)
|
||||||
|
egress_only_igw = EgressOnlyInternetGateway(self, vpc_id, tags)
|
||||||
|
self.egress_only_internet_gateway_backend[egress_only_igw.id] = egress_only_igw
|
||||||
|
return egress_only_igw
|
||||||
|
|
||||||
|
def describe_egress_only_internet_gateways(self, ids=None, filters=None):
|
||||||
|
# TODO: support filtering based on tag
|
||||||
|
egress_only_igws = list(self.egress_only_internet_gateway_backend.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, id):
|
||||||
|
egress_only_igw = self.egress_only_internet_gateway_backend.get(id)
|
||||||
|
if not egress_only_igw:
|
||||||
|
raise InvalidGatewayIDError(id)
|
||||||
|
if egress_only_igw:
|
||||||
|
self.egress_only_internet_gateway_backend.pop(id)
|
||||||
|
|
||||||
|
|
||||||
class VPCGatewayAttachment(CloudFormationModel):
|
class VPCGatewayAttachment(CloudFormationModel):
|
||||||
def __init__(self, gateway_id, vpc_id):
|
def __init__(self, gateway_id, vpc_id):
|
||||||
self.gateway_id = gateway_id
|
self.gateway_id = gateway_id
|
||||||
@ -7308,6 +7356,7 @@ class EC2Backend(
|
|||||||
RouteTableBackend,
|
RouteTableBackend,
|
||||||
RouteBackend,
|
RouteBackend,
|
||||||
InternetGatewayBackend,
|
InternetGatewayBackend,
|
||||||
|
EgressOnlyInternetGatewayBackend,
|
||||||
VPCGatewayAttachmentBackend,
|
VPCGatewayAttachmentBackend,
|
||||||
SpotFleetBackend,
|
SpotFleetBackend,
|
||||||
SpotRequestBackend,
|
SpotRequestBackend,
|
||||||
|
@ -12,6 +12,7 @@ from .elastic_network_interfaces import ElasticNetworkInterfaces
|
|||||||
from .general import General
|
from .general import General
|
||||||
from .instances import InstanceResponse
|
from .instances import InstanceResponse
|
||||||
from .internet_gateways import InternetGateways
|
from .internet_gateways import InternetGateways
|
||||||
|
from .egress_only_internet_gateways import EgressOnlyInternetGateway
|
||||||
from .ip_addresses import IPAddresses
|
from .ip_addresses import IPAddresses
|
||||||
from .key_pairs import KeyPairs
|
from .key_pairs import KeyPairs
|
||||||
from .launch_templates import LaunchTemplates
|
from .launch_templates import LaunchTemplates
|
||||||
@ -53,6 +54,7 @@ class EC2Response(
|
|||||||
General,
|
General,
|
||||||
InstanceResponse,
|
InstanceResponse,
|
||||||
InternetGateways,
|
InternetGateways,
|
||||||
|
EgressOnlyInternetGateway,
|
||||||
IPAddresses,
|
IPAddresses,
|
||||||
KeyPairs,
|
KeyPairs,
|
||||||
LaunchTemplates,
|
LaunchTemplates,
|
||||||
|
83
moto/ec2/responses/egress_only_internet_gateways.py
Normal file
83
moto/ec2/responses/egress_only_internet_gateways.py
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
from moto.core.responses import BaseResponse
|
||||||
|
from moto.ec2.utils import filters_from_querystring, add_tag_specification
|
||||||
|
|
||||||
|
|
||||||
|
class EgressOnlyInternetGateway(BaseResponse):
|
||||||
|
def create_egress_only_internet_gateway(self):
|
||||||
|
vpc_id = self._get_param("VpcId")
|
||||||
|
tags = self._get_multi_param("TagSpecification")
|
||||||
|
tags = add_tag_specification(tags)
|
||||||
|
|
||||||
|
egress_only_igw = self.ec2_backend.create_egress_only_internet_gateway(
|
||||||
|
vpc_id=vpc_id, tags=tags
|
||||||
|
)
|
||||||
|
template = self.response_template(CREATE_EGRESS_ONLY_IGW_RESPONSE)
|
||||||
|
return template.render(egress_only_igw=egress_only_igw)
|
||||||
|
|
||||||
|
def describe_egress_only_internet_gateways(self):
|
||||||
|
egress_only_igw_ids = self._get_multi_param("EgressOnlyInternetGatewayId")
|
||||||
|
filters = filters_from_querystring(self.querystring)
|
||||||
|
egress_only_igws = self.ec2_backend.describe_egress_only_internet_gateways(
|
||||||
|
egress_only_igw_ids, filters,
|
||||||
|
)
|
||||||
|
template = self.response_template(DESCRIBE_EGRESS_ONLY_IGW_RESPONSE)
|
||||||
|
return template.render(egress_only_igws=egress_only_igws)
|
||||||
|
|
||||||
|
def delete_egress_only_internet_gateway(self):
|
||||||
|
egress_only_igw_id = self._get_param("EgressOnlyInternetGatewayId")
|
||||||
|
self.ec2_backend.delete_egress_only_internet_gateway(id=egress_only_igw_id)
|
||||||
|
template = self.response_template(DELETE_EGRESS_ONLY_IGW_RESPONSE)
|
||||||
|
return template.render()
|
||||||
|
|
||||||
|
|
||||||
|
CREATE_EGRESS_ONLY_IGW_RESPONSE = """<CreateEgressOnlyInternetGatewayResponse xmlns="http://ec2.amazonaws.com/doc/2016-11-15/">
|
||||||
|
<requestId>c617595f-6c29-4a00-a941-example</requestId>
|
||||||
|
<egressOnlyInternetGateway>
|
||||||
|
<attachmentSet>
|
||||||
|
<item>
|
||||||
|
<state>{{ egress_only_igw.state }}</state>
|
||||||
|
<vpcId>{{ egress_only_igw.vpc_id }}</vpcId>
|
||||||
|
</item>
|
||||||
|
</attachmentSet>
|
||||||
|
<egressOnlyInternetGatewayId>{{ egress_only_igw.id }}</egressOnlyInternetGatewayId>
|
||||||
|
<tagSet>
|
||||||
|
{% for tag in egress_only_igw.get_tags() %}
|
||||||
|
<item>
|
||||||
|
<key>{{ tag.key }}</key>
|
||||||
|
<value>{{ tag.value }}</value>
|
||||||
|
</item>
|
||||||
|
{% endfor %}
|
||||||
|
</tagSet>
|
||||||
|
</egressOnlyInternetGateway>
|
||||||
|
</CreateEgressOnlyInternetGatewayResponse>
|
||||||
|
"""
|
||||||
|
|
||||||
|
DESCRIBE_EGRESS_ONLY_IGW_RESPONSE = """<DescribeEgressOnlyInternetGatewaysResponse xmlns="http://ec2.amazonaws.com/doc/2016-11-15/">
|
||||||
|
<requestId>ec441b4c-357f-4483-b4a7-example</requestId>
|
||||||
|
<egressOnlyInternetGatewaySet>
|
||||||
|
{% for egress_only_igw in egress_only_igws %}
|
||||||
|
<item>
|
||||||
|
<attachmentSet>
|
||||||
|
<item>
|
||||||
|
<state>{{ egress_only_igw.state }}</state>
|
||||||
|
<vpcId>{{ egress_only_igw.vpc_id }}</vpcId>
|
||||||
|
</item>
|
||||||
|
</attachmentSet>
|
||||||
|
<egressOnlyInternetGatewayId>{{ egress_only_igw.id }}</egressOnlyInternetGatewayId>
|
||||||
|
<tagSet>
|
||||||
|
{% for tag in egress_only_igw.get_tags() %}
|
||||||
|
<item>
|
||||||
|
<key>{{ tag.key }}</key>
|
||||||
|
<value>{{ tag.value }}</value>
|
||||||
|
</item>
|
||||||
|
{% endfor %}
|
||||||
|
</tagSet>
|
||||||
|
</item>
|
||||||
|
{% endfor %}
|
||||||
|
</egressOnlyInternetGatewaySet>
|
||||||
|
</DescribeEgressOnlyInternetGatewaysResponse>"""
|
||||||
|
|
||||||
|
DELETE_EGRESS_ONLY_IGW_RESPONSE = """<DeleteEgressOnlyInternetGateway xmlns="http://ec2.amazonaws.com/doc/2016-11-15/">
|
||||||
|
<requestId>59dbff89-35bd-4eac-99ed-be587EXAMPLE</requestId>
|
||||||
|
<returnCode>true</returnCode>
|
||||||
|
</DeleteEgressOnlyInternetGateway>"""
|
@ -23,6 +23,7 @@ EC2_RESOURCE_TO_PREFIX = {
|
|||||||
"image": "ami",
|
"image": "ami",
|
||||||
"instance": "i",
|
"instance": "i",
|
||||||
"internet-gateway": "igw",
|
"internet-gateway": "igw",
|
||||||
|
"egress-only-internet-gateway": "eigw",
|
||||||
"launch-template": "lt",
|
"launch-template": "lt",
|
||||||
"nat-gateway": "nat",
|
"nat-gateway": "nat",
|
||||||
"network-acl": "acl",
|
"network-acl": "acl",
|
||||||
@ -153,6 +154,12 @@ def random_internet_gateway_id():
|
|||||||
return random_id(prefix=EC2_RESOURCE_TO_PREFIX["internet-gateway"])
|
return random_id(prefix=EC2_RESOURCE_TO_PREFIX["internet-gateway"])
|
||||||
|
|
||||||
|
|
||||||
|
def random_egress_only_internet_gateway_id():
|
||||||
|
return random_id(
|
||||||
|
prefix=EC2_RESOURCE_TO_PREFIX["egress-only-internet-gateway"], size=17
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def random_route_table_id():
|
def random_route_table_id():
|
||||||
return random_id(prefix=EC2_RESOURCE_TO_PREFIX["route-table"])
|
return random_id(prefix=EC2_RESOURCE_TO_PREFIX["route-table"])
|
||||||
|
|
||||||
|
@ -87,3 +87,4 @@ TestAccAWSRouteTable_IPv4_To_TransitGateway
|
|||||||
TestAccAWSRouteTable_disappears
|
TestAccAWSRouteTable_disappears
|
||||||
TestAccAWSRouteTable_basic
|
TestAccAWSRouteTable_basic
|
||||||
TestAccAwsEc2ManagedPrefixList
|
TestAccAwsEc2ManagedPrefixList
|
||||||
|
TestAccAWSEgressOnlyInternetGateway
|
Loading…
Reference in New Issue
Block a user