moto/tests/test_ec2/test_vpc_peering.py
2023-11-30 14:55:51 -01:00

755 lines
30 KiB
Python

import os
from unittest import mock
import boto3
import pytest
from botocore.exceptions import ClientError
from moto import mock_ec2, settings
def create_vpx_pcx(ec2, client):
vpc = ec2.create_vpc(CidrBlock="10.0.0.0/16")
peer_vpc = ec2.create_vpc(CidrBlock="11.0.0.0/16")
vpc_pcx = client.create_vpc_peering_connection(VpcId=vpc.id, PeerVpcId=peer_vpc.id)
vpc_pcx = vpc_pcx["VpcPeeringConnection"]
return vpc_pcx
@mock_ec2
def test_vpc_peering_connections_boto3():
ec2 = boto3.resource("ec2", region_name="us-east-1")
client = boto3.client("ec2", region_name="us-east-1")
vpc_pcx = create_vpx_pcx(ec2, client)
assert "VpcPeeringConnectionId" in vpc_pcx
assert vpc_pcx["Status"]["Code"] == "initiating-request"
@mock_ec2
def test_vpc_peering_connections_get_all_boto3():
ec2 = boto3.resource("ec2", region_name="us-east-1")
client = boto3.client("ec2", region_name="us-east-1")
vpc_pcx = create_vpx_pcx(ec2, client)
vpc_pcx_id = vpc_pcx["VpcPeeringConnectionId"]
all_vpc_pcxs = retrieve_all(client)
assert vpc_pcx_id in [vpc_pcx["VpcPeeringConnectionId"] for vpc_pcx in all_vpc_pcxs]
my_vpc_pcx = [
vpc_pcx
for vpc_pcx in all_vpc_pcxs
if vpc_pcx["VpcPeeringConnectionId"] == vpc_pcx_id
][0]
assert my_vpc_pcx["Status"]["Code"] == "pending-acceptance"
assert my_vpc_pcx["Status"]["Message"] == "Pending Acceptance by 123456789012"
@mock_ec2
def test_vpc_peering_connections_accept_boto3():
ec2 = boto3.resource("ec2", region_name="us-east-1")
client = boto3.client("ec2", region_name="us-east-1")
vpc_pcx = create_vpx_pcx(ec2, client)
vpc_pcx_id = vpc_pcx["VpcPeeringConnectionId"]
vpc_pcx = client.accept_vpc_peering_connection(VpcPeeringConnectionId=vpc_pcx_id)
vpc_pcx = vpc_pcx["VpcPeeringConnection"]
assert vpc_pcx["Status"]["Code"] == "active"
with pytest.raises(ClientError) as ex:
client.reject_vpc_peering_connection(VpcPeeringConnectionId=vpc_pcx_id)
assert ex.value.response["ResponseMetadata"]["HTTPStatusCode"] == 400
assert "RequestId" in ex.value.response["ResponseMetadata"]
assert ex.value.response["Error"]["Code"] == "InvalidStateTransition"
my_vpc_pcxs = client.describe_vpc_peering_connections(
VpcPeeringConnectionIds=[vpc_pcx_id]
)["VpcPeeringConnections"]
assert len(my_vpc_pcxs) == 1
assert my_vpc_pcxs[0]["Status"]["Code"] == "active"
@mock_ec2
def test_vpc_peering_connections_reject_boto3():
ec2 = boto3.resource("ec2", region_name="us-east-1")
client = boto3.client("ec2", region_name="us-east-1")
vpc_pcx = create_vpx_pcx(ec2, client)
vpc_pcx_id = vpc_pcx["VpcPeeringConnectionId"]
client.reject_vpc_peering_connection(VpcPeeringConnectionId=vpc_pcx_id)
with pytest.raises(ClientError) as ex:
client.accept_vpc_peering_connection(VpcPeeringConnectionId=vpc_pcx_id)
assert ex.value.response["ResponseMetadata"]["HTTPStatusCode"] == 400
assert "RequestId" in ex.value.response["ResponseMetadata"]
assert ex.value.response["Error"]["Code"] == "InvalidStateTransition"
my_pcxs = client.describe_vpc_peering_connections(
VpcPeeringConnectionIds=[vpc_pcx_id]
)["VpcPeeringConnections"]
assert len(my_pcxs) == 1
assert my_pcxs[0]["Status"]["Code"] == "rejected"
@mock_ec2
def test_vpc_peering_connections_delete_boto3():
ec2 = boto3.resource("ec2", region_name="us-east-1")
client = boto3.client("ec2", region_name="us-east-1")
vpc_pcx = create_vpx_pcx(ec2, client)
vpc_pcx_id = vpc_pcx["VpcPeeringConnectionId"]
client.delete_vpc_peering_connection(VpcPeeringConnectionId=vpc_pcx_id)
all_vpc_pcxs = retrieve_all(client)
assert vpc_pcx_id in [vpcx["VpcPeeringConnectionId"] for vpcx in all_vpc_pcxs]
my_vpcx = [
vpcx for vpcx in all_vpc_pcxs if vpcx["VpcPeeringConnectionId"] == vpc_pcx_id
][0]
assert my_vpcx["Status"]["Code"] == "deleted"
with pytest.raises(ClientError) as ex:
client.delete_vpc_peering_connection(VpcPeeringConnectionId="pcx-1234abcd")
assert ex.value.response["ResponseMetadata"]["HTTPStatusCode"] == 400
assert "RequestId" in ex.value.response["ResponseMetadata"]
assert (
ex.value.response["Error"]["Code"] == "InvalidVpcPeeringConnectionId.NotFound"
)
@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_vpc_peering_connections_cross_region(account1, account2):
# create vpc in us-west-1 and ap-northeast-1
with mock.patch.dict(os.environ, {"MOTO_ACCOUNT_ID": account1}):
ec2_usw1 = boto3.resource("ec2", region_name="us-west-1")
vpc_usw1 = ec2_usw1.create_vpc(CidrBlock="10.90.0.0/16")
with mock.patch.dict(os.environ, {"MOTO_ACCOUNT_ID": account2}):
ec2_apn1 = boto3.resource("ec2", region_name="ap-northeast-1")
vpc_apn1 = ec2_apn1.create_vpc(CidrBlock="10.20.0.0/16")
# create peering
with mock.patch.dict(os.environ, {"MOTO_ACCOUNT_ID": account1}):
ec2_usw1 = boto3.client("ec2", region_name="us-west-1")
vpc_pcx_usw1 = ec2_usw1.create_vpc_peering_connection(
VpcId=vpc_usw1.id,
PeerVpcId=vpc_apn1.id,
PeerRegion="ap-northeast-1",
PeerOwnerId=account2,
)
assert (
vpc_pcx_usw1["VpcPeeringConnection"]["Status"]["Code"] == "initiating-request"
)
assert (
vpc_pcx_usw1["VpcPeeringConnection"]["Status"]["Message"]
== f"Initiating Request to {account2}"
)
assert (
vpc_pcx_usw1["VpcPeeringConnection"]["RequesterVpcInfo"]["VpcId"] == vpc_usw1.id
)
assert (
vpc_pcx_usw1["VpcPeeringConnection"]["RequesterVpcInfo"]["CidrBlock"]
== "10.90.0.0/16"
)
assert (
vpc_pcx_usw1["VpcPeeringConnection"]["RequesterVpcInfo"]["OwnerId"] == account1
)
assert (
vpc_pcx_usw1["VpcPeeringConnection"]["RequesterVpcInfo"]["Region"]
== "us-west-1"
)
assert (
vpc_pcx_usw1["VpcPeeringConnection"]["AccepterVpcInfo"]["VpcId"] == vpc_apn1.id
)
assert (
vpc_pcx_usw1["VpcPeeringConnection"]["AccepterVpcInfo"]["CidrBlock"]
== "10.20.0.0/16"
)
assert (
vpc_pcx_usw1["VpcPeeringConnection"]["AccepterVpcInfo"]["OwnerId"] == account2
)
assert (
vpc_pcx_usw1["VpcPeeringConnection"]["AccepterVpcInfo"]["Region"]
== "ap-northeast-1"
)
# test cross region vpc peering connection exist
with mock.patch.dict(os.environ, {"MOTO_ACCOUNT_ID": account2}):
vpc_pcx_apn1 = ec2_apn1.VpcPeeringConnection(
vpc_pcx_usw1["VpcPeeringConnection"]["VpcPeeringConnectionId"]
)
assert (
vpc_pcx_apn1.id
== vpc_pcx_usw1["VpcPeeringConnection"]["VpcPeeringConnectionId"]
)
assert vpc_pcx_apn1.requester_vpc.id == vpc_usw1.id
assert vpc_pcx_apn1.accepter_vpc.id == vpc_apn1.id
# Quick check to verify the options have a default value
accepter_options = vpc_pcx_apn1.accepter_vpc_info["PeeringOptions"]
assert accepter_options["AllowDnsResolutionFromRemoteVpc"] is False
assert accepter_options["AllowEgressFromLocalClassicLinkToRemoteVpc"] is False
assert accepter_options["AllowEgressFromLocalVpcToRemoteClassicLink"] is False
requester_options = vpc_pcx_apn1.requester_vpc_info["PeeringOptions"]
assert requester_options["AllowDnsResolutionFromRemoteVpc"] is False
assert requester_options["AllowEgressFromLocalClassicLinkToRemoteVpc"] is False
assert requester_options["AllowEgressFromLocalVpcToRemoteClassicLink"] is False
@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_modify_vpc_peering_connections_accepter_only(account1, account2):
# create vpc in us-west-1 and ap-northeast-1
with mock.patch.dict(os.environ, {"MOTO_ACCOUNT_ID": account1}):
ec2_usw1 = boto3.resource("ec2", region_name="us-west-1")
client = boto3.client("ec2", region_name="us-west-1")
vpc_usw1 = ec2_usw1.create_vpc(CidrBlock="10.90.0.0/16")
with mock.patch.dict(os.environ, {"MOTO_ACCOUNT_ID": account2}):
ec2_apn1 = boto3.resource("ec2", region_name="ap-northeast-1")
vpc_apn1 = ec2_apn1.create_vpc(CidrBlock="10.20.0.0/16")
# create peering
with mock.patch.dict(os.environ, {"MOTO_ACCOUNT_ID": account1}):
vpc_pcx_usw1 = ec2_usw1.create_vpc_peering_connection(
VpcId=vpc_usw1.id,
PeerVpcId=vpc_apn1.id,
PeerRegion="ap-northeast-1",
PeerOwnerId=account2,
)
# modify peering connection options
client.modify_vpc_peering_connection_options(
VpcPeeringConnectionId=vpc_pcx_usw1.id,
AccepterPeeringConnectionOptions={"AllowDnsResolutionFromRemoteVpc": True},
)
# Accepter options are different
vpc_pcx_usw1.reload()
accepter_options = vpc_pcx_usw1.accepter_vpc_info["PeeringOptions"]
assert accepter_options["AllowDnsResolutionFromRemoteVpc"] is True
assert accepter_options["AllowEgressFromLocalClassicLinkToRemoteVpc"] is False
assert accepter_options["AllowEgressFromLocalVpcToRemoteClassicLink"] is False
# Requester options are untouched
requester_options = vpc_pcx_usw1.requester_vpc_info["PeeringOptions"]
assert requester_options["AllowDnsResolutionFromRemoteVpc"] is False
assert requester_options["AllowEgressFromLocalClassicLinkToRemoteVpc"] is False
assert requester_options["AllowEgressFromLocalVpcToRemoteClassicLink"] is False
@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_modify_vpc_peering_connections_requester_only(account1, account2):
# create vpc in us-west-1 and ap-northeast-1
with mock.patch.dict(os.environ, {"MOTO_ACCOUNT_ID": account1}):
ec2_usw1 = boto3.resource("ec2", region_name="us-west-1")
client = boto3.client("ec2", region_name="us-west-1")
vpc_usw1 = ec2_usw1.create_vpc(CidrBlock="10.90.0.0/16")
with mock.patch.dict(os.environ, {"MOTO_ACCOUNT_ID": account2}):
ec2_apn1 = boto3.resource("ec2", region_name="ap-northeast-1")
vpc_apn1 = ec2_apn1.create_vpc(CidrBlock="10.20.0.0/16")
# create peering
with mock.patch.dict(os.environ, {"MOTO_ACCOUNT_ID": account1}):
vpc_pcx_usw1 = ec2_usw1.create_vpc_peering_connection(
VpcId=vpc_usw1.id,
PeerVpcId=vpc_apn1.id,
PeerRegion="ap-northeast-1",
PeerOwnerId=account2,
)
#
client.modify_vpc_peering_connection_options(
VpcPeeringConnectionId=vpc_pcx_usw1.id,
RequesterPeeringConnectionOptions={
"AllowEgressFromLocalVpcToRemoteClassicLink": True,
},
)
# Requester options are different
vpc_pcx_usw1.reload()
requester_options = vpc_pcx_usw1.requester_vpc_info["PeeringOptions"]
assert requester_options["AllowDnsResolutionFromRemoteVpc"] is False
assert requester_options["AllowEgressFromLocalClassicLinkToRemoteVpc"] is False
assert requester_options["AllowEgressFromLocalVpcToRemoteClassicLink"] is True
# Accepter options are untouched
accepter_options = vpc_pcx_usw1.accepter_vpc_info["PeeringOptions"]
assert accepter_options["AllowDnsResolutionFromRemoteVpc"] is False
assert accepter_options["AllowEgressFromLocalClassicLinkToRemoteVpc"] is False
assert accepter_options["AllowEgressFromLocalVpcToRemoteClassicLink"] is False
@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_modify_vpc_peering_connections_unknown_vpc(account1, account2):
# create vpc in us-west-1 and ap-northeast-1
with mock.patch.dict(os.environ, {"MOTO_ACCOUNT_ID": account1}):
ec2_usw1 = boto3.resource("ec2", region_name="us-west-1")
client = boto3.client("ec2", region_name="us-west-1")
vpc_usw1 = ec2_usw1.create_vpc(CidrBlock="10.90.0.0/16")
with mock.patch.dict(os.environ, {"MOTO_ACCOUNT_ID": account2}):
ec2_apn1 = boto3.resource("ec2", region_name="ap-northeast-1")
vpc_apn1 = ec2_apn1.create_vpc(CidrBlock="10.20.0.0/16")
# create peering
with mock.patch.dict(os.environ, {"MOTO_ACCOUNT_ID": account1}):
ec2_usw1.create_vpc_peering_connection(
VpcId=vpc_usw1.id,
PeerVpcId=vpc_apn1.id,
PeerRegion="ap-northeast-1",
PeerOwnerId=account2,
)
with pytest.raises(ClientError) as ex:
client.modify_vpc_peering_connection_options(
VpcPeeringConnectionId="vpx-unknown",
RequesterPeeringConnectionOptions={},
)
err = ex.value.response["Error"]
assert err["Code"] == "InvalidVpcPeeringConnectionId.NotFound"
assert err["Message"] == "VpcPeeringConnectionID vpx-unknown does not exist."
@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_vpc_peering_connections_cross_region_fail(account1, account2):
# create vpc in us-west-1 and ap-northeast-1
with mock.patch.dict(os.environ, {"MOTO_ACCOUNT_ID": account1}):
ec2_usw1 = boto3.resource("ec2", region_name="us-west-1")
vpc_usw1 = ec2_usw1.create_vpc(CidrBlock="10.90.0.0/16")
with mock.patch.dict(os.environ, {"MOTO_ACCOUNT_ID": account2}):
ec2_apn1 = boto3.resource("ec2", region_name="ap-northeast-1")
vpc_apn1 = ec2_apn1.create_vpc(CidrBlock="10.20.0.0/16")
# create peering wrong region with no vpc
with pytest.raises(ClientError) as cm:
with mock.patch.dict(os.environ, {"MOTO_ACCOUNT_ID": account1}):
ec2_usw1.create_vpc_peering_connection(
VpcId=vpc_usw1.id,
PeerVpcId=vpc_apn1.id,
PeerRegion="ap-northeast-2",
PeerOwnerId=account2,
)
assert cm.value.response["Error"]["Code"] == "InvalidVpcID.NotFound"
@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_describe_vpc_peering_connections_only_returns_requested_id(account1, account2):
# create vpc in us-west-1 and ap-northeast-1
with mock.patch.dict(os.environ, {"MOTO_ACCOUNT_ID": account1}):
ec2_usw1 = boto3.resource("ec2", region_name="us-west-1")
vpc_usw1 = ec2_usw1.create_vpc(CidrBlock="10.90.0.0/16")
with mock.patch.dict(os.environ, {"MOTO_ACCOUNT_ID": account2}):
ec2_apn1 = boto3.resource("ec2", region_name="ap-northeast-1")
vpc_apn1 = ec2_apn1.create_vpc(CidrBlock="10.20.0.0/16")
# create peering
with mock.patch.dict(os.environ, {"MOTO_ACCOUNT_ID": account1}):
vpc_pcx_usw1 = ec2_usw1.create_vpc_peering_connection(
VpcId=vpc_usw1.id,
PeerVpcId=vpc_apn1.id,
PeerRegion="ap-northeast-1",
PeerOwnerId=account2,
)
vpc_pcx_usw2 = ec2_usw1.create_vpc_peering_connection(
VpcId=vpc_usw1.id,
PeerVpcId=vpc_apn1.id,
PeerRegion="ap-northeast-1",
PeerOwnerId=account2,
)
# describe peering
ec2_usw1 = boto3.client("ec2", region_name="us-west-1")
our_vpcx = [vpcx["VpcPeeringConnectionId"] for vpcx in retrieve_all(ec2_usw1)]
assert vpc_pcx_usw1.id in our_vpcx
assert vpc_pcx_usw2.id in our_vpcx
assert vpc_apn1.id not in our_vpcx
both_pcx = ec2_usw1.describe_vpc_peering_connections(
VpcPeeringConnectionIds=[vpc_pcx_usw1.id, vpc_pcx_usw2.id]
)["VpcPeeringConnections"]
assert len(both_pcx) == 2
one_pcx = ec2_usw1.describe_vpc_peering_connections(
VpcPeeringConnectionIds=[vpc_pcx_usw1.id]
)["VpcPeeringConnections"]
assert len(one_pcx) == 1
@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_vpc_peering_connections_cross_region_accept(account1, account2):
# create vpc in us-west-1 and ap-northeast-1
with mock.patch.dict(os.environ, {"MOTO_ACCOUNT_ID": account1}):
ec2_usw1 = boto3.resource("ec2", region_name="us-west-1")
vpc_usw1 = ec2_usw1.create_vpc(CidrBlock="10.90.0.0/16")
with mock.patch.dict(os.environ, {"MOTO_ACCOUNT_ID": account2}):
ec2_apn1 = boto3.resource("ec2", region_name="ap-northeast-1")
vpc_apn1 = ec2_apn1.create_vpc(CidrBlock="10.20.0.0/16")
# create peering
with mock.patch.dict(os.environ, {"MOTO_ACCOUNT_ID": account1}):
vpc_pcx_usw1 = ec2_usw1.create_vpc_peering_connection(
VpcId=vpc_usw1.id,
PeerVpcId=vpc_apn1.id,
PeerRegion="ap-northeast-1",
PeerOwnerId=account2,
)
# accept peering from ap-northeast-1
with mock.patch.dict(os.environ, {"MOTO_ACCOUNT_ID": account2}):
ec2_apn1 = boto3.client("ec2", region_name="ap-northeast-1")
acp_pcx_apn1 = ec2_apn1.accept_vpc_peering_connection(
VpcPeeringConnectionId=vpc_pcx_usw1.id
)
with mock.patch.dict(os.environ, {"MOTO_ACCOUNT_ID": account1}):
ec2_usw1 = boto3.client("ec2", region_name="us-west-1")
des_pcx_apn1 = ec2_usw1.describe_vpc_peering_connections(
VpcPeeringConnectionIds=[vpc_pcx_usw1.id]
)
des_pcx_usw1 = ec2_usw1.describe_vpc_peering_connections(
VpcPeeringConnectionIds=[vpc_pcx_usw1.id]
)
assert acp_pcx_apn1["VpcPeeringConnection"]["Status"]["Code"] == "active"
assert (
acp_pcx_apn1["VpcPeeringConnection"]["AccepterVpcInfo"]["Region"]
== "ap-northeast-1"
)
assert (
acp_pcx_apn1["VpcPeeringConnection"]["RequesterVpcInfo"]["Region"]
== "us-west-1"
)
assert des_pcx_apn1["VpcPeeringConnections"][0]["Status"]["Code"] == "active"
assert (
des_pcx_apn1["VpcPeeringConnections"][0]["AccepterVpcInfo"]["Region"]
== "ap-northeast-1"
)
assert (
des_pcx_apn1["VpcPeeringConnections"][0]["RequesterVpcInfo"]["Region"]
== "us-west-1"
)
assert des_pcx_usw1["VpcPeeringConnections"][0]["Status"]["Code"] == "active"
assert (
des_pcx_usw1["VpcPeeringConnections"][0]["AccepterVpcInfo"]["Region"]
== "ap-northeast-1"
)
assert (
des_pcx_usw1["VpcPeeringConnections"][0]["RequesterVpcInfo"]["Region"]
== "us-west-1"
)
@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_vpc_peering_connections_cross_region_reject(account1, account2):
# create vpc in us-west-1 and ap-northeast-1
with mock.patch.dict(os.environ, {"MOTO_ACCOUNT_ID": account1}):
ec2_usw1 = boto3.resource("ec2", region_name="us-west-1")
vpc_usw1 = ec2_usw1.create_vpc(CidrBlock="10.90.0.0/16")
with mock.patch.dict(os.environ, {"MOTO_ACCOUNT_ID": account2}):
ec2_apn1 = boto3.resource("ec2", region_name="ap-northeast-1")
vpc_apn1 = ec2_apn1.create_vpc(CidrBlock="10.20.0.0/16")
# create peering
with mock.patch.dict(os.environ, {"MOTO_ACCOUNT_ID": account1}):
vpc_pcx_usw1 = ec2_usw1.create_vpc_peering_connection(
VpcId=vpc_usw1.id,
PeerVpcId=vpc_apn1.id,
PeerRegion="ap-northeast-1",
PeerOwnerId=account2,
)
# reject peering from ap-northeast-1
with mock.patch.dict(os.environ, {"MOTO_ACCOUNT_ID": account2}):
ec2_apn1 = boto3.client("ec2", region_name="ap-northeast-1")
rej_pcx_apn1 = ec2_apn1.reject_vpc_peering_connection(
VpcPeeringConnectionId=vpc_pcx_usw1.id
)
with mock.patch.dict(os.environ, {"MOTO_ACCOUNT_ID": account1}):
ec2_usw1 = boto3.client("ec2", region_name="us-west-1")
des_pcx_apn1 = ec2_usw1.describe_vpc_peering_connections(
VpcPeeringConnectionIds=[vpc_pcx_usw1.id]
)
des_pcx_usw1 = ec2_usw1.describe_vpc_peering_connections(
VpcPeeringConnectionIds=[vpc_pcx_usw1.id]
)
assert rej_pcx_apn1["Return"] is True
assert des_pcx_apn1["VpcPeeringConnections"][0]["Status"]["Code"] == "rejected"
assert des_pcx_usw1["VpcPeeringConnections"][0]["Status"]["Code"] == "rejected"
@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_vpc_peering_connections_cross_region_delete(account1, account2):
# create vpc in us-west-1 and ap-northeast-1
with mock.patch.dict(os.environ, {"MOTO_ACCOUNT_ID": account1}):
ec2_usw1 = boto3.resource("ec2", region_name="us-west-1")
vpc_usw1 = ec2_usw1.create_vpc(CidrBlock="10.90.0.0/16")
with mock.patch.dict(os.environ, {"MOTO_ACCOUNT_ID": account2}):
ec2_apn1 = boto3.resource("ec2", region_name="ap-northeast-1")
vpc_apn1 = ec2_apn1.create_vpc(CidrBlock="10.20.0.0/16")
# create peering
with mock.patch.dict(os.environ, {"MOTO_ACCOUNT_ID": account1}):
vpc_pcx_usw1 = ec2_usw1.create_vpc_peering_connection(
VpcId=vpc_usw1.id,
PeerVpcId=vpc_apn1.id,
PeerRegion="ap-northeast-1",
PeerOwnerId=account2,
)
with mock.patch.dict(os.environ, {"MOTO_ACCOUNT_ID": account2}):
# reject peering from ap-northeast-1
ec2_apn1 = boto3.client("ec2", region_name="ap-northeast-1")
del_pcx_apn1 = ec2_apn1.delete_vpc_peering_connection(
VpcPeeringConnectionId=vpc_pcx_usw1.id
)
with mock.patch.dict(os.environ, {"MOTO_ACCOUNT_ID": account1}):
ec2_usw1 = boto3.client("ec2", region_name="us-west-1")
des_pcx_apn1 = ec2_usw1.describe_vpc_peering_connections(
VpcPeeringConnectionIds=[vpc_pcx_usw1.id]
)
des_pcx_usw1 = ec2_usw1.describe_vpc_peering_connections(
VpcPeeringConnectionIds=[vpc_pcx_usw1.id]
)
assert del_pcx_apn1["Return"] is True
assert des_pcx_apn1["VpcPeeringConnections"][0]["Status"]["Code"] == "deleted"
assert (
des_pcx_apn1["VpcPeeringConnections"][0]["Status"]["Message"]
== f"Deleted by {account2}"
)
assert des_pcx_usw1["VpcPeeringConnections"][0]["Status"]["Code"] == "deleted"
assert (
des_pcx_usw1["VpcPeeringConnections"][0]["Status"]["Message"]
== f"Deleted by {account2}"
)
@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_vpc_peering_connections_cross_region_accept_wrong_region(account1, account2):
# create vpc in us-west-1 and ap-northeast-1
with mock.patch.dict(os.environ, {"MOTO_ACCOUNT_ID": account1}):
ec2_usw1 = boto3.resource("ec2", region_name="us-west-1")
vpc_usw1 = ec2_usw1.create_vpc(CidrBlock="10.90.0.0/16")
with mock.patch.dict(os.environ, {"MOTO_ACCOUNT_ID": account2}):
ec2_apn1 = boto3.resource("ec2", region_name="ap-northeast-1")
vpc_apn1 = ec2_apn1.create_vpc(CidrBlock="10.20.0.0/16")
# create peering
with mock.patch.dict(os.environ, {"MOTO_ACCOUNT_ID": account1}):
vpc_pcx_usw1 = ec2_usw1.create_vpc_peering_connection(
VpcId=vpc_usw1.id,
PeerVpcId=vpc_apn1.id,
PeerRegion="ap-northeast-1",
PeerOwnerId=account2,
)
# accept wrong peering from us-west-1 which will raise error
# only applicable for cross-region intra-account peering.
if account1 == account2:
with mock.patch.dict(os.environ, {"MOTO_ACCOUNT_ID": account1}):
ec2_usw1 = boto3.client("ec2", region_name="us-west-1")
with pytest.raises(ClientError) as cm:
ec2_usw1.accept_vpc_peering_connection(
VpcPeeringConnectionId=vpc_pcx_usw1.id
)
assert cm.value.response["Error"]["Code"] == "OperationNotPermitted"
exp_msg = f"Incorrect region (us-west-1) specified for this request. VPC peering connection {vpc_pcx_usw1.id} must be accepted in region ap-northeast-1"
assert cm.value.response["Error"]["Message"] == exp_msg
# Ensure accepting peering from requester account raises
# only applicable for cross-region inter-account peering.
if account1 != account2:
with mock.patch.dict(os.environ, {"MOTO_ACCOUNT_ID": account1}):
ec2_usw1 = boto3.client("ec2", region_name="us-west-1")
with pytest.raises(ClientError) as cm:
ec2_usw1.accept_vpc_peering_connection(
VpcPeeringConnectionId=vpc_pcx_usw1.id
)
assert cm.value.response["Error"]["Code"] == "OperationNotPermitted"
exp_msg = f"User ({account1}) cannot accept peering {vpc_pcx_usw1.id}"
assert cm.value.response["Error"]["Message"] == exp_msg
@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_vpc_peering_connections_cross_region_reject_wrong_region(account1, account2):
# create vpc in us-west-1 and ap-northeast-1
with mock.patch.dict(os.environ, {"MOTO_ACCOUNT_ID": account1}):
ec2_usw1 = boto3.resource("ec2", region_name="us-west-1")
vpc_usw1 = ec2_usw1.create_vpc(CidrBlock="10.90.0.0/16")
with mock.patch.dict(os.environ, {"MOTO_ACCOUNT_ID": account2}):
ec2_apn1 = boto3.resource("ec2", region_name="ap-northeast-1")
vpc_apn1 = ec2_apn1.create_vpc(CidrBlock="10.20.0.0/16")
# create peering
with mock.patch.dict(os.environ, {"MOTO_ACCOUNT_ID": account1}):
vpc_pcx_usw1 = ec2_usw1.create_vpc_peering_connection(
VpcId=vpc_usw1.id,
PeerVpcId=vpc_apn1.id,
PeerRegion="ap-northeast-1",
PeerOwnerId=account2,
)
# reject wrong peering from us-west-1 which will raise error.
# only applicable for cross-region intra-account peering.
if account1 == account2:
with mock.patch.dict(os.environ, {"MOTO_ACCOUNT_ID": account1}):
ec2_usw1 = boto3.client("ec2", region_name="us-west-1")
with pytest.raises(ClientError) as cm:
ec2_usw1.reject_vpc_peering_connection(
VpcPeeringConnectionId=vpc_pcx_usw1.id
)
assert cm.value.response["Error"]["Code"] == "OperationNotPermitted"
exp_msg = f"Incorrect region (us-west-1) specified for this request. VPC peering connection {vpc_pcx_usw1.id} must be accepted or rejected in region ap-northeast-1"
assert cm.value.response["Error"]["Message"] == exp_msg
# Ensure rejecting peering from requester account raises
# only applicable for cross-region inter-account peering.
if account1 != account2:
with mock.patch.dict(os.environ, {"MOTO_ACCOUNT_ID": account1}):
ec2_usw1 = boto3.client("ec2", region_name="us-west-1")
with pytest.raises(ClientError) as cm:
ec2_usw1.reject_vpc_peering_connection(
VpcPeeringConnectionId=vpc_pcx_usw1.id
)
assert cm.value.response["Error"]["Code"] == "OperationNotPermitted"
exp_msg = f"User ({account1}) cannot reject peering {vpc_pcx_usw1.id}"
assert cm.value.response["Error"]["Message"] == exp_msg
def retrieve_all(client):
resp = client.describe_vpc_peering_connections()
all_vpx = resp["VpcPeeringConnections"]
token = resp.get("NextToken")
while token:
resp = client.describe_vpc_peering_connections(NextToken=token)
all_vpx.extend(resp["VpcPeeringConnections"])
token = resp.get("NextToken")
return all_vpx