756 lines
30 KiB
Python
756 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
|