added support for tags in vpc peering connections (#4137)

This commit is contained in:
Macwan Nevil 2021-08-07 13:08:27 +05:30 committed by GitHub
parent 35d0ddef24
commit f096b0e717
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 71 additions and 32 deletions

View File

@ -127,6 +127,7 @@ from .utils import (
random_ipv6_cidr, random_ipv6_cidr,
random_transit_gateway_attachment_id, random_transit_gateway_attachment_id,
random_transit_gateway_route_table_id, random_transit_gateway_route_table_id,
random_vpc_ep_id,
randor_ipv4_cidr, randor_ipv4_cidr,
random_launch_template_id, random_launch_template_id,
random_nat_gateway_id, random_nat_gateway_id,
@ -137,7 +138,6 @@ from .utils import (
random_reservation_id, random_reservation_id,
random_route_table_id, random_route_table_id,
generate_route_id, generate_route_id,
generate_vpc_end_point_id,
create_dns_entries, create_dns_entries,
split_route_id, split_route_id,
random_security_group_id, random_security_group_id,
@ -3267,11 +3267,11 @@ class VPCBackend(object):
dns_entries=None, dns_entries=None,
client_token=None, client_token=None,
security_group_ids=None, security_group_ids=None,
tag_specifications=None, tags=None,
private_dns_enabled=None, private_dns_enabled=None,
): ):
vpc_endpoint_id = generate_vpc_end_point_id(vpc_id) vpc_endpoint_id = random_vpc_ep_id()
# validates if vpc is present or not. # validates if vpc is present or not.
self.get_vpc(vpc_id) self.get_vpc(vpc_id)
@ -3308,7 +3308,7 @@ class VPCBackend(object):
dns_entries, dns_entries,
client_token, client_token,
security_group_ids, security_group_ids,
tag_specifications, tags,
private_dns_enabled, private_dns_enabled,
) )
@ -3378,10 +3378,12 @@ class PeeringConnectionStatus(object):
class VPCPeeringConnection(TaggedEC2Resource, CloudFormationModel): class VPCPeeringConnection(TaggedEC2Resource, CloudFormationModel):
def __init__(self, vpc_pcx_id, vpc, peer_vpc): def __init__(self, backend, vpc_pcx_id, vpc, peer_vpc, tags=None):
self.id = vpc_pcx_id self.id = vpc_pcx_id
self.ec2_backend = backend
self.vpc = vpc self.vpc = vpc
self.peer_vpc = peer_vpc self.peer_vpc = peer_vpc
self.add_tags(tags or {})
self._status = PeeringConnectionStatus() self._status = PeeringConnectionStatus()
@staticmethod @staticmethod
@ -3428,9 +3430,9 @@ class VPCPeeringConnectionBackend(object):
if inst is not None: if inst is not None:
yield inst yield inst
def create_vpc_peering_connection(self, vpc, peer_vpc): def create_vpc_peering_connection(self, vpc, peer_vpc, tags=None):
vpc_pcx_id = random_vpc_peering_connection_id() vpc_pcx_id = random_vpc_peering_connection_id()
vpc_pcx = VPCPeeringConnection(vpc_pcx_id, vpc, peer_vpc) vpc_pcx = VPCPeeringConnection(self, vpc_pcx_id, vpc, peer_vpc, tags)
vpc_pcx._status.pending() vpc_pcx._status.pending()
self.vpc_pcxs[vpc_pcx_id] = vpc_pcx self.vpc_pcxs[vpc_pcx_id] = vpc_pcx
# insert cross region peering info # insert cross region peering info
@ -4362,7 +4364,7 @@ class VPCEndPoint(TaggedEC2Resource):
dns_entries=None, dns_entries=None,
client_token=None, client_token=None,
security_group_ids=None, security_group_ids=None,
tag_specifications=None, tags=None,
private_dns_enabled=None, private_dns_enabled=None,
): ):
self.ec2_backend = ec2_backend self.ec2_backend = ec2_backend
@ -4376,10 +4378,14 @@ class VPCEndPoint(TaggedEC2Resource):
self.subnet_ids = subnet_ids self.subnet_ids = subnet_ids
self.client_token = client_token self.client_token = client_token
self.security_group_ids = security_group_ids self.security_group_ids = security_group_ids
self.tag_specifications = tag_specifications
self.private_dns_enabled = private_dns_enabled self.private_dns_enabled = private_dns_enabled
self.created_at = datetime.utcnow() self._created_at = datetime.utcnow()
self.dns_entries = dns_entries self.dns_entries = dns_entries
self.add_tags(tags or {})
@property
def created_at(self):
return iso_8601_datetime_with_milliseconds(self._created_at)
class RouteBackend(object): class RouteBackend(object):

View File

