Added support for tgw peering attachment (#4115)

* Added required params to run the terraform test
This commit is contained in:
Mohit Alonja 2021-08-03 12:28:25 +05:30 committed by GitHub
parent 16a4db1ce5
commit 911d29cc33
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 278 additions and 7 deletions

View File

@ -230,7 +230,7 @@ jobs:
- name: Run Terraform Tests - name: Run Terraform Tests
run: | run: |
cd moto-terraform-tests cd moto-terraform-tests
bin/run-tests -i ../tests/terraform-tests.success.txt -e ../tests/terraform-tests.failures.txt AWS_DEFAULT_REGION=us-east-1 AWS_ALTERNATE_REGION=eu-west-1 bin/run-tests -i ../tests/terraform-tests.success.txt -e ../tests/terraform-tests.failures.txt
cd .. cd ..
- name: "Create report" - name: "Create report"
run: | run: |

View File

@ -170,6 +170,7 @@ from .utils import (
tag_filter_matches, tag_filter_matches,
rsa_public_key_parse, rsa_public_key_parse,
rsa_public_key_fingerprint, rsa_public_key_fingerprint,
describe_tag_filter,
) )
@ -3355,7 +3356,7 @@ class VPCBackend(object):
} }
class VPCPeeringConnectionStatus(object): class PeeringConnectionStatus(object):
def __init__(self, code="initiating-request", message=""): def __init__(self, code="initiating-request", message=""):
self.code = code self.code = code
self.message = message self.message = message
@ -3386,7 +3387,7 @@ class VPCPeeringConnection(TaggedEC2Resource, CloudFormationModel):
self.id = vpc_pcx_id self.id = vpc_pcx_id
self.vpc = vpc self.vpc = vpc
self.peer_vpc = peer_vpc self.peer_vpc = peer_vpc
self._status = VPCPeeringConnectionStatus() self._status = PeeringConnectionStatus()
@staticmethod @staticmethod
def cloudformation_name_type(): def cloudformation_name_type():
@ -6332,7 +6333,7 @@ class TransitGatewayAttachment(TaggedEC2Resource):
self.add_tags(tags or {}) self.add_tags(tags or {})
self._created_at = datetime.utcnow() self._created_at = datetime.utcnow()
self.owner_id = ACCOUNT_ID self.owner_id = self.resource_owner_id
@property @property
def create_time(self): def create_time(self):
@ -6372,6 +6373,43 @@ class TransitGatewayVpcAttachment(TransitGatewayAttachment):
self.options = merge_multiple_dicts(self.DEFAULT_OPTIONS, options or {}) self.options = merge_multiple_dicts(self.DEFAULT_OPTIONS, options or {})
class TransitGatewayPeeringAttachment(TransitGatewayAttachment):
def __init__(
self,
backend,
transit_gateway_id=None,
peer_transit_gateway_id=None,
peer_region=None,
peer_account_id=None,
tags=None,
region_name=None,
):
super().__init__(
backend=backend,
transit_gateway_id=transit_gateway_id,
resource_id=peer_transit_gateway_id,
resource_type="peering",
tags=tags,
)
self.accepter_tgw_info = {
"ownerId": peer_account_id,
"region": peer_region,
"transitGatewayId": peer_transit_gateway_id,
}
self.requester_tgw_info = {
"ownerId": self.owner_id,
"region": region_name,
"transitGatewayId": transit_gateway_id,
}
self.status = PeeringConnectionStatus()
@property
def resource_owner_id(self):
return ACCOUNT_ID
class TransitGatewayAttachmentBackend(object): class TransitGatewayAttachmentBackend(object):
def __init__(self): def __init__(self):
self.transit_gateway_attachments = {} self.transit_gateway_attachments = {}
@ -6512,6 +6550,82 @@ class TransitGatewayAttachmentBackend(object):
"state" "state"
] = "disabled" ] = "disabled"
def create_transit_gateway_peering_attachment(
self,
transit_gateway_id,
peer_transit_gateway_id,
peer_region,
peer_account_id,
tags,
):
transit_gateway_peering_attachment = TransitGatewayPeeringAttachment(
self,
transit_gateway_id=transit_gateway_id,
peer_transit_gateway_id=peer_transit_gateway_id,
peer_region=peer_region,
peer_account_id=peer_account_id,
tags=tags,
region_name=self.region_name,
)
transit_gateway_peering_attachment.status.accept()
transit_gateway_peering_attachment.state = "available"
self.transit_gateway_attachments[
transit_gateway_peering_attachment.id
] = transit_gateway_peering_attachment
return transit_gateway_peering_attachment
def describe_transit_gateway_peering_attachments(
self, transit_gateways_attachment_ids=None, filters=None, max_results=0
):
transit_gateway_attachments = list(self.transit_gateway_attachments.values())
attr_pairs = (
("state", "state"),
("transit-gateway-attachment-id", "id"),
("local-owner-id", "requester_tgw_info", "ownerId"),
("remote-owner-id", "accepter_tgw_info", "ownerId"),
)
if transit_gateways_attachment_ids:
transit_gateway_attachments = [
transit_gateways_attachment
for transit_gateways_attachment in transit_gateway_attachments
if transit_gateways_attachment.id in transit_gateways_attachment_ids
]
if filters:
transit_gateway_attachments = filter_resources(
transit_gateway_attachments, filters, attr_pairs
)
transit_gateway_attachments = describe_tag_filter(
filters, transit_gateway_attachments
)
return transit_gateway_attachments
def accept_transit_gateway_peering_attachment(self, transit_gateway_attachment_id):
transit_gateway_attachment = self.transit_gateway_attachments[
transit_gateway_attachment_id
]
transit_gateway_attachment.state = "available"
transit_gateway_attachment.status.accept()
return transit_gateway_attachment
def reject_transit_gateway_peering_attachment(self, transit_gateway_attachment_id):
transit_gateway_attachment = self.transit_gateway_attachments[
transit_gateway_attachment_id
]
transit_gateway_attachment.state = "rejected"
transit_gateway_attachment.status.reject()
return transit_gateway_attachment
def delete_transit_gateway_peering_attachment(self, transit_gateway_attachment_id):
transit_gateway_attachment = self.transit_gateway_attachments[
transit_gateway_attachment_id
]
transit_gateway_attachment.state = "deleted"
transit_gateway_attachment.status.deleted()
return transit_gateway_attachment
class TransitGatewayRelations(object): class TransitGatewayRelations(object):
# this class is for TransitGatewayAssociation and TransitGatewayPropagation # this class is for TransitGatewayAssociation and TransitGatewayPropagation

