2023-09-27 12:50:26 +00:00
|
|
|
import os
|
2023-11-30 15:55:51 +00:00
|
|
|
from unittest import SkipTest, mock
|
2023-09-27 12:50:26 +00:00
|
|
|
|
2021-08-03 14:06:06 +00:00
|
|
|
import boto3
|
2023-09-27 12:50:26 +00:00
|
|
|
import pytest
|
|
|
|
from botocore.exceptions import ClientError
|
|
|
|
|
2021-10-05 17:11:07 +00:00
|
|
|
from moto import mock_ec2, settings
|
2022-08-13 09:49:43 +00:00
|
|
|
from moto.core import DEFAULT_ACCOUNT_ID as ACCOUNT_ID
|
2021-08-03 14:06:06 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_ec2
|
|
|
|
def test_describe_transit_gateway_peering_attachment_empty():
|
2021-10-05 17:11:07 +00:00
|
|
|
if settings.TEST_SERVER_MODE:
|
|
|
|
raise SkipTest("ServerMode is not guaranteed to be empty")
|
2021-08-03 14:06:06 +00:00
|
|
|
ec2 = boto3.client("ec2", region_name="us-west-1")
|
|
|
|
|
|
|
|
all_attachments = ec2.describe_transit_gateway_peering_attachments()[
|
|
|
|
"TransitGatewayPeeringAttachments"
|
|
|
|
]
|
2023-07-17 09:31:05 +00:00
|
|
|
assert all_attachments == []
|
2021-08-03 14:06:06 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_ec2
|
|
|
|
def test_create_and_describe_transit_gateway_peering_attachment():
|
|
|
|
ec2 = boto3.client("ec2", region_name="us-west-1")
|
|
|
|
gateway_id1 = ec2.create_transit_gateway(Description="my first gateway")[
|
|
|
|
"TransitGateway"
|
|
|
|
]["TransitGatewayId"]
|
|
|
|
gateway_id2 = ec2.create_transit_gateway(Description="my second gateway")[
|
|
|
|
"TransitGateway"
|
|
|
|
]["TransitGatewayId"]
|
|
|
|
response = ec2.create_transit_gateway_peering_attachment(
|
|
|
|
TransitGatewayId=gateway_id1,
|
|
|
|
PeerTransitGatewayId=gateway_id2,
|
|
|
|
PeerAccountId=ACCOUNT_ID,
|
|
|
|
PeerRegion="us-east-1",
|
|
|
|
)
|
2023-07-17 09:31:05 +00:00
|
|
|
assert "TransitGatewayPeeringAttachment" in response
|
2021-08-03 14:06:06 +00:00
|
|
|
attachment = response["TransitGatewayPeeringAttachment"]
|
2023-07-17 09:31:05 +00:00
|
|
|
assert attachment["TransitGatewayAttachmentId"].startswith("tgw-attach-")
|
|
|
|
assert attachment["RequesterTgwInfo"]["TransitGatewayId"] == gateway_id1
|
|
|
|
assert attachment["AccepterTgwInfo"]["TransitGatewayId"] == gateway_id2
|
2021-08-03 14:06:06 +00:00
|
|
|
|
|
|
|
all_attachments = ec2.describe_transit_gateway_peering_attachments()[
|
|
|
|
"TransitGatewayPeeringAttachments"
|
|
|
|
]
|
2021-10-05 17:11:07 +00:00
|
|
|
our_attachment = [
|
|
|
|
att
|
|
|
|
for att in all_attachments
|
|
|
|
if att["TransitGatewayAttachmentId"] == attachment["TransitGatewayAttachmentId"]
|
|
|
|
]
|
2023-07-17 09:31:05 +00:00
|
|
|
assert our_attachment == [attachment]
|
2021-08-03 14:06:06 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_ec2
|
|
|
|
def test_describe_transit_gateway_peering_attachment_by_filters():
|
|
|
|
ec2 = boto3.client("ec2", region_name="us-west-1")
|
|
|
|
gateway_id1 = ec2.create_transit_gateway(Description="my first gateway")[
|
|
|
|
"TransitGateway"
|
|
|
|
]["TransitGatewayId"]
|
|
|
|
gateway_id2 = ec2.create_transit_gateway(Description="my second gateway")[
|
|
|
|
"TransitGateway"
|
|
|
|
]["TransitGatewayId"]
|
|
|
|
gateway_id3 = ec2.create_transit_gateway(Description="my second gateway")[
|
|
|
|
"TransitGateway"
|
|
|
|
]["TransitGatewayId"]
|
|
|
|
attchmnt1 = create_peering_attachment(ec2, gateway_id1, gateway_id2)
|
|
|
|
attchmnt2 = create_peering_attachment(ec2, gateway_id1, gateway_id3)
|
|
|
|
attchmnt3 = create_peering_attachment(ec2, gateway_id2, gateway_id3)
|
|
|
|
|
|
|
|
all_attachments = ec2.describe_transit_gateway_peering_attachments()[
|
|
|
|
"TransitGatewayPeeringAttachments"
|
|
|
|
]
|
2021-10-05 17:11:07 +00:00
|
|
|
ours = [
|
|
|
|
a
|
|
|
|
for a in all_attachments
|
|
|
|
if a["TransitGatewayAttachmentId"] in [attchmnt1, attchmnt2, attchmnt3]
|
|
|
|
]
|
2023-07-17 09:31:05 +00:00
|
|
|
assert len(ours) == 3
|
2021-08-03 14:06:06 +00:00
|
|
|
|
|
|
|
find_1 = ec2.describe_transit_gateway_peering_attachments(
|
|
|
|
TransitGatewayAttachmentIds=[attchmnt1]
|
|
|
|
)["TransitGatewayPeeringAttachments"]
|
2023-07-17 09:31:05 +00:00
|
|
|
assert [a["TransitGatewayAttachmentId"] for a in find_1] == [attchmnt1]
|
2021-08-03 14:06:06 +00:00
|
|
|
|
|
|
|
find_1_3 = ec2.describe_transit_gateway_peering_attachments(
|
|
|
|
TransitGatewayAttachmentIds=[attchmnt1, attchmnt3]
|
|
|
|
)["TransitGatewayPeeringAttachments"]
|
2023-07-17 09:31:05 +00:00
|
|
|
assert [a["TransitGatewayAttachmentId"] for a in find_1_3] == [attchmnt1, attchmnt3]
|
2021-08-03 14:06:06 +00:00
|
|
|
|
|
|
|
find_3 = ec2.describe_transit_gateway_peering_attachments(
|
|
|
|
Filters=[{"Name": "transit-gateway-attachment-id", "Values": [attchmnt3]}]
|
|
|
|
)["TransitGatewayPeeringAttachments"]
|
2023-07-17 09:31:05 +00:00
|
|
|
assert [a["TransitGatewayAttachmentId"] for a in find_3] == [attchmnt3]
|
2021-08-03 14:06:06 +00:00
|
|
|
|
2023-09-27 12:50:26 +00:00
|
|
|
filters = [{"Name": "state", "Values": ["pendingAcceptance"]}]
|
2021-10-05 17:11:07 +00:00
|
|
|
find_all = retrieve_all_attachments(ec2, filters)
|
|
|
|
all_ids = [a["TransitGatewayAttachmentId"] for a in find_all]
|
2023-07-17 09:31:05 +00:00
|
|
|
assert attchmnt1 in all_ids
|
|
|
|
assert attchmnt2 in all_ids
|
|
|
|
assert attchmnt3 in all_ids
|
2021-08-03 14:06:06 +00:00
|
|
|
|
|
|
|
find_none = ec2.describe_transit_gateway_peering_attachments(
|
|
|
|
Filters=[{"Name": "state", "Values": ["unknown"]}]
|
|
|
|
)["TransitGatewayPeeringAttachments"]
|
2023-07-17 09:31:05 +00:00
|
|
|
assert find_none == []
|
2021-08-03 14:06:06 +00:00
|
|
|
|
|
|
|
ec2.reject_transit_gateway_peering_attachment(TransitGatewayAttachmentId=attchmnt2)
|
|
|
|
|
|
|
|
find_available = ec2.describe_transit_gateway_peering_attachments(
|
|
|
|
TransitGatewayAttachmentIds=[attchmnt1, attchmnt2],
|
2023-09-27 12:50:26 +00:00
|
|
|
Filters=[{"Name": "state", "Values": ["pendingAcceptance"]}],
|
2021-08-03 14:06:06 +00:00
|
|
|
)["TransitGatewayPeeringAttachments"]
|
2023-07-17 09:31:05 +00:00
|
|
|
assert [a["TransitGatewayAttachmentId"] for a in find_available] == [attchmnt1]
|
2021-08-03 14:06:06 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_ec2
|
|
|
|
def test_create_and_accept_transit_gateway_peering_attachment():
|
|
|
|
ec2 = boto3.client("ec2", region_name="us-west-1")
|
|
|
|
gateway_id1 = ec2.create_transit_gateway(Description="my first gateway")[
|
|
|
|
"TransitGateway"
|
|
|
|
]["TransitGatewayId"]
|
|
|
|
gateway_id2 = ec2.create_transit_gateway(Description="my second gateway")[
|
|
|
|
"TransitGateway"
|
|
|
|
]["TransitGatewayId"]
|
2023-09-27 12:50:26 +00:00
|
|
|
attchment_id = create_peering_attachment(
|
|
|
|
ec2, gateway_id1, gateway_id2, peer_region="us-west-1"
|
|
|
|
)
|
2021-08-03 14:06:06 +00:00
|
|
|
|
|
|
|
ec2.accept_transit_gateway_peering_attachment(
|
|
|
|
TransitGatewayAttachmentId=attchment_id
|
|
|
|
)
|
|
|
|
|
2021-10-05 17:11:07 +00:00
|
|
|
attachment = ec2.describe_transit_gateway_peering_attachments(
|
|
|
|
TransitGatewayAttachmentIds=[attchment_id]
|
|
|
|
)["TransitGatewayPeeringAttachments"][0]
|
2023-07-17 09:31:05 +00:00
|
|
|
assert attachment["TransitGatewayAttachmentId"] == attchment_id
|
|
|
|
assert attachment["State"] == "available"
|
2021-08-03 14:06:06 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_ec2
|
|
|
|
def test_create_and_reject_transit_gateway_peering_attachment():
|
|
|
|
ec2 = boto3.client("ec2", region_name="us-west-1")
|
|
|
|
gateway_id1 = ec2.create_transit_gateway(Description="my first gateway")[
|
|
|
|
"TransitGateway"
|
|
|
|
]["TransitGatewayId"]
|
|
|
|
gateway_id2 = ec2.create_transit_gateway(Description="my second gateway")[
|
|
|
|
"TransitGateway"
|
|
|
|
]["TransitGatewayId"]
|
|
|
|
attchment_id = create_peering_attachment(ec2, gateway_id1, gateway_id2)
|
|
|
|
|
|
|
|
ec2.reject_transit_gateway_peering_attachment(
|
|
|
|
TransitGatewayAttachmentId=attchment_id
|
|
|
|
)
|
|
|
|
|
2021-10-05 17:11:07 +00:00
|
|
|
attachment = ec2.describe_transit_gateway_peering_attachments(
|
|
|
|
TransitGatewayAttachmentIds=[attchment_id]
|
|
|
|
)["TransitGatewayPeeringAttachments"][0]
|
2023-07-17 09:31:05 +00:00
|
|
|
assert attachment["TransitGatewayAttachmentId"] == attchment_id
|
|
|
|
assert attachment["State"] == "rejected"
|
2021-08-03 14:06:06 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_ec2
|
|
|
|
def test_create_and_delete_transit_gateway_peering_attachment():
|
|
|
|
ec2 = boto3.client("ec2", region_name="us-west-1")
|
|
|
|
gateway_id1 = ec2.create_transit_gateway(Description="my first gateway")[
|
|
|
|
"TransitGateway"
|
|
|
|
]["TransitGatewayId"]
|
|
|
|
gateway_id2 = ec2.create_transit_gateway(Description="my second gateway")[
|
|
|
|
"TransitGateway"
|
|
|
|
]["TransitGatewayId"]
|
|
|
|
attchment_id = create_peering_attachment(ec2, gateway_id1, gateway_id2)
|
|
|
|
|
|
|
|
ec2.delete_transit_gateway_peering_attachment(
|
|
|
|
TransitGatewayAttachmentId=attchment_id
|
|
|
|
)
|
|
|
|
|
2021-10-05 17:11:07 +00:00
|
|
|
attachment = ec2.describe_transit_gateway_peering_attachments(
|
|
|
|
TransitGatewayAttachmentIds=[attchment_id]
|
|
|
|
)["TransitGatewayPeeringAttachments"][0]
|
2023-07-17 09:31:05 +00:00
|
|
|
assert attachment["TransitGatewayAttachmentId"] == attchment_id
|
|
|
|
assert attachment["State"] == "deleted"
|
2021-08-03 14:06:06 +00:00
|
|
|
|
|
|
|
|
2023-09-27 12:50:26 +00:00
|
|
|
@mock_ec2
|
|
|
|
@pytest.mark.parametrize(
|
|
|
|
"account1,account2",
|
|
|
|
[
|
|
|
|
pytest.param("111111111111", "111111111111", id="within account"),
|
|
|
|
pytest.param("111111111111", "222222222222", id="across accounts"),
|
|
|
|
],
|
|
|
|
)
|
|
|
|
@pytest.mark.skipif(
|
|
|
|
settings.TEST_SERVER_MODE, reason="Cannot set account ID in server mode"
|
|
|
|
)
|
|
|
|
def test_transit_gateway_peering_attachments_cross_region(account1, account2):
|
|
|
|
# create transit gateways
|
|
|
|
with mock.patch.dict(os.environ, {"MOTO_ACCOUNT_ID": account1}):
|
|
|
|
ec2_us = boto3.client("ec2", "us-west-1")
|
|
|
|
gateway_us = ec2_us.create_transit_gateway()["TransitGateway"][
|
|
|
|
"TransitGatewayId"
|
|
|
|
]
|
|
|
|
|
|
|
|
with mock.patch.dict(os.environ, {"MOTO_ACCOUNT_ID": account2}):
|
|
|
|
ec2_eu = boto3.client("ec2", "eu-central-1")
|
|
|
|
gateway_eu = ec2_eu.create_transit_gateway()["TransitGateway"][
|
|
|
|
"TransitGatewayId"
|
|
|
|
]
|
|
|
|
|
|
|
|
# create peering
|
|
|
|
with mock.patch.dict(os.environ, {"MOTO_ACCOUNT_ID": account1}):
|
|
|
|
attachment_id = create_peering_attachment(
|
|
|
|
ec2_us,
|
|
|
|
gateway_us,
|
|
|
|
gateway_eu,
|
|
|
|
peer_account=account2,
|
|
|
|
peer_region="eu-central-1",
|
|
|
|
)
|
|
|
|
|
|
|
|
# ensure peering can be described by the accepter
|
|
|
|
with mock.patch.dict(os.environ, {"MOTO_ACCOUNT_ID": account2}):
|
|
|
|
response = ec2_eu.describe_transit_gateway_peering_attachments(
|
|
|
|
TransitGatewayAttachmentIds=[attachment_id]
|
|
|
|
)["TransitGatewayPeeringAttachments"][0]
|
|
|
|
assert response["TransitGatewayAttachmentId"] == attachment_id
|
|
|
|
assert response["RequesterTgwInfo"]["OwnerId"] == account1
|
|
|
|
assert response["RequesterTgwInfo"]["Region"] == "us-west-1"
|
|
|
|
assert response["AccepterTgwInfo"]["OwnerId"] == account2
|
|
|
|
assert response["AccepterTgwInfo"]["Region"] == "eu-central-1"
|
|
|
|
|
|
|
|
# ensure accepting in requester account/region raises
|
|
|
|
with mock.patch.dict(os.environ, {"MOTO_ACCOUNT_ID": account1}):
|
|
|
|
with pytest.raises(ClientError) as exc:
|
|
|
|
ec2_us.accept_transit_gateway_peering_attachment(
|
|
|
|
TransitGatewayAttachmentId=attachment_id
|
|
|
|
)
|
|
|
|
assert exc.value.response["Error"]["Code"] == "InvalidParameterValue"
|
|
|
|
assert (
|
|
|
|
exc.value.response["Error"]["Message"]
|
|
|
|
== f"Cannot accept {attachment_id} as the source of the peering request."
|
|
|
|
)
|
|
|
|
|
|
|
|
with mock.patch.dict(os.environ, {"MOTO_ACCOUNT_ID": account2}):
|
|
|
|
# ensure peering can be accepted by the accepter
|
|
|
|
response = ec2_eu.accept_transit_gateway_peering_attachment(
|
|
|
|
TransitGatewayAttachmentId=attachment_id
|
|
|
|
)
|
|
|
|
assert response["TransitGatewayPeeringAttachment"]["State"] == "available"
|
|
|
|
|
|
|
|
# ensure peering can be deleted by the accepter
|
|
|
|
response = ec2_eu.delete_transit_gateway_peering_attachment(
|
|
|
|
TransitGatewayAttachmentId=attachment_id
|
|
|
|
)
|
|
|
|
assert response["TransitGatewayPeeringAttachment"]["State"] == "deleted"
|
|
|
|
|
|
|
|
|
|
|
|
def create_peering_attachment(
|
|
|
|
ec2, gateway_id1, gateway_id2, peer_account=ACCOUNT_ID, peer_region="us-east-1"
|
|
|
|
):
|
2021-08-03 14:06:06 +00:00
|
|
|
return ec2.create_transit_gateway_peering_attachment(
|
|
|
|
TransitGatewayId=gateway_id1,
|
|
|
|
PeerTransitGatewayId=gateway_id2,
|
2023-09-27 12:50:26 +00:00
|
|
|
PeerAccountId=peer_account,
|
|
|
|
PeerRegion=peer_region,
|
2021-08-03 14:06:06 +00:00
|
|
|
)["TransitGatewayPeeringAttachment"]["TransitGatewayAttachmentId"]
|
2021-10-05 17:11:07 +00:00
|
|
|
|
|
|
|
|
2021-10-18 19:44:29 +00:00
|
|
|
def retrieve_all_attachments(client, filters=[]): # pylint: disable=W0102
|
2021-10-05 17:11:07 +00:00
|
|
|
resp = client.describe_transit_gateway_peering_attachments(Filters=filters)
|
|
|
|
attmnts = resp["TransitGatewayPeeringAttachments"]
|
|
|
|
token = resp.get("NextToken")
|
|
|
|
while token:
|
|
|
|
resp = client.describe_transit_gateway_peering_attachments(
|
|
|
|
Filters=filters, NextToken=token
|
|
|
|
)
|
|
|
|
attmnts.extend(resp["TransitGatewayPeeringAttachments"])
|
|
|
|
token = resp.get("NextToken")
|
|
|
|
return attmnts
|