@ -6,6 +6,11 @@ from moto.core import ACCOUNT_ID
class VPCPeeringConnections(BaseResponse): class VPCPeeringConnections(BaseResponse):
def create_vpc_peering_connection(self): def create_vpc_peering_connection(self):
peer_region = self._get_param("PeerRegion") peer_region = self._get_param("PeerRegion")
tags = self._get_multi_param("TagSpecification")
tags = tags[0] if isinstance(tags, list) and len(tags) == 1 else tags
tags = (tags or {}).get("Tag", [])
tags = {t["Key"]: t["Value"] for t in tags}
if peer_region == self.region or peer_region is None: if peer_region == self.region or peer_region is None:
peer_vpc = self.ec2_backend.get_vpc(self._get_param("PeerVpcId")) peer_vpc = self.ec2_backend.get_vpc(self._get_param("PeerVpcId"))
else: else:
@ -13,7 +18,7 @@ class VPCPeeringConnections(BaseResponse):
self._get_param("PeerVpcId"), peer_region self._get_param("PeerVpcId"), peer_region
) )
vpc = self.ec2_backend.get_vpc(self._get_param("VpcId")) vpc = self.ec2_backend.get_vpc(self._get_param("VpcId"))
vpc_pcx = self.ec2_backend.create_vpc_peering_connection(vpc, peer_vpc) vpc_pcx = self.ec2_backend.create_vpc_peering_connection(vpc, peer_vpc, tags)
template = self.response_template(CREATE_VPC_PEERING_CONNECTION_RESPONSE) template = self.response_template(CREATE_VPC_PEERING_CONNECTION_RESPONSE)
return template.render(vpc_pcx=vpc_pcx) return template.render(vpc_pcx=vpc_pcx)
@ -68,7 +73,14 @@ CREATE_VPC_PEERING_CONNECTION_RESPONSE = (
<message>Initiating Request to {accepter ID}</message> <message>Initiating Request to {accepter ID}</message>
</status> </status>
<expirationTime>2014-02-18T14:37:25.000Z</expirationTime> <expirationTime>2014-02-18T14:37:25.000Z</expirationTime>
<tagSet/> <tagSet>
{% for tag in vpc_pcx.get_tags() %}
<item>
<key>{{ tag.key }}</key>
<value>{{ tag.value }}</value>
</item>
{% endfor %}
</tagSet>
</vpcPeeringConnection> </vpcPeeringConnection>
</CreateVpcPeeringConnectionResponse> </CreateVpcPeeringConnectionResponse>
""" """
@ -105,7 +117,14 @@ DESCRIBE_VPC_PEERING_CONNECTIONS_RESPONSE = (
<code>{{ vpc_pcx._status.code }}</code> <code>{{ vpc_pcx._status.code }}</code>
<message>{{ vpc_pcx._status.message }}</message> <message>{{ vpc_pcx._status.message }}</message>
</status> </status>
<tagSet/> <tagSet>
{% for tag in vpc_pcx.get_tags() %}
<item>
<key>{{ tag.key }}</key>
<value>{{ tag.value }}</value>
</item>
{% endfor %}
</tagSet>
</item> </item>
{% endfor %} {% endfor %}
</vpcPeeringConnectionSet> </vpcPeeringConnectionSet>
@ -149,7 +168,14 @@ ACCEPT_VPC_PEERING_CONNECTION_RESPONSE = (
<code>{{ vpc_pcx._status.code }}</code> <code>{{ vpc_pcx._status.code }}</code>
<message>{{ vpc_pcx._status.message }}</message> <message>{{ vpc_pcx._status.message }}</message>
</status> </status>
<tagSet/> <tagSet>
{% for tag in vpc_pcx.get_tags() %}
<item>
<key>{{ tag.key }}</key>
<value>{{ tag.value }}</value>
</item>
{% endfor %}
</tagSet>
</vpcPeeringConnection> </vpcPeeringConnection>
</AcceptVpcPeeringConnectionResponse> </AcceptVpcPeeringConnectionResponse>
""" """

View File

@ -2,7 +2,7 @@ from __future__ import unicode_literals
from moto.core import ACCOUNT_ID from moto.core import ACCOUNT_ID
from moto.core.responses import BaseResponse from moto.core.responses import BaseResponse
from moto.core.utils import camelcase_to_underscores from moto.core.utils import camelcase_to_underscores
from moto.ec2.utils import filters_from_querystring from moto.ec2.utils import add_tag_specification, filters_from_querystring
class VPCs(BaseResponse): class VPCs(BaseResponse):
@ -184,10 +184,11 @@ class VPCs(BaseResponse):
type = self._get_param("VpcEndpointType") type = self._get_param("VpcEndpointType")
policy_document = self._get_param("PolicyDocument") policy_document = self._get_param("PolicyDocument")
client_token = self._get_param("ClientToken") client_token = self._get_param("ClientToken")
tag_specifications = self._get_param("TagSpecifications") tags = self._get_multi_param("TagSpecification")
private_dns_enabled = self._get_bool_param("PrivateDnsEnabled", if_none=True) private_dns_enabled = self._get_bool_param("PrivateDnsEnabled", if_none=True)
security_group_ids = self._get_multi_param("SecurityGroupId") security_group_ids = self._get_multi_param("SecurityGroupId")
tags = add_tag_specification(tags)
vpc_end_point = self.ec2_backend.create_vpc_endpoint( vpc_end_point = self.ec2_backend.create_vpc_endpoint(
vpc_id=vpc_id, vpc_id=vpc_id,
service_name=service_name, service_name=service_name,
@ -197,10 +198,9 @@ class VPCs(BaseResponse):
subnet_ids=subnet_ids, subnet_ids=subnet_ids,
client_token=client_token, client_token=client_token,
security_group_ids=security_group_ids, security_group_ids=security_group_ids,
tag_specifications=tag_specifications, tags=tags,
private_dns_enabled=private_dns_enabled, private_dns_enabled=private_dns_enabled,
) )
template = self.response_template(CREATE_VPC_END_POINT) template = self.response_template(CREATE_VPC_END_POINT)
return template.render(vpc_end_point=vpc_end_point) return template.render(vpc_end_point=vpc_end_point)
@ -483,6 +483,14 @@ CREATE_VPC_END_POINT = """ <CreateVpcEndpointResponse xmlns="http://monitoring.a
{% endfor %} {% endfor %}
{% endif %} {% endif %}
</dnsEntrySet> </dnsEntrySet>
<tagSet>
{% for tag in vpc_end_point.get_tags() %}
<item>
<key>{{ tag.key }}</key>
<value>{{ tag.value }}</value>
</item>
{% endfor %}
</tagSet>
<creationTimestamp>{{ vpc_end_point.created_at }}</creationTimestamp> <creationTimestamp>{{ vpc_end_point.created_at }}</creationTimestamp>
</vpcEndpoint> </vpcEndpoint>
</CreateVpcEndpointResponse>""" </CreateVpcEndpointResponse>"""
@ -571,16 +579,14 @@ DESCRIBE_VPC_ENDPOINT_RESPONSE = """<DescribeVpcEndpointsResponse xmlns="http://
{% endfor %} {% endfor %}
</groupSet> </groupSet>
{% endif %} {% endif %}
{% if vpc_end_point.tag_specifications %} <tagSet>
<tagSet> {% for tag in vpc_end_point.get_tags() %}
{% for tag in vpc_end_point.tag_specifications %} <item>
<item> <key>{{ tag.key }}</key>
<key>{{ tag.key }}</key> <value>{{ tag.value }}</value>
<value>{{ tag.value }}</value> </item>
</item> {% endfor %}
{% endfor %} </tagSet>
</tagSet>
{% endif %}
<ownerId>{{ account_id }}</ownerId> <ownerId>{{ account_id }}</ownerId>
<creationTimestamp>{{ vpc_end_point.created_at }}</creationTimestamp> <creationTimestamp>{{ vpc_end_point.created_at }}</creationTimestamp>
</item> </item>

View File

@ -40,6 +40,7 @@ EC2_RESOURCE_TO_PREFIX = {
"reservation": "r", "reservation": "r",
"volume": "vol", "volume": "vol",
"vpc": "vpc", "vpc": "vpc",
"vpc-endpoint": "vpce",
"vpc-cidr-association-id": "vpc-cidr-assoc", "vpc-cidr-association-id": "vpc-cidr-assoc",
"vpc-elastic-ip": "eipalloc", "vpc-elastic-ip": "eipalloc",
"vpc-elastic-ip-association": "eipassoc", "vpc-elastic-ip-association": "eipassoc",
@ -131,6 +132,10 @@ def random_vpc_id():
return random_id(prefix=EC2_RESOURCE_TO_PREFIX["vpc"]) return random_id(prefix=EC2_RESOURCE_TO_PREFIX["vpc"])
def random_vpc_ep_id():
return random_id(prefix=EC2_RESOURCE_TO_PREFIX["vpc-endpoint"], size=8)
def random_vpc_cidr_association_id(): def random_vpc_cidr_association_id():
return random_id(prefix=EC2_RESOURCE_TO_PREFIX["vpc-cidr-association-id"]) return random_id(prefix=EC2_RESOURCE_TO_PREFIX["vpc-cidr-association-id"])
@ -225,10 +230,6 @@ def generate_route_id(route_table_id, cidr_block, ipv6_cidr_block=None):
return "%s~%s" % (route_table_id, cidr_block) return "%s~%s" % (route_table_id, cidr_block)
def generate_vpc_end_point_id(vpc_id):
return "%s-%s%s" % ("vpce", vpc_id[4:], random_resource_id(4))
def create_dns_entries(service_name, vpc_endpoint_id): def create_dns_entries(service_name, vpc_endpoint_id):
dns_entries = {} dns_entries = {}
dns_entries["dns_name"] = "{}-{}.{}".format( dns_entries["dns_name"] = "{}-{}.{}".format(