View File

@ -1,6 +1,6 @@
from __future__ import unicode_literals from __future__ import unicode_literals
from moto.core.responses import BaseResponse from moto.core.responses import BaseResponse
from moto.ec2.utils import filters_from_querystring from moto.ec2.utils import filters_from_querystring, add_tag_specification
class TransitGatewayAttachment(BaseResponse): class TransitGatewayAttachment(BaseResponse):
@ -108,6 +108,74 @@ class TransitGatewayAttachment(BaseResponse):
template = self.response_template(TRANSIT_GATEWAY_PROPAGATION) template = self.response_template(TRANSIT_GATEWAY_PROPAGATION)
return template.render(transit_gateway_propagation=transit_gateway_propagation) return template.render(transit_gateway_propagation=transit_gateway_propagation)
def create_transit_gateway_peering_attachment(self):
peer_account_id = self._get_param("PeerAccountId")
peer_region = self._get_param("PeerRegion")
peer_transit_gateway_id = self._get_param("PeerTransitGatewayId")
transit_gateway_id = self._get_param("TransitGatewayId")
tags = add_tag_specification(self._get_multi_param("TagSpecification"))
transit_gateway_peering_attachment = self.ec2_backend.create_transit_gateway_peering_attachment(
transit_gateway_id,
peer_transit_gateway_id,
peer_region,
peer_account_id,
tags,
)
template = self.response_template(TRANSIT_GATEWAY_PEERING_ATTACHMENT)
return template.render(
method_name="CreateTransitGatewayPeeringAttachment",
transit_gateway_peering_attachment=transit_gateway_peering_attachment,
)
def describe_transit_gateway_peering_attachments(self):
transit_gateways_attachment_ids = self._get_multi_param(
"TransitGatewayAttachmentIds"
)
filters = filters_from_querystring(self.querystring)
max_results = self._get_param("MaxResults")
transit_gateway_peering_attachments = self.ec2_backend.describe_transit_gateway_peering_attachments(
transit_gateways_attachment_ids=transit_gateways_attachment_ids,
filters=filters,
max_results=max_results,
)
template = self.response_template(DESCRIBE_TRANSIT_GATEWAY_PEERING_ATTACHMENTS)
return template.render(
transit_gateway_peering_attachments=transit_gateway_peering_attachments
)
def accept_transit_gateway_peering_attachment(self):
transit_gateway_attachment_id = self._get_param("TransitGatewayAttachmentId")
transit_gateway_peering_attachment = self.ec2_backend.accept_transit_gateway_peering_attachment(
transit_gateway_attachment_id=transit_gateway_attachment_id
)
template = self.response_template(TRANSIT_GATEWAY_PEERING_ATTACHMENT)
return template.render(
method_name="AcceptTransitGatewayPeeringAttachment",
transit_gateway_peering_attachment=transit_gateway_peering_attachment,
)
def delete_transit_gateway_peering_attachment(self):
transit_gateway_attachment_id = self._get_param("TransitGatewayAttachmentId")
transit_gateway_peering_attachment = self.ec2_backend.delete_transit_gateway_peering_attachment(
transit_gateway_attachment_id=transit_gateway_attachment_id
)
template = self.response_template(TRANSIT_GATEWAY_PEERING_ATTACHMENT)
return template.render(
method_name="DeleteTransitGatewayPeeringAttachment",
transit_gateway_peering_attachment=transit_gateway_peering_attachment,
)
def reject_transit_gateway_peering_attachment(self):
transit_gateway_attachment_id = self._get_param("TransitGatewayAttachmentId")
transit_gateway_peering_attachment = self.ec2_backend.reject_transit_gateway_peering_attachment(
transit_gateway_attachment_id=transit_gateway_attachment_id
)
template = self.response_template(TRANSIT_GATEWAY_PEERING_ATTACHMENT)
return template.render(
method_name="RejectTransitGatewayPeeringAttachment",
transit_gateway_peering_attachment=transit_gateway_peering_attachment,
)
CREATE_TRANSIT_GATEWAY_VPC_ATTACHMENT = """<CreateTransitGatewayVpcAttachmentResponse xmlns="http://ec2.amazonaws.com/doc/2016-11-15/"> CREATE_TRANSIT_GATEWAY_VPC_ATTACHMENT = """<CreateTransitGatewayVpcAttachmentResponse xmlns="http://ec2.amazonaws.com/doc/2016-11-15/">
<requestId>9b5766ac-2af6-4b92-9a8a-4d74ae46ae79</requestId> <requestId>9b5766ac-2af6-4b92-9a8a-4d74ae46ae79</requestId>
@ -294,3 +362,66 @@ TRANSIT_GATEWAY_PROPAGATION = """<EnableTransitGatewayRouteTablePropagationRespo
</propagation> </propagation>
</EnableTransitGatewayRouteTablePropagationResponse> </EnableTransitGatewayRouteTablePropagationResponse>
""" """
TRANSIT_GATEWAY_PEERING_ATTACHMENT = """<{{ method_name }} xmlns="http://ec2.amazonaws.com/doc/2016-11-15/">
<requestId>9b5766ac-2af6-4b92-9a8a-4d74ae46ae79</requestId>
<transitGatewayPeeringAttachment>
<createTime>{{ transit_gateway_peering_attachment.create_time }}</createTime>
<state>{{ transit_gateway_peering_attachment.state }}</state>
<accepterTgwInfo>
<ownerId>{{ transit_gateway_peering_attachment.accepter_tgw_info.ownerId or '' }}</ownerId>
<region>{{ transit_gateway_peering_attachment.accepter_tgw_info.region or '' }}</region>
<transitGatewayId>{{ transit_gateway_peering_attachment.accepter_tgw_info.transitGatewayId or '' }}</transitGatewayId>
</accepterTgwInfo>
<requesterTgwInfo>
<ownerId>{{ transit_gateway_peering_attachment.requester_tgw_info.ownerId or '' }}</ownerId>
<region>{{ transit_gateway_peering_attachment.requester_tgw_info.region or '' }}</region>
<transitGatewayId>{{ transit_gateway_peering_attachment.requester_tgw_info.transitGatewayId or '' }}</transitGatewayId>
</requesterTgwInfo>
<status>{{ transit_gateway_peering_attachment.status.code }}</status>
<tagSet>
{% for tag in transit_gateway_peering_attachment.get_tags() %}
<item>
<key>{{ tag.key }}</key>
<value>{{ tag.value }}</value>
</item>
{% endfor %}
</tagSet>
<transitGatewayAttachmentId>{{ transit_gateway_peering_attachment.id }}</transitGatewayAttachmentId>
</transitGatewayPeeringAttachment>
</{{ method_name }}>"""
DESCRIBE_TRANSIT_GATEWAY_PEERING_ATTACHMENTS = """<DescribeTransitGatewayPeeringAttachments xmlns="http://ec2.amazonaws.com/doc/2016-11-15/">
<requestId>bebc9670-0205-4f28-ad89-049c97e46633</requestId>
<transitGatewayPeeringAttachments>
{% for transit_gateway_peering_attachment in transit_gateway_peering_attachments %}
<item>
<createTime>{{ transit_gateway_peering_attachment.create_time }}</createTime>
<state>{{ transit_gateway_peering_attachment.state }}</state>
<accepterTgwInfo>
<ownerId>{{ transit_gateway_peering_attachment.accepter_tgw_info.ownerId or '' }}</ownerId>
<region>{{ transit_gateway_peering_attachment.accepter_tgw_info.region or '' }}</region>
<transitGatewayId>{{ transit_gateway_peering_attachment.accepter_tgw_info.transitGatewayId or '' }}</transitGatewayId>
</accepterTgwInfo>
<requesterTgwInfo>
<ownerId>{{ transit_gateway_peering_attachment.requester_tgw_info.ownerId or '' }}</ownerId>
<region>{{ transit_gateway_peering_attachment.requester_tgw_info.region or '' }}</region>
<transitGatewayId>{{ transit_gateway_peering_attachment.requester_tgw_info.transitGatewayId or '' }}</transitGatewayId>
</requesterTgwInfo>
<status>{{ transit_gateway_peering_attachment.status.code }}</status>
<tagSet>
{% for tag in transit_gateway_peering_attachment.get_tags() %}
<item>
<key>{{ tag.key }}</key>
<value>{{ tag.value }}</value>
</item>
{% endfor %}
</tagSet>
<transitGatewayAttachmentId>{{ transit_gateway_peering_attachment.id }}</transitGatewayAttachmentId>
</item>
{% endfor %}
</transitGatewayPeeringAttachments>
</DescribeTransitGatewayPeeringAttachments>
"""

View File

@ -201,18 +201,21 @@ CREATE_VPN_CONNECTION_ROUTE_RESPONSE = """
<return>true</return> <return>true</return>
</CreateVpnConnectionRouteResponse>""" </CreateVpnConnectionRouteResponse>"""
DELETE_VPN_CONNECTION_RESPONSE = """ DELETE_VPN_CONNECTION_RESPONSE = """
<DeleteVpnConnectionResponse xmlns="http://ec2.amazonaws.com/doc/2013-10-15/"> <DeleteVpnConnectionResponse xmlns="http://ec2.amazonaws.com/doc/2013-10-15/">
<requestId>7a62c49f-347e-4fc4-9331-6e8eEXAMPLE</requestId> <requestId>7a62c49f-347e-4fc4-9331-6e8eEXAMPLE</requestId>
<return>true</return> <return>true</return>
</DeleteVpnConnectionResponse>""" </DeleteVpnConnectionResponse>"""
DELETE_VPN_CONNECTION_ROUTE_RESPONSE = """ DELETE_VPN_CONNECTION_ROUTE_RESPONSE = """
<DeleteVpnConnectionRouteResponse xmlns="http://ec2.amazonaws.com/doc/2013-10- 15/"> <DeleteVpnConnectionRouteResponse xmlns="http://ec2.amazonaws.com/doc/2013-10- 15/">
<requestId>4f35a1b2-c2c3-4093-b51f-abb9d7311990</requestId> <requestId>4f35a1b2-c2c3-4093-b51f-abb9d7311990</requestId>
<return>true</return> <return>true</return>
</DeleteVpnConnectionRouteResponse>""" </DeleteVpnConnectionRouteResponse>"""
DESCRIBE_VPN_CONNECTION_RESPONSE = ( DESCRIBE_VPN_CONNECTION_RESPONSE = (
""" """
<DescribeVpnConnectionsResponse xmlns="http://ec2.amazonaws.com/doc/2013-10-15/"> <DescribeVpnConnectionsResponse xmlns="http://ec2.amazonaws.com/doc/2013-10-15/">

View File

@ -678,3 +678,26 @@ def filter_iam_instance_profiles(iam_instance_profile_arn, iam_instance_profile_
instance_profile = None instance_profile = None
return instance_profile return instance_profile
def describe_tag_filter(filters, instances):
result = instances.copy()
for instance in instances:
for key in filters:
if key.startswith("tag:"):
match = re.match(r"tag:(.*)", key)
if match:
tag_key_name = match.group(1)
need_delete = True
for tag in instance.get_tags():
if tag.get("key") == tag_key_name and tag.get(
"value"
) in filters.get(key):
need_delete = False
elif tag.get("key") == tag_key_name and tag.get(
"value"
) not in filters.get(key):
need_delete = True
if need_delete:
result.remove(instance)
return result

View File

@ -1,7 +1,5 @@
TestAccAWSEc2TransitGatewayDxGatewayAttachmentDataSource TestAccAWSEc2TransitGatewayDxGatewayAttachmentDataSource
TestAccAWSEc2TransitGatewayPeeringAttachment
TestAccAWSEc2TransitGatewayPeeringAttachmentAccepter TestAccAWSEc2TransitGatewayPeeringAttachmentAccepter
TestAccAWSEc2TransitGatewayPeeringAttachmentDataSource
TestAccAWSEc2TransitGatewayRouteTableAssociation TestAccAWSEc2TransitGatewayRouteTableAssociation
TestAccAWSEc2TransitGatewayVpcAttachment TestAccAWSEc2TransitGatewayVpcAttachment
TestAccAWSFms TestAccAWSFms

View File

@ -39,6 +39,8 @@ TestAccAWSEc2TransitGatewayVpcAttachment_SharedTransitGateway
TestAccAWSEc2TransitGatewayVpcAttachmentAccepter TestAccAWSEc2TransitGatewayVpcAttachmentAccepter
TestAccAWSEc2TransitGatewayVpcAttachmentDataSource TestAccAWSEc2TransitGatewayVpcAttachmentDataSource
TestAccAWSEc2TransitGatewayVpnAttachmentDataSource TestAccAWSEc2TransitGatewayVpnAttachmentDataSource
TestAccAWSEc2TransitGatewayPeeringAttachment
TestAccAWSEc2TransitGatewayPeeringAttachmentDataSource
TestAccAWSElasticBeanstalkSolutionStackDataSource TestAccAWSElasticBeanstalkSolutionStackDataSource
TestAccAWSElbHostedZoneId TestAccAWSElbHostedZoneId
TestAccAWSElbServiceAccount TestAccAWSElbServiceAccount