Rewrite deprecated EC2 tests (#3881)

This commit is contained in:
Bert Blommers 2021-09-25 11:13:07 +00:00 committed by GitHub
parent 8e93bfc60b
commit 939b800e96
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
24 changed files with 7076 additions and 286 deletions

View File

@ -268,7 +268,7 @@ CREATE_SNAPSHOT_RESPONSE = """<CreateSnapshotResponse xmlns="http://ec2.amazonaw
<ownerId>{{ snapshot.owner_id }}</ownerId>
<volumeSize>{{ snapshot.volume.size }}</volumeSize>
<description>{{ snapshot.description }}</description>
<encrypted>{{ snapshot.encrypted }}</encrypted>
<encrypted>{{ 'true' if snapshot.encrypted else 'false' }}</encrypted>
<tagSet>
{% for tag in snapshot.get_tags() %}
<item>
@ -309,7 +309,7 @@ DESCRIBE_SNAPSHOTS_RESPONSE = """<DescribeSnapshotsResponse xmlns="http://ec2.am
<ownerId>{{ snapshot.owner_id }}</ownerId>
<volumeSize>{{ snapshot.volume.size }}</volumeSize>
<description>{{ snapshot.description }}</description>
<encrypted>{{ snapshot.encrypted }}</encrypted>
<encrypted>{{ 'true' if snapshot.encrypted else 'false' }}</encrypted>
<tagSet>
{% for tag in snapshot.get_tags() %}
<item>

View File

@ -11,3 +11,5 @@ logging.getLogger("botocore").setLevel(logging.CRITICAL)
# (Source: moto/ec2/resources/amis.json)
EXAMPLE_AMI_ID = "ami-12c6146b"
EXAMPLE_AMI_ID2 = "ami-03cf127a"
EXAMPLE_AMI_PARAVIRTUAL = "ami-fa7cdd89"
EXAMPLE_AMI_WINDOWS = "ami-f4cf1d8d"

View File

@ -12,10 +12,11 @@ import sure # noqa
from moto import mock_ec2_deprecated, mock_ec2
from moto.ec2.models import AMIS, OWNER_ID
from moto.core import ACCOUNT_ID
from tests import EXAMPLE_AMI_ID
from tests import EXAMPLE_AMI_ID, EXAMPLE_AMI_PARAVIRTUAL, EXAMPLE_AMI_WINDOWS
from tests.helpers import requires_boto_gte
# Has boto3 equivalent
@mock_ec2_deprecated
def test_ami_create_and_delete():
conn = boto.connect_ec2("the_key", "the_secret")
@ -94,6 +95,97 @@ def test_ami_create_and_delete():
cm.value.request_id.should_not.be.none
@mock_ec2
def test_ami_create_and_delete_boto3():
ec2 = boto3.client("ec2", region_name="us-east-1")
initial_ami_count = len(AMIS)
ec2.describe_volumes()["Volumes"].should.have.length_of(0)
ec2.describe_snapshots()["Snapshots"].should.have.length_of(initial_ami_count)
reservation = ec2.run_instances(ImageId=EXAMPLE_AMI_ID, MinCount=1, MaxCount=1)
instance = reservation["Instances"][0]
with pytest.raises(ClientError) as ex:
ec2.create_image(
InstanceId=instance["InstanceId"], Name="test-ami", DryRun=True
)
ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(412)
err = ex.value.response["Error"]
err["Code"].should.equal("DryRunOperation")
err["Message"].should.equal(
"An error occurred (DryRunOperation) when calling the CreateImage operation: Request would have succeeded, but DryRun flag is set"
)
image_id = ec2.create_image(
InstanceId=instance["InstanceId"],
Name="test-ami",
Description="this is a test ami",
)["ImageId"]
all_images = ec2.describe_images()["Images"]
set([i["ImageId"] for i in all_images]).should.contain(image_id)
retrieved_image = [i for i in all_images if i["ImageId"] == image_id][0]
retrieved_image.should.have.key("ImageId").equal(image_id)
retrieved_image.should.have.key("VirtualizationType").equal(
instance["VirtualizationType"]
)
retrieved_image.should.have.key("Architecture").equal(instance["Architecture"])
retrieved_image.should.have.key("KernelId").equal(instance["KernelId"])
retrieved_image.should.have.key("Platform").equal(instance["Platform"])
retrieved_image.should.have.key("CreationDate")
ec2.terminate_instances(InstanceIds=[instance["InstanceId"]])
# Ensure we're no longer creating a volume
ec2.describe_volumes()["Volumes"].should.have.length_of(0)
# Validate auto-created snapshot
snapshots = ec2.describe_snapshots()["Snapshots"]
snapshots.should.have.length_of(initial_ami_count + 1)
retrieved_image_snapshot_id = retrieved_image["BlockDeviceMappings"][0]["Ebs"][
"SnapshotId"
]
[s["SnapshotId"] for s in snapshots].should.contain(retrieved_image_snapshot_id)
snapshot = [s for s in snapshots if s["SnapshotId"] == retrieved_image_snapshot_id][
0
]
snapshot["Description"].should.equal(
"Auto-created snapshot for AMI {0}".format(retrieved_image["ImageId"])
)
# root device should be in AMI's block device mappings
root_mapping = [
m
for m in retrieved_image["BlockDeviceMappings"]
if m["DeviceName"] == retrieved_image["RootDeviceName"]
]
root_mapping.should_not.equal([])
# Deregister
with pytest.raises(ClientError) as ex:
ec2.deregister_image(ImageId=image_id, DryRun=True)
ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(412)
err = ex.value.response["Error"]
err["Code"].should.equal("DryRunOperation")
err["Message"].should.equal(
"An error occurred (DryRunOperation) when calling the DeregisterImage operation: Request would have succeeded, but DryRun flag is set"
)
success = ec2.deregister_image(ImageId=image_id)
success["ResponseMetadata"]["HTTPStatusCode"].should.equal(200)
with pytest.raises(ClientError) as ex:
ec2.deregister_image(ImageId=image_id)
ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
err = ex.value.response["Error"]
err["Code"].should.equal("InvalidAMIID.NotFound")
ex.value.response["ResponseMetadata"]["RequestId"].should_not.be.none
# Has boto3 equivalent
@requires_boto_gte("2.14.0")
@mock_ec2_deprecated
def test_ami_copy():
@ -176,6 +268,92 @@ def test_ami_copy():
cm.value.request_id.should_not.be.none
@mock_ec2
def test_ami_copy_boto3():
ec2 = boto3.client("ec2", region_name="us-west-1")
initial_ami_count = len(AMIS)
ec2.describe_volumes()["Volumes"].should.have.length_of(0)
ec2.describe_snapshots()["Snapshots"].should.have.length_of(initial_ami_count)
reservation = ec2.run_instances(ImageId=EXAMPLE_AMI_ID, MinCount=1, MaxCount=1)
instance = reservation["Instances"][0]
source_image_id = ec2.create_image(
InstanceId=instance["InstanceId"],
Name="test-ami",
Description="this is a test ami",
)["ImageId"]
ec2.terminate_instances(InstanceIds=[instance["InstanceId"]])
source_image = ec2.describe_images(ImageIds=[source_image_id])["Images"][0]
with pytest.raises(ClientError) as ex:
ec2.copy_image(
SourceRegion="us-west-1",
SourceImageId=source_image["ImageId"],
Name="test-copy-ami",
Description="this is a test copy ami",
DryRun=True,
)
ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(412)
err = ex.value.response["Error"]
err["Code"].should.equal("DryRunOperation")
err["Message"].should.equal(
"An error occurred (DryRunOperation) when calling the CopyImage operation: Request would have succeeded, but DryRun flag is set"
)
copy_image_ref = ec2.copy_image(
SourceRegion="us-west-1",
SourceImageId=source_image["ImageId"],
Name="test-copy-ami",
Description="this is a test copy ami",
)
copy_image_id = copy_image_ref["ImageId"]
copy_image = ec2.describe_images(ImageIds=[copy_image_id])["Images"][0]
copy_image["Name"].should.equal("test-copy-ami")
copy_image["Description"].should.equal("this is a test copy ami")
copy_image["ImageId"].should.equal(copy_image_id)
copy_image["VirtualizationType"].should.equal(source_image["VirtualizationType"])
copy_image["Architecture"].should.equal(source_image["Architecture"])
copy_image["KernelId"].should.equal(source_image["KernelId"])
copy_image["Platform"].should.equal(source_image["Platform"])
# Ensure we're no longer creating a volume
ec2.describe_volumes()["Volumes"].should.have.length_of(0)
# Validate auto-created snapshot
ec2.describe_snapshots()["Snapshots"].should.have.length_of(initial_ami_count + 2)
copy_image["BlockDeviceMappings"][0]["Ebs"]["SnapshotId"].shouldnt.equal(
source_image["BlockDeviceMappings"][0]["Ebs"]["SnapshotId"]
)
# Copy from non-existent source ID.
with pytest.raises(ClientError) as ex:
ec2.copy_image(
SourceRegion="us-west-1",
SourceImageId="ami-abcd1234",
Name="test-copy-ami",
Description="this is a test copy ami",
)
ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
ex.value.response["ResponseMetadata"].should.have.key("RequestId")
ex.value.response["Error"]["Code"].should.equal("InvalidAMIID.NotFound")
# Copy from non-existent source region.
with pytest.raises(ClientError) as ex:
ec2.copy_image(
SourceRegion="us-east-1",
SourceImageId=source_image["ImageId"],
Name="test-copy-ami",
Description="this is a test copy ami",
)
ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
ex.value.response["ResponseMetadata"].should.have.key("RequestId")
ex.value.response["Error"]["Code"].should.equal("InvalidAMIID.NotFound")
@mock_ec2
def test_copy_image_changes_owner_id():
conn = boto3.client("ec2", region_name="us-east-1")
@ -200,6 +378,7 @@ def test_copy_image_changes_owner_id():
describe_resp["Images"][0]["ImageId"].should.equal(copy_resp["ImageId"])
# Has boto3 equivalent
@mock_ec2_deprecated
def test_ami_tagging():
conn = boto.connect_vpc("the_key", "the_secret")
@ -228,6 +407,36 @@ def test_ami_tagging():
image.tags["a key"].should.equal("some value")
@mock_ec2
def test_ami_tagging_boto3():
ec2 = boto3.client("ec2", region_name="us-east-1")
res = boto3.resource("ec2", region_name="us-east-1")
reservation = ec2.run_instances(ImageId=EXAMPLE_AMI_ID, MinCount=1, MaxCount=1)
instance = reservation["Instances"][0]
image_id = ec2.create_image(
InstanceId=instance["InstanceId"],
Name="test-ami",
Description="this is a test ami",
)["ImageId"]
image = res.Image(image_id)
with pytest.raises(ClientError) as ex:
image.create_tags(Tags=[{"Key": "a key", "Value": "some value"}], DryRun=True)
ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(412)
err = ex.value.response["Error"]
err["Code"].should.equal("DryRunOperation")
err["Message"].should.equal(
"An error occurred (DryRunOperation) when calling the CreateTags operation: Request would have succeeded, but DryRun flag is set"
)
image.create_tags(Tags=[{"Key": "a key", "Value": "some value"}])
image.tags.should.equal([{"Value": "some value", "Key": "a key"}])
image = ec2.describe_images(ImageIds=[image_id])["Images"][0]
image["Tags"].should.equal([{"Value": "some value", "Key": "a key"}])
# Has boto3 equivalent
@mock_ec2_deprecated
def test_ami_create_from_missing_instance():
conn = boto.connect_ec2("the_key", "the_secret")
@ -240,6 +449,20 @@ def test_ami_create_from_missing_instance():
cm.value.request_id.should_not.be.none
@mock_ec2
def test_ami_create_from_missing_instance_boto3():
ec2 = boto3.client("ec2", region_name="us-east-1")
with pytest.raises(ClientError) as ex:
ec2.create_image(
InstanceId="i-abcdefg", Name="test-ami", Description="this is a test ami"
)
ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
ex.value.response["ResponseMetadata"].should.have.key("RequestId")
ex.value.response["Error"]["Code"].should.equal("InvalidInstanceID.NotFound")
# Has boto3 equivalent
@mock_ec2_deprecated
def test_ami_pulls_attributes_from_instance():
conn = boto.connect_ec2("the_key", "the_secret")
@ -252,6 +475,23 @@ def test_ami_pulls_attributes_from_instance():
image.kernel_id.should.equal("test-kernel")
@mock_ec2
def test_ami_pulls_attributes_from_instance_boto3():
ec2 = boto3.client("ec2", region_name="us-east-1")
reservation = ec2.run_instances(ImageId=EXAMPLE_AMI_ID, MinCount=1, MaxCount=1)
instance = reservation["Instances"][0]
ec2.modify_instance_attribute(
InstanceId=instance["InstanceId"], Kernel={"Value": "test-kernel"}
)
image_id = ec2.create_image(InstanceId=instance["InstanceId"], Name="test-ami")[
"ImageId"
]
image = boto3.resource("ec2", region_name="us-east-1").Image(image_id)
image.kernel_id.should.equal("test-kernel")
# Has boto3 equivalent
@mock_ec2_deprecated
def test_ami_uses_account_id_if_valid_access_key_is_supplied():
access_key = "AKIAXXXXXXXXXXXXXXXX"
@ -265,6 +505,29 @@ def test_ami_uses_account_id_if_valid_access_key_is_supplied():
[(ami.id, ami.owner_id) for ami in images].should.equal([(image_id, ACCOUNT_ID)])
@mock_ec2
def test_ami_uses_account_id_if_valid_access_key_is_supplied_boto3():
# The boto-equivalent required an access_key to be passed in, but Moto will always mock this in boto3
# So the only thing we're testing here, really.. is whether OwnerId is equal to ACCOUNT_ID?
# TODO: Maybe patch account_id with multiple values, and verify it always matches with OwnerId
# TODO: And probably remove the modify_instance_attribute, as it looks like it was a unnecessary copy-paste
ec2 = boto3.client("ec2", region_name="us-east-1")
reservation = ec2.run_instances(ImageId=EXAMPLE_AMI_ID, MinCount=1, MaxCount=1)
instance = reservation["Instances"][0]
ec2.modify_instance_attribute(
InstanceId=instance["InstanceId"], Kernel={"Value": "test-kernel"}
)
image_id = ec2.create_image(InstanceId=instance["InstanceId"], Name="test-ami")[
"ImageId"
]
images = ec2.describe_images(Owners=["self"])["Images"]
[(ami["ImageId"], ami["OwnerId"]) for ami in images].should.equal(
[(image_id, ACCOUNT_ID)]
)
# Has boto3 equivalent
@mock_ec2_deprecated
def test_ami_filters():
conn = boto.connect_ec2("the_key", "the_secret")
@ -326,6 +589,87 @@ def test_ami_filters():
len(amis_by_nonpublic).should.equal(1)
@mock_ec2
def test_ami_filters_boto3():
ec2 = boto3.client("ec2", region_name="us-east-1")
reservationA = ec2.run_instances(ImageId=EXAMPLE_AMI_ID, MinCount=1, MaxCount=1)
instanceA = reservationA["Instances"][0]
ec2.modify_instance_attribute(
InstanceId=instanceA["InstanceId"], Kernel={"Value": "k-1234abcd"}
)
imageA_id = ec2.create_image(InstanceId=instanceA["InstanceId"], Name="test-ami-A")[
"ImageId"
]
imageA = boto3.resource("ec2", region_name="us-east-1").Image(imageA_id)
reservationB = ec2.run_instances(
ImageId=EXAMPLE_AMI_PARAVIRTUAL, MinCount=1, MaxCount=1
)
instanceB = reservationB["Instances"][0]
ec2.modify_instance_attribute(
InstanceId=instanceB["InstanceId"], Kernel={"Value": "k-abcd1234"}
)
imageB_id = ec2.create_image(InstanceId=instanceB["InstanceId"], Name="test-ami-B")[
"ImageId"
]
imageB = boto3.resource("ec2", region_name="us-east-1").Image(imageB_id)
imageB.modify_attribute(LaunchPermission={"Add": [{"Group": "all"}]})
amis_by_architecture = ec2.describe_images(
Filters=[{"Name": "architecture", "Values": ["x86_64"]}]
)["Images"]
[ami["ImageId"] for ami in amis_by_architecture].should.contain(imageB_id)
amis_by_architecture.should.have.length_of(40)
amis_by_kernel = ec2.describe_images(
Filters=[{"Name": "kernel-id", "Values": ["k-abcd1234"]}]
)["Images"]
[ami["ImageId"] for ami in amis_by_kernel].should.equal([imageB.id])
amis_by_virtualization = ec2.describe_images(
Filters=[{"Name": "virtualization-type", "Values": ["paravirtual"]}]
)["Images"]
[ami["ImageId"] for ami in amis_by_virtualization].should.contain(imageB.id)
amis_by_virtualization.should.have.length_of(3)
amis_by_platform = ec2.describe_images(
Filters=[{"Name": "platform", "Values": ["windows"]}]
)["Images"]
[ami["ImageId"] for ami in amis_by_platform].should.contain(imageA_id)
amis_by_platform.should.have.length_of(25)
amis_by_id = ec2.describe_images(
Filters=[{"Name": "image-id", "Values": [imageA_id]}]
)["Images"]
[ami["ImageId"] for ami in amis_by_id].should.equal([imageA_id])
amis_by_state = ec2.describe_images(
Filters=[{"Name": "state", "Values": ["available"]}]
)["Images"]
ami_ids_by_state = [ami["ImageId"] for ami in amis_by_state]
ami_ids_by_state.should.contain(imageA_id)
ami_ids_by_state.should.contain(imageB.id)
amis_by_state.should.have.length_of(40)
amis_by_name = ec2.describe_images(
Filters=[{"Name": "name", "Values": [imageA.name]}]
)["Images"]
[ami["ImageId"] for ami in amis_by_name].should.equal([imageA.id])
amis_by_public = ec2.describe_images(
Filters=[{"Name": "is-public", "Values": ["true"]}]
)["Images"]
amis_by_public.should.have.length_of(38)
amis_by_nonpublic = ec2.describe_images(
Filters=[{"Name": "is-public", "Values": ["false"]}]
)["Images"]
[ami["ImageId"] for ami in amis_by_nonpublic].should.contain(imageA.id)
amis_by_nonpublic.should.have.length_of(2)
# Has boto3 equivalent
@mock_ec2_deprecated
def test_ami_filtering_via_tag():
conn = boto.connect_vpc("the_key", "the_secret")
@ -349,6 +693,38 @@ def test_ami_filtering_via_tag():
set([ami.id for ami in amis_by_tagB]).should.equal(set([imageB.id]))
@mock_ec2
def test_ami_filtering_via_tag_boto3():
ec2 = boto3.client("ec2", region_name="us-east-1")
reservationA = ec2.run_instances(ImageId=EXAMPLE_AMI_ID, MinCount=1, MaxCount=1)
instanceA = reservationA["Instances"][0]
imageA_id = ec2.create_image(InstanceId=instanceA["InstanceId"], Name="test-ami-A")[
"ImageId"
]
imageA = boto3.resource("ec2", region_name="us-east-1").Image(imageA_id)
imageA.create_tags(Tags=[{"Key": "a key", "Value": "some value"}])
reservationB = ec2.run_instances(ImageId=EXAMPLE_AMI_ID, MinCount=1, MaxCount=1)
instanceB = reservationB["Instances"][0]
imageB_id = ec2.create_image(InstanceId=instanceB["InstanceId"], Name="test-ami-B")[
"ImageId"
]
imageB = boto3.resource("ec2", region_name="us-east-1").Image(imageB_id)
imageB.create_tags(Tags=[{"Key": "another key", "Value": "some other value"}])
amis_by_tagA = ec2.describe_images(
Filters=[{"Name": "tag:a key", "Values": ["some value"]}]
)["Images"]
[ami["ImageId"] for ami in amis_by_tagA].should.equal([imageA_id])
amis_by_tagB = ec2.describe_images(
Filters=[{"Name": "tag:another key", "Values": ["some other value"]}]
)["Images"]
[ami["ImageId"] for ami in amis_by_tagB].should.equal([imageB_id])
# Has boto3 equivalent
@mock_ec2_deprecated
def test_getting_missing_ami():
conn = boto.connect_ec2("the_key", "the_secret")
@ -360,6 +736,18 @@ def test_getting_missing_ami():
cm.value.request_id.should_not.be.none
@mock_ec2
def test_getting_missing_ami_boto3():
ec2 = boto3.resource("ec2", region_name="us-east-1")
with pytest.raises(ClientError) as ex:
ec2.Image("ami-missing").load()
ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
ex.value.response["ResponseMetadata"].should.have.key("RequestId")
ex.value.response["Error"]["Code"].should.equal("InvalidAMIID.NotFound")
# Has boto3 equivalent
@mock_ec2_deprecated
def test_getting_malformed_ami():
conn = boto.connect_ec2("the_key", "the_secret")
@ -371,6 +759,18 @@ def test_getting_malformed_ami():
cm.value.request_id.should_not.be.none
@mock_ec2
def test_getting_malformed_ami_boto3():
ec2 = boto3.resource("ec2", region_name="us-east-1")
with pytest.raises(ClientError) as ex:
ec2.Image("foo-missing").load()
ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
ex.value.response["ResponseMetadata"].should.have.key("RequestId")
ex.value.response["Error"]["Code"].should.equal("InvalidAMIID.Malformed")
# Has boto3 equivalent
@mock_ec2_deprecated
def test_ami_attribute_group_permissions():
conn = boto.connect_ec2("the_key", "the_secret")
@ -434,6 +834,73 @@ def test_ami_attribute_group_permissions():
)
@mock_ec2
def test_ami_attribute_group_permissions_boto3():
ec2 = boto3.client("ec2", region_name="us-east-1")
reservation = ec2.run_instances(ImageId=EXAMPLE_AMI_ID, MinCount=1, MaxCount=1)
instance = reservation["Instances"][0]
image_id = ec2.create_image(InstanceId=instance["InstanceId"], Name="test-ami-A")[
"ImageId"
]
image = boto3.resource("ec2", region_name="us-east-1").Image(image_id)
# Baseline
permissions = image.describe_attribute(Attribute="launchPermission")[
"LaunchPermissions"
]
permissions.should.equal([])
ADD_GROUP_ARGS = {
"ImageId": image_id,
"Attribute": "launchPermission",
"OperationType": "add",
"UserGroups": ["all"],
}
REMOVE_GROUP_ARGS = {
"ImageId": image_id,
"Attribute": "launchPermission",
"OperationType": "remove",
"UserGroups": ["all"],
}
# Add 'all' group and confirm
with pytest.raises(ClientError) as ex:
image.modify_attribute(DryRun=True)
ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(412)
ex.value.response["Error"]["Code"].should.equal("DryRunOperation")
ex.value.response["Error"]["Message"].should.equal(
"An error occurred (DryRunOperation) when calling the ModifyImageAttribute operation: Request would have succeeded, but DryRun flag is set"
)
image.modify_attribute(**ADD_GROUP_ARGS)
permissions = image.describe_attribute(Attribute="launchPermission")[
"LaunchPermissions"
]
permissions.should.equal([{"Group": "all"}])
image.reload()
image.public.should.equal(True)
# Add is idempotent
image.modify_attribute(**ADD_GROUP_ARGS)
# Remove 'all' group and confirm
image.modify_attribute(**REMOVE_GROUP_ARGS)
permissions = image.describe_attribute(Attribute="launchPermission")[
"LaunchPermissions"
]
permissions.should.equal([])
image.reload()
image.public.should.equal(False)
# Remove is idempotent
image.modify_attribute(**REMOVE_GROUP_ARGS)
# Has boto3 equivalent
@mock_ec2_deprecated
def test_ami_attribute_user_permissions():
conn = boto.connect_ec2("the_key", "the_secret")
@ -509,6 +976,86 @@ def test_ami_attribute_user_permissions():
)
@mock_ec2
def test_ami_attribute_user_permissions_boto3():
ec2 = boto3.client("ec2", region_name="us-east-1")
reservation = ec2.run_instances(ImageId=EXAMPLE_AMI_ID, MinCount=1, MaxCount=1)
instance = reservation["Instances"][0]
image_id = ec2.create_image(InstanceId=instance["InstanceId"], Name="test-ami-A")[
"ImageId"
]
image = boto3.resource("ec2", region_name="us-east-1").Image(image_id)
# Baseline
permissions = image.describe_attribute(Attribute="launchPermission")[
"LaunchPermissions"
]
permissions.should.equal([])
USER1 = "123456789011"
USER2 = "123456789022"
ADD_USERS_ARGS = {
"ImageId": image.id,
"Attribute": "launchPermission",
"OperationType": "add",
"UserIds": [USER1, USER2],
}
REMOVE_USERS_ARGS = {
"ImageId": image.id,
"Attribute": "launchPermission",
"OperationType": "remove",
"UserIds": [USER1, USER2],
}
REMOVE_SINGLE_USER_ARGS = {
"ImageId": image.id,
"Attribute": "launchPermission",
"OperationType": "remove",
"UserIds": [USER1],
}
# Add multiple users and confirm
image.modify_attribute(**ADD_USERS_ARGS)
permissions = image.describe_attribute(Attribute="launchPermission")[
"LaunchPermissions"
]
permissions.should.have.length_of(2)
permissions.should.contain({"UserId": USER1})
permissions.should.contain({"UserId": USER2})
image.reload()
image.public.should.equal(False)
# Add is idempotent
image.modify_attribute(**ADD_USERS_ARGS)
# Remove single user and confirm
image.modify_attribute(**REMOVE_SINGLE_USER_ARGS)
permissions = image.describe_attribute(Attribute="launchPermission")[
"LaunchPermissions"
]
permissions.should.equal([{"UserId": USER2}])
image.reload()
image.public.should.equal(False)
# Remove multiple users and confirm
image.modify_attribute(**REMOVE_USERS_ARGS)
permissions = image.describe_attribute(Attribute="launchPermission")[
"LaunchPermissions"
]
permissions.should.equal([])
image.reload()
image.public.should.equal(False)
# Remove is idempotent
image.modify_attribute(**REMOVE_USERS_ARGS)
@mock_ec2
def test_ami_describe_executable_users():
conn = boto3.client("ec2", region_name="us-east-1")
@ -613,6 +1160,7 @@ def test_ami_describe_executable_users_and_filter():
images[0]["ImageId"].should.equal(image_id)
# Has boto3 equivalent
@mock_ec2_deprecated
def test_ami_attribute_user_and_group_permissions():
"""
@ -669,6 +1217,72 @@ def test_ami_attribute_user_and_group_permissions():
image.is_public.should.equal(False)
@mock_ec2
def test_ami_attribute_user_and_group_permissions_boto3():
"""
Boto supports adding/removing both users and groups at the same time.
Just spot-check this -- input variations, idempotency, etc are validated
via user-specific and group-specific tests above.
"""
ec2 = boto3.client("ec2", region_name="us-east-1")
reservation = ec2.run_instances(ImageId=EXAMPLE_AMI_ID, MinCount=1, MaxCount=1)
instance = reservation["Instances"][0]
image_id = ec2.create_image(InstanceId=instance["InstanceId"], Name="test-ami-A")[
"ImageId"
]
image = boto3.resource("ec2", region_name="us-east-1").Image(image_id)
# Baseline
permissions = image.describe_attribute(Attribute="launchPermission")[
"LaunchPermissions"
]
permissions.should.equal([])
USER1 = "123456789011"
USER2 = "123456789022"
ADD_ARGS = {
"ImageId": image.id,
"Attribute": "launchPermission",
"OperationType": "add",
"UserGroups": ["all"],
"UserIds": [USER1, USER2],
}
REMOVE_ARGS = {
"ImageId": image.id,
"Attribute": "launchPermission",
"OperationType": "remove",
"UserGroups": ["all"],
"UserIds": [USER1, USER2],
}
# Add and confirm
image.modify_attribute(**ADD_ARGS)
permissions = image.describe_attribute(Attribute="launchPermission")[
"LaunchPermissions"
]
permissions.should.have.length_of(3)
permissions.should.contain({"Group": "all"})
permissions.should.contain({"UserId": "123456789022"})
permissions.should.contain({"UserId": "123456789011"})
image.reload()
image.public.should.equal(True)
# Remove and confirm
image.modify_attribute(**REMOVE_ARGS)
permissions = image.describe_attribute(Attribute="launchPermission")[
"LaunchPermissions"
]
permissions.should.equal([])
image.reload()
image.public.should.equal(False)
# Has boto3 equivalent
@mock_ec2_deprecated
def test_ami_attribute_error_cases():
conn = boto.connect_ec2("the_key", "the_secret")
@ -760,6 +1374,108 @@ def test_ami_attribute_error_cases():
cm.value.request_id.should_not.be.none
@mock_ec2
def test_ami_attribute_error_cases_boto3():
ec2 = boto3.client("ec2", region_name="us-east-1")
reservation = ec2.run_instances(ImageId=EXAMPLE_AMI_ID, MinCount=1, MaxCount=1)
instance = reservation["Instances"][0]
image_id = ec2.create_image(InstanceId=instance["InstanceId"], Name="test-ami-A")[
"ImageId"
]
image = boto3.resource("ec2", region_name="us-east-1").Image(image_id)
# Error: Add with group != 'all'
with pytest.raises(ClientError) as ex:
image.modify_attribute(
ImageId=image_id,
Attribute="launchPermission",
OperationType="add",
UserGroups=["everyone"],
)
ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
ex.value.response["ResponseMetadata"].should.have.key("RequestId")
ex.value.response["Error"]["Code"].should.equal("InvalidAMIAttributeItemValue")
# Error: Add with user ID that isn't an integer.
with pytest.raises(ClientError) as ex:
image.modify_attribute(
ImageId=image_id,
Attribute="launchPermission",
OperationType="add",
UserIds=["12345678901A"],
)
ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
ex.value.response["ResponseMetadata"].should.have.key("RequestId")
ex.value.response["Error"]["Code"].should.equal("InvalidAMIAttributeItemValue")
# Error: Add with user ID that is > length 12.
with pytest.raises(ClientError) as ex:
image.modify_attribute(
ImageId=image_id,
Attribute="launchPermission",
OperationType="add",
UserIds=["1234567890123"],
)
ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
ex.value.response["ResponseMetadata"].should.have.key("RequestId")
ex.value.response["Error"]["Code"].should.equal("InvalidAMIAttributeItemValue")
# Error: Add with user ID that is < length 12.
with pytest.raises(ClientError) as ex:
image.modify_attribute(
ImageId=image_id,
Attribute="launchPermission",
OperationType="add",
UserIds=["12345678901"],
)
ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
ex.value.response["ResponseMetadata"].should.have.key("RequestId")
ex.value.response["Error"]["Code"].should.equal("InvalidAMIAttributeItemValue")
# Error: Add with one invalid user ID among other valid IDs, ensure no
# partial changes.
with pytest.raises(ClientError) as ex:
image.modify_attribute(
ImageId=image_id,
Attribute="launchPermission",
OperationType="add",
UserIds=["123456789011", "foo", "123456789022"],
)
ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
ex.value.response["ResponseMetadata"].should.have.key("RequestId")
ex.value.response["Error"]["Code"].should.equal("InvalidAMIAttributeItemValue")
permissions = image.describe_attribute(Attribute="launchPermission")[
"LaunchPermissions"
]
permissions.should.equal([])
# Error: Add with invalid image ID
with pytest.raises(ClientError) as ex:
image.modify_attribute(
ImageId="ami-abcd1234",
Attribute="launchPermission",
OperationType="add",
UserGroups=["all"],
)
ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
ex.value.response["ResponseMetadata"].should.have.key("RequestId")
ex.value.response["Error"]["Code"].should.equal("InvalidAMIID.NotFound")
# Error: Remove with invalid image ID
with pytest.raises(ClientError) as ex:
image.modify_attribute(
ImageId="ami-abcd1234",
Attribute="launchPermission",
OperationType="remove",
UserGroups=["all"],
)
ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
ex.value.response["ResponseMetadata"].should.have.key("RequestId")
ex.value.response["Error"]["Code"].should.equal("InvalidAMIID.NotFound")
@mock_ec2
def test_ami_describe_non_existent():
ec2 = boto3.resource("ec2", region_name="us-west-1")

View File

@ -7,6 +7,7 @@ import sure # noqa
from moto import mock_ec2, mock_ec2_deprecated
# Has boto3 equivalent
@mock_ec2_deprecated
def test_describe_regions():
conn = boto.connect_ec2("the_key", "the_secret")
@ -16,6 +17,7 @@ def test_describe_regions():
region.endpoint.should.contain(region.name)
# Has boto3 equivalent
@mock_ec2_deprecated
def test_availability_zones():
conn = boto.connect_ec2("the_key", "the_secret")

View File

@ -1,12 +1,15 @@
from __future__ import unicode_literals
import boto
import boto3
import sure # noqa
import pytest
from boto.exception import EC2ResponseError
from botocore.exceptions import ClientError
from moto import mock_ec2_deprecated
from moto import mock_ec2_deprecated, mock_ec2
# Has boto3 equivalent
@mock_ec2_deprecated
def test_create_customer_gateways():
conn = boto.connect_vpc("the_key", "the_secret")
@ -19,6 +22,18 @@ def test_create_customer_gateways():
customer_gateway.ip_address.should.equal("205.251.242.54")
@mock_ec2
def test_create_customer_gateways_boto3():
ec2 = boto3.client("ec2", region_name="us-east-1")
customer_gateway = create_customer_gateway(ec2)
customer_gateway.should.have.key("CustomerGatewayId").match(r"cgw-\w+")
customer_gateway.should.have.key("Type").equal("ipsec.1")
customer_gateway.should.have.key("BgpAsn").equal("65534")
customer_gateway.should.have.key("IpAddress").equal("205.251.242.54")
# Has boto3 equivalent
@mock_ec2_deprecated
def test_describe_customer_gateways():
conn = boto.connect_vpc("the_key", "the_secret")
@ -28,6 +43,17 @@ def test_describe_customer_gateways():
cgws[0].id.should.match(customer_gateway.id)
@mock_ec2
def test_describe_customer_gateways_boto3():
ec2 = boto3.client("ec2", region_name="us-east-1")
customer_gateway = create_customer_gateway(ec2)
cgws = ec2.describe_customer_gateways()["CustomerGateways"]
cgws.should.have.length_of(1)
cgws[0]["CustomerGatewayId"].should.match(customer_gateway["CustomerGatewayId"])
# Has boto3 equivalent
@mock_ec2_deprecated
def test_delete_customer_gateways():
conn = boto.connect_vpc("the_key", "the_secret")
@ -42,8 +68,40 @@ def test_delete_customer_gateways():
cgws.should.have.length_of(1)
@mock_ec2
def test_delete_customer_gateways_boto3():
ec2 = boto3.client("ec2", region_name="us-east-1")
customer_gateway = create_customer_gateway(ec2)
cgws = ec2.describe_customer_gateways()["CustomerGateways"]
cgws.should.have.length_of(1)
ec2.delete_customer_gateway(CustomerGatewayId=customer_gateway["CustomerGatewayId"])
cgws = ec2.describe_customer_gateways()["CustomerGateways"]
cgws.should.have.length_of(1)
cgws[0].should.have.key("State").equal("deleted")
# Has boto3 equivalent
@mock_ec2_deprecated
def test_delete_customer_gateways_bad_id():
conn = boto.connect_vpc("the_key", "the_secret")
with pytest.raises(EC2ResponseError) as cm:
conn.delete_customer_gateway("cgw-0123abcd")
@mock_ec2
def test_delete_customer_gateways_bad_id_boto3():
ec2 = boto3.client("ec2", region_name="us-east-1")
with pytest.raises(ClientError) as ex:
ec2.delete_customer_gateway(CustomerGatewayId="cgw-0123abcd")
ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
ex.value.response["ResponseMetadata"].should.have.key("RequestId")
ex.value.response["Error"]["Code"].should.equal("InvalidCustomerGatewayID.NotFound")
def create_customer_gateway(ec2):
return ec2.create_customer_gateway(
Type="ipsec.1", PublicIp="205.251.242.54", BgpAsn=65534
)["CustomerGateway"]

View File

@ -5,15 +5,18 @@ import pytest
import boto3
import boto
from boto.exception import EC2ResponseError
from botocore.exceptions import ClientError
import sure # noqa
from moto import mock_ec2, mock_ec2_deprecated
from moto import mock_ec2, mock_ec2_deprecated, settings
from unittest import SkipTest
SAMPLE_DOMAIN_NAME = "example.com"
SAMPLE_NAME_SERVERS = ["10.0.0.6", "10.0.0.7"]
# Has boto3 equivalent
@mock_ec2_deprecated
def test_dhcp_options_associate():
"""associate dhcp option"""
@ -25,6 +28,27 @@ def test_dhcp_options_associate():
rval.should.be.equal(True)
@mock_ec2
def test_dhcp_options_associate_boto3():
""" associate dhcp option """
ec2 = boto3.resource("ec2", region_name="us-west-1")
client = boto3.client("ec2", region_name="us-west-1")
dhcp_options = ec2.create_dhcp_options(
DhcpConfigurations=[
{"Key": "domain-name", "Values": [SAMPLE_DOMAIN_NAME]},
{"Key": "domain-name-servers", "Values": SAMPLE_NAME_SERVERS},
]
)
vpc = ec2.create_vpc(CidrBlock="10.0.0.0/16")
client.associate_dhcp_options(DhcpOptionsId=dhcp_options.id, VpcId=vpc.id)
#
vpc.reload()
vpc.dhcp_options_id.should.equal(dhcp_options.id)
# Has boto3 equivalent
@mock_ec2_deprecated
def test_dhcp_options_associate_invalid_dhcp_id():
"""associate dhcp option bad dhcp options id"""
@ -38,6 +62,21 @@ def test_dhcp_options_associate_invalid_dhcp_id():
cm.value.request_id.should_not.be.none
@mock_ec2
def test_dhcp_options_associate_invalid_dhcp_id_boto3():
""" associate dhcp option bad dhcp options id """
ec2 = boto3.resource("ec2", region_name="us-west-1")
client = boto3.client("ec2", region_name="us-west-1")
vpc = ec2.create_vpc(CidrBlock="10.0.0.0/16")
with pytest.raises(ClientError) as ex:
client.associate_dhcp_options(DhcpOptionsId="foo", VpcId=vpc.id)
ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
ex.value.response["ResponseMetadata"].should.have.key("RequestId")
ex.value.response["Error"]["Code"].should.equal("InvalidDhcpOptionID.NotFound")
# Has boto3 equivalent
@mock_ec2_deprecated
def test_dhcp_options_associate_invalid_vpc_id():
"""associate dhcp option invalid vpc id"""
@ -51,6 +90,26 @@ def test_dhcp_options_associate_invalid_vpc_id():
cm.value.request_id.should_not.be.none
@mock_ec2
def test_dhcp_options_associate_invalid_vpc_id_boto3():
""" associate dhcp option invalid vpc id """
ec2 = boto3.resource("ec2", region_name="us-west-1")
client = boto3.client("ec2", region_name="us-west-1")
dhcp_options = ec2.create_dhcp_options(
DhcpConfigurations=[
{"Key": "domain-name", "Values": [SAMPLE_DOMAIN_NAME]},
{"Key": "domain-name-servers", "Values": SAMPLE_NAME_SERVERS},
]
)
with pytest.raises(ClientError) as ex:
client.associate_dhcp_options(DhcpOptionsId=dhcp_options.id, VpcId="foo")
ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
ex.value.response["ResponseMetadata"].should.have.key("RequestId")
ex.value.response["Error"]["Code"].should.equal("InvalidVpcID.NotFound")
# Has boto3 equivalent
@mock_ec2_deprecated
def test_dhcp_options_delete_with_vpc():
"""Test deletion of dhcp options with vpc"""
@ -77,6 +136,37 @@ def test_dhcp_options_delete_with_vpc():
cm.value.request_id.should_not.be.none
@mock_ec2
def test_dhcp_options_delete_with_vpc_boto3():
"""Test deletion of dhcp options with vpc"""
ec2 = boto3.resource("ec2", region_name="us-west-1")
client = boto3.client("ec2", region_name="us-west-1")
dhcp_options = ec2.create_dhcp_options(
DhcpConfigurations=[
{"Key": "domain-name", "Values": [SAMPLE_DOMAIN_NAME]},
{"Key": "domain-name-servers", "Values": SAMPLE_NAME_SERVERS},
]
)
vpc = ec2.create_vpc(CidrBlock="10.0.0.0/16")
client.associate_dhcp_options(DhcpOptionsId=dhcp_options.id, VpcId=vpc.id)
with pytest.raises(ClientError) as ex:
client.delete_dhcp_options(DhcpOptionsId=dhcp_options.id)
ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
ex.value.response["ResponseMetadata"].should.have.key("RequestId")
ex.value.response["Error"]["Code"].should.equal("DependencyViolation")
vpc.delete()
with pytest.raises(ClientError) as ex:
client.describe_dhcp_options(DhcpOptionsIds=[dhcp_options.id])
ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
ex.value.response["ResponseMetadata"].should.have.key("RequestId")
ex.value.response["Error"]["Code"].should.equal("InvalidDhcpOptionID.NotFound")
# Has boto3 equivalent
@mock_ec2_deprecated
def test_create_dhcp_options():
"""Create most basic dhcp option"""
@ -92,6 +182,31 @@ def test_create_dhcp_options():
)
@mock_ec2
def test_create_dhcp_options_boto3():
"""Create most basic dhcp option"""
ec2 = boto3.resource("ec2", region_name="us-west-1")
dhcp_options = ec2.create_dhcp_options(
DhcpConfigurations=[
{"Key": "domain-name", "Values": [SAMPLE_DOMAIN_NAME]},
{"Key": "domain-name-servers", "Values": SAMPLE_NAME_SERVERS},
]
)
config = dhcp_options.dhcp_configurations
config.should.have.length_of(2)
config.should.contain(
{
"Key": "domain-name-servers",
"Values": [{"Value": ip} for ip in SAMPLE_NAME_SERVERS],
}
)
config.should.contain(
{"Key": "domain-name", "Values": [{"Value": SAMPLE_DOMAIN_NAME}]}
)
# Has boto3 equivalent
@mock_ec2_deprecated
def test_create_dhcp_options_invalid_options():
"""Create invalid dhcp options"""
@ -111,6 +226,30 @@ def test_create_dhcp_options_invalid_options():
cm.value.request_id.should_not.be.none
@mock_ec2
def test_create_dhcp_options_invalid_options_boto3():
"""Create invalid dhcp options"""
ec2 = boto3.resource("ec2", region_name="us-west-1")
servers = ["f", "f", "f", "f", "f"]
with pytest.raises(ClientError) as ex:
ec2.create_dhcp_options(
DhcpConfigurations=[{"Key": "ntp-servers", "Values": servers}]
)
ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
ex.value.response["ResponseMetadata"].should.have.key("RequestId")
ex.value.response["Error"]["Code"].should.equal("InvalidParameterValue")
with pytest.raises(ClientError) as ex:
ec2.create_dhcp_options(
DhcpConfigurations=[{"Key": "netbios-node-type", "Values": ["0"]}]
)
ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
ex.value.response["ResponseMetadata"].should.have.key("RequestId")
ex.value.response["Error"]["Code"].should.equal("InvalidParameterValue")
# Has boto3 equivalent
@mock_ec2_deprecated
def test_describe_dhcp_options():
"""Test dhcp options lookup by id"""
@ -124,6 +263,43 @@ def test_describe_dhcp_options():
dhcp_options.should.be.length_of(1)
@mock_ec2
def test_describe_dhcp_options_boto3():
"""Test dhcp options lookup by id"""
ec2 = boto3.resource("ec2", region_name="us-west-1")
client = boto3.client("ec2", region_name="us-west-1")
all_options = client.describe_dhcp_options()["DhcpOptions"]
all_options.should.have.length_of(0)
dhcp_options = ec2.create_dhcp_options(
DhcpConfigurations=[
{"Key": "domain-name", "Values": [SAMPLE_DOMAIN_NAME]},
{"Key": "domain-name-servers", "Values": SAMPLE_NAME_SERVERS},
]
)
all_options = client.describe_dhcp_options(DhcpOptionsIds=[dhcp_options.id])[
"DhcpOptions"
]
all_options.should.have.length_of(1)
all_options = client.describe_dhcp_options()["DhcpOptions"]
all_options.should.have.length_of(1)
all_options[0]["DhcpOptionsId"].should.equal(dhcp_options.id)
config = all_options[0]["DhcpConfigurations"]
config.should.have.length_of(2)
config.should.contain(
{
"Key": "domain-name-servers",
"Values": [{"Value": ip} for ip in SAMPLE_NAME_SERVERS],
}
)
config.should.contain(
{"Key": "domain-name", "Values": [{"Value": SAMPLE_DOMAIN_NAME}]}
)
# Has boto3 equivalent
@mock_ec2_deprecated
def test_describe_dhcp_options_invalid_id():
"""get error on invalid dhcp_option_id lookup"""
@ -136,6 +312,19 @@ def test_describe_dhcp_options_invalid_id():
cm.value.request_id.should_not.be.none
@mock_ec2
def test_describe_dhcp_options_invalid_id_boto3():
"""get error on invalid dhcp_option_id lookup"""
client = boto3.client("ec2", region_name="us-west-1")
with pytest.raises(ClientError) as ex:
client.describe_dhcp_options(DhcpOptionsIds=["1"])
ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
ex.value.response["ResponseMetadata"].should.have.key("RequestId")
ex.value.response["Error"]["Code"].should.equal("InvalidDhcpOptionID.NotFound")
# Has boto3 equivalent
@mock_ec2_deprecated
def test_delete_dhcp_options():
"""delete dhcp option"""
@ -154,6 +343,29 @@ def test_delete_dhcp_options():
cm.value.request_id.should_not.be.none
@mock_ec2
def test_delete_dhcp_options_boto3():
"""delete dhcp option"""
ec2 = boto3.resource("ec2", region_name="us-west-1")
client = boto3.client("ec2", region_name="us-west-1")
dhcp_option = ec2.create_dhcp_options(
DhcpConfigurations=[
{"Key": "domain-name", "Values": [SAMPLE_DOMAIN_NAME]},
{"Key": "domain-name-servers", "Values": SAMPLE_NAME_SERVERS},
]
)
client.delete_dhcp_options(DhcpOptionsId=dhcp_option.id)
with pytest.raises(ClientError) as ex:
client.describe_dhcp_options(DhcpOptionsIds=[dhcp_option.id])
ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
ex.value.response["ResponseMetadata"].should.have.key("RequestId")
ex.value.response["Error"]["Code"].should.equal("InvalidDhcpOptionID.NotFound")
# Has boto3 equivalent
@mock_ec2_deprecated
def test_delete_dhcp_options_invalid_id():
conn = boto.connect_vpc("the_key", "the_secret")
@ -167,6 +379,18 @@ def test_delete_dhcp_options_invalid_id():
cm.value.request_id.should_not.be.none
@mock_ec2
def test_delete_dhcp_options_invalid_id_boto3():
client = boto3.client("ec2", region_name="us-west-1")
with pytest.raises(ClientError) as ex:
client.delete_dhcp_options(DhcpOptionsId="dopt-abcd1234")
ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
ex.value.response["ResponseMetadata"].should.have.key("RequestId")
ex.value.response["Error"]["Code"].should.equal("InvalidDhcpOptionID.NotFound")
# Has boto3 equivalent
@mock_ec2_deprecated
def test_delete_dhcp_options_malformed_id():
conn = boto.connect_vpc("the_key", "the_secret")
@ -180,6 +404,18 @@ def test_delete_dhcp_options_malformed_id():
cm.value.request_id.should_not.be.none
@mock_ec2
def test_delete_dhcp_options_malformed_id_boto3():
client = boto3.client("ec2", region_name="us-west-1")
with pytest.raises(ClientError) as ex:
client.delete_dhcp_options(DhcpOptionsId="foo-abcd1234")
ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
ex.value.response["ResponseMetadata"].should.have.key("RequestId")
ex.value.response["Error"]["Code"].should.equal("InvalidDhcpOptionsId.Malformed")
# Has boto3 equivalent
@mock_ec2_deprecated
def test_dhcp_tagging():
conn = boto.connect_vpc("the_key", "the_secret")
@ -197,6 +433,32 @@ def test_dhcp_tagging():
dhcp_option.tags["a key"].should.equal("some value")
@mock_ec2
def test_dhcp_tagging_boto3():
ec2 = boto3.resource("ec2", region_name="us-west-1")
client = boto3.client("ec2", region_name="us-west-1")
dhcp_option = ec2.create_dhcp_options(
DhcpConfigurations=[
{"Key": "domain-name", "Values": [SAMPLE_DOMAIN_NAME]},
{"Key": "domain-name-servers", "Values": SAMPLE_NAME_SERVERS},
]
)
dhcp_option.create_tags(Tags=[{"Key": "a tag", "Value": "some value"}])
tag = client.describe_tags()["Tags"][0]
tag.should.have.key("ResourceId").equal(dhcp_option.id)
tag.should.have.key("ResourceType").equal("dhcp-options")
tag.should.have.key("Key").equal("a tag")
tag.should.have.key("Value").equal("some value")
# Refresh the DHCP options
dhcp_option = client.describe_dhcp_options()["DhcpOptions"][0]
dhcp_option["Tags"].should.equal([{"Key": "a tag", "Value": "some value"}])
# Has boto3 equivalent
@mock_ec2_deprecated
def test_dhcp_options_get_by_tag():
conn = boto.connect_vpc("the_key", "the_secret")
@ -233,6 +495,83 @@ def test_dhcp_options_get_by_tag():
dhcp_options_sets.should.have.length_of(2)
@mock_ec2
def test_dhcp_options_get_by_tag_boto3():
ec2 = boto3.resource("ec2", region_name="us-west-1")
client = boto3.client("ec2", region_name="us-west-1")
dhcp1 = ec2.create_dhcp_options(
DhcpConfigurations=[
{"Key": "domain-name", "Values": ["example.com"]},
{"Key": "domain-name-servers", "Values": ["10.0.10.2"]},
]
)
dhcp1.create_tags(
Tags=[
{"Key": "Name", "Value": "TestDhcpOptions1"},
{"Key": "test-tag", "Value": "test-value"},
]
)
dhcp2 = ec2.create_dhcp_options(
DhcpConfigurations=[
{"Key": "domain-name", "Values": ["example.com"]},
{"Key": "domain-name-servers", "Values": ["10.0.20.2"]},
]
)
dhcp2.create_tags(
Tags=[
{"Key": "Name", "Value": "TestDhcpOptions2"},
{"Key": "test-tag", "Value": "test-value"},
]
)
dhcp_options_sets = client.describe_dhcp_options(
Filters=[
{"Name": "tag:Name", "Values": ["TestDhcpOptions1"]},
{"Name": "tag:test-tag", "Values": ["test-value"]},
]
)["DhcpOptions"]
dhcp_options_sets.should.have.length_of(1)
config = dhcp_options_sets[0]["DhcpConfigurations"]
config.should.have.length_of(2)
config.should.contain({"Key": "domain-name", "Values": [{"Value": "example.com"}]})
config.should.contain(
{"Key": "domain-name-servers", "Values": [{"Value": "10.0.10.2"}]}
)
tags = dhcp_options_sets[0]["Tags"]
tags.should.have.length_of(2)
tags.should.contain({"Key": "Name", "Value": "TestDhcpOptions1"})
tags.should.contain({"Key": "test-tag", "Value": "test-value"})
dhcp_options_sets = client.describe_dhcp_options(
Filters=[
{"Name": "tag:Name", "Values": ["TestDhcpOptions2"]},
{"Name": "tag:test-tag", "Values": ["test-value"]},
]
)["DhcpOptions"]
dhcp_options_sets.should.have.length_of(1)
config = dhcp_options_sets[0]["DhcpConfigurations"]
config.should.have.length_of(2)
config.should.contain({"Key": "domain-name", "Values": [{"Value": "example.com"}]})
config.should.contain(
{"Key": "domain-name-servers", "Values": [{"Value": "10.0.20.2"}]}
)
tags = dhcp_options_sets[0]["Tags"]
tags.should.have.length_of(2)
tags.should.contain({"Key": "Name", "Value": "TestDhcpOptions2"})
tags.should.contain({"Key": "test-tag", "Value": "test-value"})
dhcp_options_sets = client.describe_dhcp_options(
Filters=[{"Name": "tag:test-tag", "Values": ["test-value"]}]
)["DhcpOptions"]
dhcp_options_sets.should.have.length_of(2)
# Has boto3 equivalent
@mock_ec2_deprecated
def test_dhcp_options_get_by_id():
conn = boto.connect_vpc("the_key", "the_secret")
@ -263,6 +602,47 @@ def test_dhcp_options_get_by_id():
dhcp_options_sets[0].options["domain-name-servers"][0].should.be.equal("10.0.20.2")
@mock_ec2
def test_dhcp_options_get_by_id_boto3():
ec2 = boto3.resource("ec2", region_name="us-west-1")
client = boto3.client("ec2", region_name="us-west-1")
dhcp1 = ec2.create_dhcp_options(
DhcpConfigurations=[
{"Key": "domain-name", "Values": ["test1.com"]},
{"Key": "domain-name-servers", "Values": ["10.0.10.2"]},
]
)
dhcp1.create_tags(Tags=[{"Key": "Name", "Value": "TestDhcpOptions1"}])
dhcp1.create_tags(Tags=[{"Key": "test-tag", "Value": "test-value"}])
dhcp2 = ec2.create_dhcp_options(
DhcpConfigurations=[
{"Key": "domain-name", "Values": ["test2.com"]},
{"Key": "domain-name-servers", "Values": ["10.0.20.2"]},
]
)
dhcp1.create_tags(Tags=[{"Key": "Name", "Value": "TestDhcpOptions2"}])
dhcp1.create_tags(Tags=[{"Key": "test-tag", "Value": "test-value"}])
d = client.describe_dhcp_options()["DhcpOptions"]
d.should.have.length_of(2)
d = client.describe_dhcp_options(
Filters=[{"Name": "dhcp-options-id", "Values": [dhcp1.id]}]
)["DhcpOptions"]
d.should.have.length_of(1)
d[0].should.have.key("DhcpOptionsId").equal(dhcp1.id)
d = client.describe_dhcp_options(
Filters=[{"Name": "dhcp-options-id", "Values": [dhcp2.id]}]
)["DhcpOptions"]
d.should.have.length_of(1)
d[0].should.have.key("DhcpOptionsId").equal(dhcp2.id)
@mock_ec2
def test_dhcp_options_get_by_value_filter():
ec2 = boto3.resource("ec2", region_name="us-west-1")
@ -323,6 +703,7 @@ def test_dhcp_options_get_by_key_filter():
dhcp_options_sets.should.have.length_of(3)
# Has boto3 equivalent
@mock_ec2_deprecated
def test_dhcp_options_get_by_invalid_filter():
conn = boto.connect_vpc("the_key", "the_secret")
@ -333,3 +714,24 @@ def test_dhcp_options_get_by_invalid_filter():
conn.get_all_dhcp_options.when.called_with(filters=filters).should.throw(
NotImplementedError
)
@mock_ec2
def test_dhcp_options_get_by_invalid_filter_boto3():
if settings.TEST_SERVER_MODE:
raise SkipTest("Will throw a generic 500 in ServerMode")
ec2 = boto3.resource("ec2", region_name="us-west-1")
client = boto3.client("ec2", region_name="us-west-1")
ec2.create_dhcp_options(
DhcpConfigurations=[
{"Key": "domain-name", "Values": [SAMPLE_DOMAIN_NAME]},
{"Key": "domain-name-servers", "Values": SAMPLE_NAME_SERVERS},
]
)
filters = [{"Name": "invalid-filter", "Values": ["n/a"]}]
client.describe_dhcp_options.when.called_with(Filters=filters).should.throw(
NotImplementedError
)

View File

@ -1,6 +1,7 @@
from __future__ import unicode_literals
import boto
import boto.ec2
import boto3
import pytest
@ -14,6 +15,7 @@ from moto.kms import mock_kms
from tests import EXAMPLE_AMI_ID
# Has boto3 equivalent
@mock_ec2_deprecated
def test_create_and_delete_volume():
conn = boto.ec2.connect_to_region("us-east-1")
@ -51,6 +53,43 @@ def test_create_and_delete_volume():
cm.value.request_id.should_not.be.none
@mock_ec2
def test_create_and_delete_volume_boto3():
client = boto3.client("ec2", region_name="us-east-1")
ec2 = boto3.resource("ec2", region_name="us-east-1")
volume = ec2.create_volume(Size=80, AvailabilityZone="us-east-1a")
all_volumes = client.describe_volumes()["Volumes"]
current_volume = [item for item in all_volumes if item["VolumeId"] == volume.id]
current_volume.should.have.length_of(1)
current_volume[0]["Size"].should.equal(80)
current_volume[0]["AvailabilityZone"].should.equal("us-east-1a")
current_volume[0]["Encrypted"].should.be(False)
with pytest.raises(ClientError) as ex:
volume.delete(DryRun=True)
ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(412)
ex.value.response["Error"]["Code"].should.equal("DryRunOperation")
ex.value.response["Error"]["Message"].should.equal(
"An error occurred (DryRunOperation) when calling the DeleteVolume operation: Request would have succeeded, but DryRun flag is set"
)
volume.delete()
all_volumes = client.describe_volumes()["Volumes"]
my_volume = [item for item in all_volumes if item["VolumeId"] == volume.id]
my_volume.should.have.length_of(0)
# Deleting something that was already deleted should throw an error
with pytest.raises(ClientError) as ex:
volume.delete()
ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
ex.value.response["ResponseMetadata"].should.have.key("RequestId")
ex.value.response["Error"]["Code"].should.equal("InvalidVolume.NotFound")
# Has boto3 equivalent
@mock_ec2_deprecated
def test_delete_attached_volume():
conn = boto.ec2.connect_to_region("us-east-1")
@ -90,6 +129,47 @@ def test_delete_attached_volume():
my_volume.should.have.length_of(0)
@mock_ec2
def test_delete_attached_volume_boto3():
client = boto3.client("ec2", region_name="us-east-1")
ec2 = boto3.resource("ec2", region_name="us-east-1")
reservation = client.run_instances(ImageId=EXAMPLE_AMI_ID, MinCount=1, MaxCount=1)
# create an instance
instance = reservation["Instances"][0]
# create a volume
volume = ec2.create_volume(Size=80, AvailabilityZone="us-east-1a")
# attach volume to instance
volume.attach_to_instance(InstanceId=instance["InstanceId"], Device="/dev/sdh")
volume.state.should.equal("in-use")
volume.attachments.should.have.length_of(1)
volume.attachments[0]["InstanceId"].should.equal(instance["InstanceId"])
volume.attachments[0]["State"].should.equal("attached")
# attempt to delete volume
# assert raises VolumeInUseError
with pytest.raises(ClientError) as ex:
volume.delete()
ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
ex.value.response["Error"]["Code"].should.equal("VolumeInUse")
ex.value.response["Error"]["Message"].should.equal(
"Volume {0} is currently attached to {1}".format(
volume.id, instance["InstanceId"]
)
)
volume.detach_from_instance(InstanceId=instance["InstanceId"])
volume.state.should.equal("available")
volume.delete()
all_volumes = client.describe_volumes()["Volumes"]
[v["VolumeId"] for v in all_volumes].shouldnt.contain(volume.id)
# Has boto3 equivalent
@mock_ec2_deprecated
def test_create_encrypted_volume_dryrun():
conn = boto.ec2.connect_to_region("us-east-1")
@ -102,6 +182,19 @@ def test_create_encrypted_volume_dryrun():
)
@mock_ec2
def test_create_encrypted_volume_dryrun_boto3():
ec2 = boto3.resource("ec2", region_name="us-east-1")
with pytest.raises(ClientError) as ex:
ec2.create_volume(Size=80, AvailabilityZone="us-east-1a", DryRun=True)
ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(412)
ex.value.response["Error"]["Code"].should.equal("DryRunOperation")
ex.value.response["Error"]["Message"].should.equal(
"An error occurred (DryRunOperation) when calling the CreateVolume operation: Request would have succeeded, but DryRun flag is set"
)
# Has boto3 equivalent
@mock_ec2_deprecated
def test_create_encrypted_volume():
conn = boto.ec2.connect_to_region("us-east-1")
@ -119,6 +212,17 @@ def test_create_encrypted_volume():
all_volumes[0].encrypted.should.be(True)
@mock_ec2
def test_create_encrypted_volume_boto3():
client = boto3.client("ec2", region_name="us-east-1")
ec2 = boto3.resource("ec2", region_name="us-east-1")
volume = ec2.create_volume(Size=80, AvailabilityZone="us-east-1a", Encrypted=True)
all_volumes = client.describe_volumes(VolumeIds=[volume.id])["Volumes"]
all_volumes[0]["Encrypted"].should.be(True)
# Has boto3 equivalent
@mock_ec2_deprecated
def test_filter_volume_by_id():
conn = boto.ec2.connect_to_region("us-east-1")
@ -139,6 +243,29 @@ def test_filter_volume_by_id():
cm.value.request_id.should_not.be.none
@mock_ec2
def test_filter_volume_by_id_boto3():
client = boto3.client("ec2", region_name="us-east-1")
ec2 = boto3.resource("ec2", region_name="us-east-1")
volume1 = ec2.create_volume(Size=80, AvailabilityZone="us-east-1a")
volume2 = ec2.create_volume(Size=36, AvailabilityZone="us-east-1b")
volume3 = ec2.create_volume(Size=20, AvailabilityZone="us-east-1c")
vol3 = client.describe_volumes(VolumeIds=[volume3.id])["Volumes"]
vol3.should.have.length_of(1)
vol3[0]["Size"].should.equal(20)
vol3[0]["AvailabilityZone"].should.equal("us-east-1c")
vol12 = client.describe_volumes(VolumeIds=[volume1.id, volume2.id])["Volumes"]
vol12.should.have.length_of(2)
with pytest.raises(ClientError) as ex:
client.describe_volumes(VolumeIds=["vol-does_not_exist"])
ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
ex.value.response["Error"]["Code"].should.equal("InvalidVolume.NotFound")
# Has boto3 equivalent
@mock_ec2_deprecated
def test_volume_filters():
conn = boto.ec2.connect_to_region("us-east-1")
@ -247,6 +374,76 @@ def test_volume_filters():
).should.equal({volume2.id})
@mock_ec2
def test_volume_filters_boto3():
client = boto3.client("ec2", region_name="us-east-1")
ec2 = boto3.resource("ec2", region_name="us-east-1")
reservation = client.run_instances(ImageId=EXAMPLE_AMI_ID, MinCount=1, MaxCount=1)
instance = reservation["Instances"][0]
volume1 = ec2.create_volume(Size=80, AvailabilityZone="us-east-1a", Encrypted=True)
volume2 = ec2.create_volume(Size=36, AvailabilityZone="us-east-1b", Encrypted=False)
volume3 = ec2.create_volume(Size=20, AvailabilityZone="us-east-1c", Encrypted=True)
snapshot = volume3.create_snapshot(Description="testsnap")
volume4 = ec2.create_volume(
Size=25, AvailabilityZone="us-east-1a", SnapshotId=snapshot.id
)
ec2.create_tags(
Resources=[volume1.id], Tags=[{"Key": "testkey1", "Value": "testvalue1"}]
)
ec2.create_tags(
Resources=[volume2.id], Tags=[{"Key": "testkey2", "Value": "testvalue2"}]
)
volume1.reload()
volume2.reload()
volume3.reload()
volume4.reload()
instance = ec2.Instance(instance["InstanceId"])
instance.reload()
block_mapping = [
m for m in instance.block_device_mappings if m["DeviceName"] == "/dev/sda1"
][0]
block_volume = block_mapping["Ebs"]["VolumeId"]
def verify_filter(name, value, expected=None):
expected = expected or block_volume
expected = expected if type(expected) == list else [expected]
volumes = client.describe_volumes(Filters=[{"Name": name, "Values": [value]}])[
"Volumes"
]
set([vol["VolumeId"] for vol in volumes]).should.equal(set(expected))
# We should probably make this less strict, i.e. figure out which formats AWS expects/approves of
attach_time = block_mapping["Ebs"]["AttachTime"].strftime("%Y-%m-%dT%H:%M:%S.000Z")
verify_filter("attachment.attach-time", attach_time)
verify_filter("attachment.device", "/dev/sda1")
verify_filter("attachment.instance-id", instance.id)
verify_filter("attachment.status", "attached")
verify_filter("size", str(volume2.size), expected=volume2.id)
verify_filter("snapshot-id", snapshot.id, expected=volume4.id)
verify_filter("status", "in-use")
verify_filter("volume-id", volume1.id, expected=volume1.id)
verify_filter("tag-key", "testkey1", expected=volume1.id)
verify_filter("tag-value", "testvalue1", expected=volume1.id)
verify_filter("tag:testkey1", "testvalue1", expected=volume1.id)
verify_filter("encrypted", "false", expected=[block_volume, volume2.id])
verify_filter("encrypted", "true", expected=[volume1.id, volume3.id, volume4.id])
verify_filter("availability-zone", "us-east-1b", expected=volume2.id)
#
create_time = volume4.create_time.strftime("%Y-%m-%dT%H:%M:%S.000Z")
volumes_by_attach_device = client.describe_volumes(
Filters=[{"Name": "create-time", "Values": [create_time]}]
)["Volumes"]
[vol["VolumeId"] for vol in volumes_by_attach_device].should.contain(volume4.id)
# Has boto3 equivalent
@mock_ec2_deprecated
def test_volume_attach_and_detach():
conn = boto.ec2.connect_to_region("us-east-1")
@ -305,6 +502,66 @@ def test_volume_attach_and_detach():
cm3.value.request_id.should_not.be.none
@mock_ec2
def test_volume_attach_and_detach_boto3():
client = boto3.client("ec2", region_name="us-east-1")
ec2 = boto3.resource("ec2", region_name="us-east-1")
reservation = client.run_instances(ImageId=EXAMPLE_AMI_ID, MinCount=1, MaxCount=1)
instance = reservation["Instances"][0]
volume = ec2.create_volume(Size=80, AvailabilityZone="us-east-1a")
volume.reload()
volume.state.should.equal("available")
with pytest.raises(ClientError) as ex:
volume.attach_to_instance(
InstanceId=instance["InstanceId"], Device="/dev/sdh", DryRun=True
)
ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(412)
ex.value.response["Error"]["Code"].should.equal("DryRunOperation")
ex.value.response["Error"]["Message"].should.equal(
"An error occurred (DryRunOperation) when calling the AttachVolume operation: Request would have succeeded, but DryRun flag is set"
)
volume.attach_to_instance(InstanceId=instance["InstanceId"], Device="/dev/sdh")
volume.state.should.equal("in-use")
volume.attachments[0]["State"].should.equal("attached")
volume.attachments[0]["InstanceId"].should.equal(instance["InstanceId"])
with pytest.raises(ClientError) as ex:
volume.detach_from_instance(DryRun=True)
ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(412)
ex.value.response["Error"]["Code"].should.equal("DryRunOperation")
ex.value.response["Error"]["Message"].should.equal(
"An error occurred (DryRunOperation) when calling the DetachVolume operation: Request would have succeeded, but DryRun flag is set"
)
volume.detach_from_instance(InstanceId=instance["InstanceId"])
volume.state.should.equal("available")
with pytest.raises(ClientError) as ex1:
volume.attach_to_instance(InstanceId="i-1234abcd", Device="/dev/sdh")
ex1.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
ex1.value.response["Error"]["Code"].should.equal("InvalidInstanceID.NotFound")
with pytest.raises(ClientError) as ex2:
client.detach_volume(
VolumeId=volume.id, InstanceId=instance["InstanceId"], Device="/dev/sdh"
)
ex2.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
ex2.value.response["Error"]["Code"].should.equal("InvalidAttachment.NotFound")
with pytest.raises(ClientError) as ex3:
client.detach_volume(
VolumeId=volume.id, InstanceId="i-1234abcd", Device="/dev/sdh"
)
ex3.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
ex3.value.response["Error"]["Code"].should.equal("InvalidInstanceID.NotFound")
# Has boto3 equivalent
@mock_ec2_deprecated
def test_create_snapshot():
conn = boto.ec2.connect_to_region("us-east-1")
@ -345,6 +602,51 @@ def test_create_snapshot():
cm.value.request_id.should_not.be.none
@mock_ec2
def test_create_snapshot_boto3():
client = boto3.client("ec2", region_name="us-east-1")
ec2 = boto3.resource("ec2", region_name="us-east-1")
volume = ec2.create_volume(Size=80, AvailabilityZone="us-east-1a")
with pytest.raises(ClientError) as ex:
volume.create_snapshot(Description="a dryrun snapshot", DryRun=True)
ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(412)
ex.value.response["Error"]["Code"].should.equal("DryRunOperation")
ex.value.response["Error"]["Message"].should.equal(
"An error occurred (DryRunOperation) when calling the CreateSnapshot operation: Request would have succeeded, but DryRun flag is set"
)
snapshot = volume.create_snapshot(Description="a test snapshot")
snapshot.reload()
snapshot.state.should.equal("completed")
snapshots = [
snap
for snap in client.describe_snapshots()["Snapshots"]
if snap["SnapshotId"] == snapshot.id
]
snapshots.should.have.length_of(1)
snapshots[0]["Description"].should.equal("a test snapshot")
snapshots[0]["StartTime"].should_not.be.none
snapshots[0]["Encrypted"].should.be(False)
# Create snapshot without description
num_snapshots = len(client.describe_snapshots()["Snapshots"])
snapshot = volume.create_snapshot()
client.describe_snapshots()["Snapshots"].should.have.length_of(num_snapshots + 1)
snapshot.delete()
client.describe_snapshots()["Snapshots"].should.have.length_of(num_snapshots)
# Deleting something that was already deleted should throw an error
with pytest.raises(ClientError) as ex:
snapshot.delete()
ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
ex.value.response["Error"]["Code"].should.equal("InvalidSnapshot.NotFound")
# Has boto3 equivalent
@mock_ec2_deprecated
def test_create_encrypted_snapshot():
conn = boto.ec2.connect_to_region("us-east-1")
@ -360,6 +662,31 @@ def test_create_encrypted_snapshot():
snapshots[0].encrypted.should.be(True)
@mock_ec2
@pytest.mark.parametrize("encrypted", [True, False])
def test_create_encrypted_snapshot_boto3(encrypted):
client = boto3.client("ec2", region_name="us-east-1")
ec2 = boto3.resource("ec2", region_name="us-east-1")
volume = ec2.create_volume(
Size=80, AvailabilityZone="us-east-1a", Encrypted=encrypted
)
snapshot = volume.create_snapshot(Description="a test snapshot")
snapshot.encrypted.should.be(encrypted)
snapshot.reload()
snapshot.state.should.equal("completed")
snapshots = [
snap
for snap in client.describe_snapshots()["Snapshots"]
if snap["SnapshotId"] == snapshot.id
]
snapshots.should.have.length_of(1)
snapshots[0]["Description"].should.equal("a test snapshot")
snapshots[0]["StartTime"].should_not.be.none
snapshots[0]["Encrypted"].should.be(encrypted)
# Has boto3 equivalent
@mock_ec2_deprecated
def test_filter_snapshot_by_id():
conn = boto.ec2.connect_to_region("us-east-1")
@ -387,6 +714,35 @@ def test_filter_snapshot_by_id():
cm.value.request_id.should_not.be.none
@mock_ec2
def test_filter_snapshot_by_id_boto3():
client = boto3.client("ec2", region_name="us-east-1")
ec2 = boto3.resource("ec2", region_name="us-east-1")
volume1 = ec2.create_volume(Size=36, AvailabilityZone="us-east-1a")
snap1 = volume1.create_snapshot(Description="a test snapshot 1")
volume2 = ec2.create_volume(Size=42, AvailabilityZone="us-east-1a")
snap2 = volume2.create_snapshot(Description="a test snapshot 2")
volume3 = ec2.create_volume(Size=84, AvailabilityZone="us-east-1a")
snap3 = volume3.create_snapshot(Description="a test snapshot 3")
snapshots1 = client.describe_snapshots(SnapshotIds=[snap1.id])["Snapshots"]
snapshots1.should.have.length_of(1)
snapshots1[0]["VolumeId"].should.equal(volume1.id)
snapshots2 = client.describe_snapshots(SnapshotIds=[snap2.id, snap3.id])[
"Snapshots"
]
snapshots2.should.have.length_of(2)
for s in snapshots2:
s["StartTime"].should_not.be.none
s["VolumeId"].should.be.within([volume2.id, volume3.id])
with pytest.raises(ClientError) as ex:
client.describe_snapshots(SnapshotIds=["snap-does_not_exist"])
ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
ex.value.response["ResponseMetadata"].should.have.key("RequestId")
ex.value.response["Error"]["Code"].should.equal("InvalidSnapshot.NotFound")
# Has boto3 equivalent
@mock_ec2_deprecated
def test_snapshot_filters():
conn = boto.ec2.connect_to_region("us-east-1")
@ -451,6 +807,60 @@ def test_snapshot_filters():
)
@mock_ec2
def test_snapshot_filters_boto3():
client = boto3.client("ec2", region_name="us-east-1")
ec2 = boto3.resource("ec2", region_name="us-east-1")
volume1 = ec2.create_volume(Size=20, AvailabilityZone="us-east-1a", Encrypted=False)
volume2 = ec2.create_volume(Size=25, AvailabilityZone="us-east-1a", Encrypted=True)
snapshot1 = volume1.create_snapshot(Description="testsnapshot1")
snapshot2 = volume1.create_snapshot(Description="testsnapshot2")
snapshot3 = volume2.create_snapshot(Description="testsnapshot3")
ec2.create_tags(
Resources=[snapshot1.id], Tags=[{"Key": "testkey1", "Value": "testvalue1"}]
)
ec2.create_tags(
Resources=[snapshot2.id], Tags=[{"Key": "testkey2", "Value": "testvalue2"}]
)
def verify_filter(name, value, expected):
expected = expected if type(expected) == list else [expected]
snapshots = client.describe_snapshots(
Filters=[{"Name": name, "Values": [value]}]
)["Snapshots"]
set([s["SnapshotId"] for s in snapshots]).should.equal(set(expected))
verify_filter("description", "testsnapshot1", expected=snapshot1.id)
verify_filter("snapshot-id", snapshot1.id, expected=snapshot1.id)
verify_filter("volume-id", volume1.id, expected=[snapshot1.id, snapshot2.id])
verify_filter(
"volume-size", str(volume1.size), expected=[snapshot1.id, snapshot2.id]
)
verify_filter("tag-key", "testkey1", expected=snapshot1.id)
verify_filter("tag-value", "testvalue1", expected=snapshot1.id)
verify_filter("tag:testkey2", "testvalue2", expected=snapshot2.id)
verify_filter("encrypted", "true", expected=snapshot3.id)
verify_filter(
"owner-id", OWNER_ID, expected=[snapshot1.id, snapshot2.id, snapshot3.id]
)
#
# We should probably make this less strict, i.e. figure out which formats AWS expects/approves of
start_time = snapshot1.start_time.strftime("%Y-%m-%dT%H:%M:%S.000Z")
snapshots = client.describe_snapshots(
Filters=[{"Name": "start-time", "Values": [start_time]}]
)["Snapshots"]
[s["SnapshotId"] for s in snapshots].should.contain(snapshot1.id)
snapshots = client.describe_snapshots(
Filters=[{"Name": "status", "Values": ["completed"]}]
)["Snapshots"]
[s["SnapshotId"] for s in snapshots].should.contain(snapshot1.id)
[s["SnapshotId"] for s in snapshots].should.contain(snapshot2.id)
[s["SnapshotId"] for s in snapshots].should.contain(snapshot3.id)
# Has boto3 equivalent
@mock_ec2_deprecated
def test_snapshot_attribute():
import copy
@ -732,6 +1142,7 @@ def test_modify_snapshot_attribute():
assert len(attributes["CreateVolumePermissions"]) == 0
# Has boto3 equivalent
@mock_ec2_deprecated
def test_create_volume_from_snapshot():
conn = boto.ec2.connect_to_region("us-east-1")
@ -755,6 +1166,7 @@ def test_create_volume_from_snapshot():
new_volume.snapshot_id.should.equal(snapshot.id)
# Has boto3 equivalent
@mock_ec2_deprecated
def test_create_volume_from_encrypted_snapshot():
conn = boto.ec2.connect_to_region("us-east-1")
@ -770,6 +1182,27 @@ def test_create_volume_from_encrypted_snapshot():
new_volume.encrypted.should.be(True)
@mock_ec2
@pytest.mark.parametrize("encrypted", [True, False])
def test_create_volume_from_snapshot_boto3(encrypted):
client = boto3.client("ec2", region_name="us-east-1")
ec2 = boto3.resource("ec2", region_name="us-east-1")
volume = ec2.create_volume(
Size=80, AvailabilityZone="us-east-1a", Encrypted=encrypted
)
snapshot = volume.create_snapshot(Description="a test snapshot")
snapshot.reload()
snapshot.state.should.equal("completed")
new_volume = client.create_volume(
SnapshotId=snapshot.id, AvailabilityZone="us-east-1a"
)
new_volume["Size"].should.equal(80)
new_volume["SnapshotId"].should.equal(snapshot.id)
new_volume["Encrypted"].should.equal(encrypted)
# Has boto3 equivalent
@mock_ec2_deprecated
def test_modify_attribute_blockDeviceMapping():
"""
@ -801,6 +1234,46 @@ def test_modify_attribute_blockDeviceMapping():
instance.block_device_mapping["/dev/sda1"].delete_on_termination.should.be(True)
@mock_ec2
def test_modify_attribute_blockDeviceMapping_boto3():
"""
Reproduces the missing feature explained at [0], where we want to mock a
call to modify an instance attribute of type: blockDeviceMapping.
[0] https://github.com/spulec/moto/issues/160
"""
client = boto3.client("ec2", region_name="us-east-1")
ec2 = boto3.resource("ec2", region_name="us-east-1")
reservation = client.run_instances(ImageId=EXAMPLE_AMI_ID, MinCount=1, MaxCount=1)
instance = ec2.Instance(reservation["Instances"][0]["InstanceId"])
with pytest.raises(ClientError) as ex:
instance.modify_attribute(
BlockDeviceMappings=[
{"DeviceName": "/dev/sda1", "Ebs": {"DeleteOnTermination": True}}
],
DryRun=True,
)
ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(412)
ex.value.response["Error"]["Code"].should.equal("DryRunOperation")
ex.value.response["Error"]["Message"].should.equal(
"An error occurred (DryRunOperation) when calling the ModifyInstanceAttribute operation: Request would have succeeded, but DryRun flag is set"
)
instance.modify_attribute(
BlockDeviceMappings=[
{"DeviceName": "/dev/sda1", "Ebs": {"DeleteOnTermination": True}}
]
)
instance.reload()
mapping = instance.block_device_mappings[0]
mapping.should.have.key("DeviceName").equal("/dev/sda1")
mapping["Ebs"]["DeleteOnTermination"].should.be(True)
# Has boto3 equivalent
@mock_ec2_deprecated
def test_volume_tag_escaping():
conn = boto.ec2.connect_to_region("us-east-1")
@ -823,6 +1296,29 @@ def test_volume_tag_escaping():
dict(snaps[0].tags).should.equal({"key": "</closed>"})
@mock_ec2
def test_volume_tag_escaping_boto3():
client = boto3.client("ec2", region_name="us-east-1")
ec2 = boto3.resource("ec2", region_name="us-east-1")
volume = ec2.create_volume(Size=10, AvailabilityZone="us-east-1a")
snapshot = client.create_snapshot(VolumeId=volume.id, Description="Desc")
snapshot = ec2.Snapshot(snapshot["SnapshotId"])
with pytest.raises(ClientError) as ex:
snapshot.create_tags(Tags=[{"Key": "key", "Value": "</closed>"}], DryRun=True)
ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(412)
ex.value.response["Error"]["Code"].should.equal("DryRunOperation")
ex.value.response["Error"]["Message"].should.equal(
"An error occurred (DryRunOperation) when calling the CreateTags operation: Request would have succeeded, but DryRun flag is set"
)
snapshot.tags.should.have.length_of(0)
snapshot.create_tags(Tags=[{"Key": "key", "Value": "</closed>"}])
snapshot.tags.should.equal([{"Key": "key", "Value": "</closed>"}])
@mock_ec2
def test_volume_property_hidden_when_no_tags_exist():
ec2_client = boto3.client("ec2", region_name="us-east-1")

View File

@ -5,6 +5,7 @@ import pytest
import boto
import boto3
from boto.exception import EC2ResponseError
from botocore.exceptions import ClientError
import sure # noqa
@ -14,6 +15,7 @@ from tests import EXAMPLE_AMI_ID
import logging
# Has boto3 equivalent
@mock_ec2_deprecated
def test_eip_allocate_classic():
"""Allocate/release Classic EIP"""
@ -45,6 +47,40 @@ def test_eip_allocate_classic():
standard.should_not.be.within(conn.get_all_addresses())
@mock_ec2
def test_eip_allocate_classic_boto3():
"""Allocate/release Classic EIP"""
client = boto3.client("ec2", region_name="us-east-1")
ec2 = boto3.resource("ec2", region_name="us-east-1")
with pytest.raises(ClientError) as ex:
client.allocate_address(DryRun=True)
ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(412)
ex.value.response["Error"]["Code"].should.equal("DryRunOperation")
ex.value.response["Error"]["Message"].should.equal(
"An error occurred (DryRunOperation) when calling the AllocateAddress operation: Request would have succeeded, but DryRun flag is set"
)
standard = client.allocate_address()
standard.should.have.key("PublicIp")
standard.should.have.key("Domain").equal("standard")
standard = ec2.ClassicAddress(standard["PublicIp"])
standard.load()
with pytest.raises(ClientError) as ex:
standard.release(DryRun=True)
ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(412)
ex.value.response["Error"]["Code"].should.equal("DryRunOperation")
ex.value.response["Error"]["Message"].should.equal(
"An error occurred (DryRunOperation) when calling the ReleaseAddress operation: Request would have succeeded, but DryRun flag is set"
)
standard.release()
client.describe_addresses()["Addresses"].should.be.empty
# Has boto3 equivalent
@mock_ec2_deprecated
def test_eip_allocate_vpc():
"""Allocate/release VPC EIP"""
@ -65,6 +101,32 @@ def test_eip_allocate_vpc():
vpc.release()
@mock_ec2
def test_eip_allocate_vpc_boto3():
"""Allocate/release VPC EIP"""
client = boto3.client("ec2", region_name="us-east-1")
ec2 = boto3.resource("ec2", region_name="us-east-1")
with pytest.raises(ClientError) as ex:
client.allocate_address(Domain="vpc", DryRun=True)
ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(412)
ex.value.response["Error"]["Code"].should.equal("DryRunOperation")
ex.value.response["Error"]["Message"].should.equal(
"An error occurred (DryRunOperation) when calling the AllocateAddress operation: Request would have succeeded, but DryRun flag is set"
)
vpc = client.allocate_address(Domain="vpc")
vpc.should.have.key("AllocationId")
vpc.should.have.key("Domain").equal("vpc")
client.describe_addresses()["Addresses"].should.have.length_of(1)
vpc = ec2.VpcAddress(vpc["AllocationId"])
vpc.release()
client.describe_addresses()["Addresses"].should.be.empty
@mock_ec2
def test_specific_eip_allocate_vpc():
"""Allocate VPC EIP with specific address"""
@ -77,6 +139,7 @@ def test_specific_eip_allocate_vpc():
logging.debug("vpc alloc_id:".format(vpc["AllocationId"]))
# Has boto3 equivalent
@mock_ec2_deprecated
def test_eip_allocate_invalid_domain():
"""Allocate EIP invalid domain"""
@ -89,6 +152,19 @@ def test_eip_allocate_invalid_domain():
cm.value.request_id.should_not.be.none
@mock_ec2
def test_eip_allocate_invalid_domain_boto3():
"""Allocate EIP invalid domain"""
client = boto3.client("ec2", region_name="us-east-1")
with pytest.raises(ClientError) as ex:
client.allocate_address(Domain="bogus")
ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
ex.value.response["ResponseMetadata"]["RequestId"].shouldnt.be.none
ex.value.response["Error"]["Code"].should.equal("InvalidParameterValue")
# Has boto3 equivalent
@mock_ec2_deprecated
def test_eip_associate_classic():
"""Associate/Disassociate EIP to classic instance"""
@ -140,6 +216,60 @@ def test_eip_associate_classic():
instance.terminate()
@mock_ec2
def test_eip_associate_classic_boto3():
"""Associate/Disassociate EIP to classic instance"""
client = boto3.client("ec2", region_name="us-east-1")
ec2 = boto3.resource("ec2", region_name="us-east-1")
reservation = client.run_instances(ImageId=EXAMPLE_AMI_ID, MinCount=1, MaxCount=1)
instance = ec2.Instance(reservation["Instances"][0]["InstanceId"])
eip = client.allocate_address()
eip = ec2.ClassicAddress(eip["PublicIp"])
eip.instance_id.should.be.empty
with pytest.raises(ClientError) as ex:
client.associate_address(PublicIp=eip.public_ip)
ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
ex.value.response["ResponseMetadata"]["RequestId"].shouldnt.be.none
ex.value.response["Error"]["Code"].should.equal("MissingParameter")
ex.value.response["Error"]["Message"].should.equal(
"Invalid request, expect InstanceId/NetworkId parameter."
)
with pytest.raises(ClientError) as ex:
client.associate_address(
InstanceId=instance.id, PublicIp=eip.public_ip, DryRun=True
)
ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(412)
ex.value.response["Error"]["Code"].should.equal("DryRunOperation")
ex.value.response["Error"]["Message"].should.equal(
"An error occurred (DryRunOperation) when calling the AssociateAddress operation: Request would have succeeded, but DryRun flag is set"
)
client.associate_address(InstanceId=instance.id, PublicIp=eip.public_ip)
eip.reload()
eip.instance_id.should.be.equal(instance.id)
with pytest.raises(ClientError) as ex:
client.disassociate_address(PublicIp=eip.public_ip, DryRun=True)
ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(412)
ex.value.response["Error"]["Code"].should.equal("DryRunOperation")
ex.value.response["Error"]["Message"].should.equal(
"An error occurred (DryRunOperation) when calling the DisAssociateAddress operation: Request would have succeeded, but DryRun flag is set"
)
client.disassociate_address(PublicIp=eip.public_ip)
eip.reload()
eip.instance_id.should.be.equal("")
eip.release()
client.describe_addresses()["Addresses"].should.be.empty
instance.terminate()
# Has boto3 equivalent
@mock_ec2_deprecated
def test_eip_associate_vpc():
"""Associate/Disassociate EIP to VPC instance"""
@ -181,6 +311,50 @@ def test_eip_associate_vpc():
instance.terminate()
@mock_ec2
def test_eip_associate_vpc_boto3():
"""Associate/Disassociate EIP to VPC instance"""
client = boto3.client("ec2", region_name="us-east-1")
ec2 = boto3.resource("ec2", region_name="us-east-1")
reservation = client.run_instances(ImageId=EXAMPLE_AMI_ID, MinCount=1, MaxCount=1)
instance = ec2.Instance(reservation["Instances"][0]["InstanceId"])
eip = client.allocate_address(Domain="vpc")
eip.shouldnt.have.key("InstanceId")
eip = ec2.VpcAddress(eip["AllocationId"])
with pytest.raises(ClientError) as ex:
client.associate_address(AllocationId=eip.allocation_id)
ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
ex.value.response["ResponseMetadata"]["RequestId"].shouldnt.be.none
ex.value.response["Error"]["Code"].should.equal("MissingParameter")
ex.value.response["Error"]["Message"].should.equal(
"Invalid request, expect InstanceId/NetworkId parameter."
)
client.associate_address(InstanceId=instance.id, AllocationId=eip.allocation_id)
eip.reload()
eip.instance_id.should.be.equal(instance.id)
client.disassociate_address(AssociationId=eip.association_id)
eip.reload()
eip.instance_id.should.be.equal("")
eip.association_id.should.be.none
with pytest.raises(ClientError) as ex:
eip.release(DryRun=True)
ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(412)
ex.value.response["Error"]["Code"].should.equal("DryRunOperation")
ex.value.response["Error"]["Message"].should.equal(
"An error occurred (DryRunOperation) when calling the ReleaseAddress operation: Request would have succeeded, but DryRun flag is set"
)
eip.release()
instance.terminate()
@mock_ec2
def test_eip_boto3_vpc_association():
"""Associate EIP to VPC instance in a new subnet with boto3"""
@ -228,6 +402,7 @@ def test_eip_boto3_vpc_association():
address.instance_id.should.be.empty
# Has boto3 equivalent
@mock_ec2_deprecated
def test_eip_associate_network_interface():
"""Associate/Disassociate EIP to NIC"""
@ -259,6 +434,42 @@ def test_eip_associate_network_interface():
eip = None
@mock_ec2
def test_eip_associate_network_interface_boto3():
"""Associate/Disassociate EIP to NIC"""
client = boto3.client("ec2", region_name="us-east-1")
ec2 = boto3.resource("ec2", region_name="us-east-1")
vpc = ec2.create_vpc(CidrBlock="10.0.0.0/16")
subnet = ec2.create_subnet(VpcId=vpc.id, CidrBlock="10.0.0.0/18")
eni = ec2.create_network_interface(SubnetId=subnet.id)
eip = client.allocate_address(Domain="vpc")
eip = ec2.ClassicAddress(eip["PublicIp"])
eip.network_interface_id.should.be.empty
with pytest.raises(ClientError) as ex:
client.associate_address(NetworkInterfaceId=eni.id)
ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
ex.value.response["ResponseMetadata"]["RequestId"].shouldnt.be.none
ex.value.response["Error"]["Code"].should.equal("MissingParameter")
ex.value.response["Error"]["Message"].should.equal(
"Invalid request, expect PublicIp/AllocationId parameter."
)
client.associate_address(NetworkInterfaceId=eni.id, AllocationId=eip.allocation_id)
eip.reload()
eip.network_interface_id.should.be.equal(eni.id)
client.disassociate_address(AssociationId=eip.association_id)
eip.reload()
eip.network_interface_id.should.be.empty
eip.association_id.should.be.none
eip.release()
# Has boto3 equivalent
@mock_ec2_deprecated
def test_eip_reassociate():
"""reassociate EIP"""
@ -292,6 +503,48 @@ def test_eip_reassociate():
instance2.terminate()
@mock_ec2
def test_eip_reassociate_boto3():
"""reassociate EIP"""
client = boto3.client("ec2", region_name="us-east-1")
ec2 = boto3.resource("ec2", region_name="us-east-1")
reservation = client.run_instances(ImageId=EXAMPLE_AMI_ID, MinCount=2, MaxCount=2)
instance1 = ec2.Instance(reservation["Instances"][0]["InstanceId"])
instance2 = ec2.Instance(reservation["Instances"][1]["InstanceId"])
eip = client.allocate_address()
eip = ec2.ClassicAddress(eip["PublicIp"])
client.associate_address(InstanceId=instance1.id, PublicIp=eip.public_ip)
# Same ID is idempotent
client.associate_address(InstanceId=instance1.id, PublicIp=eip.public_ip)
eip.reload()
eip.instance_id.should.equal(instance1.id)
# Different ID detects resource association
with pytest.raises(ClientError) as ex:
client.associate_address(
InstanceId=instance2.id, PublicIp=eip.public_ip, AllowReassociation=False
)
ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
ex.value.response["ResponseMetadata"]["RequestId"].shouldnt.be.none
ex.value.response["Error"]["Code"].should.equal("Resource.AlreadyAssociated")
client.associate_address(
InstanceId=instance2.id, PublicIp=eip.public_ip, AllowReassociation=True
)
eip.reload()
eip.instance_id.should.equal(instance2.id)
eip.release()
instance1.terminate()
instance2.terminate()
# Has boto3 equivalent
@mock_ec2_deprecated
def test_eip_reassociate_nic():
"""reassociate EIP"""
@ -323,6 +576,44 @@ def test_eip_reassociate_nic():
eip = None
@mock_ec2
def test_eip_reassociate_nic_boto3():
"""reassociate EIP"""
client = boto3.client("ec2", region_name="us-east-1")
ec2 = boto3.resource("ec2", region_name="us-east-1")
vpc = client.create_vpc(CidrBlock="10.0.0.0/16")["Vpc"]
subnet = client.create_subnet(VpcId=vpc["VpcId"], CidrBlock="10.0.0.0/18")["Subnet"]
eni1 = ec2.create_network_interface(SubnetId=subnet["SubnetId"])
eni2 = ec2.create_network_interface(SubnetId=subnet["SubnetId"])
eip = ec2.ClassicAddress(client.allocate_address()["PublicIp"])
client.associate_address(NetworkInterfaceId=eni1.id, PublicIp=eip.public_ip)
# Same ID is idempotent
client.associate_address(NetworkInterfaceId=eni1.id, PublicIp=eip.public_ip)
eip.reload()
eip.network_interface_id.should.equal(eni1.id)
# Different ID detects resource association
with pytest.raises(ClientError) as ex:
client.associate_address(NetworkInterfaceId=eni2.id, PublicIp=eip.public_ip)
ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
ex.value.response["ResponseMetadata"]["RequestId"].shouldnt.be.none
ex.value.response["Error"]["Code"].should.equal("Resource.AlreadyAssociated")
client.associate_address(
NetworkInterfaceId=eni2.id, PublicIp=eip.public_ip, AllowReassociation=True
)
eip.reload()
eip.network_interface_id.should.equal(eni2.id)
eip.release()
# Has boto3 equivalent
@mock_ec2_deprecated
def test_eip_associate_invalid_args():
"""Associate EIP, invalid args"""
@ -342,6 +633,27 @@ def test_eip_associate_invalid_args():
instance.terminate()
@mock_ec2
def test_eip_associate_invalid_args_boto3():
"""Associate EIP, invalid args """
client = boto3.client("ec2", region_name="us-east-1")
ec2 = boto3.resource("ec2", region_name="us-east-1")
reservation = client.run_instances(ImageId=EXAMPLE_AMI_ID, MinCount=1, MaxCount=1)
instance = ec2.Instance(reservation["Instances"][0]["InstanceId"])
client.allocate_address()
with pytest.raises(ClientError) as ex:
client.associate_address(InstanceId=instance.id)
ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
ex.value.response["ResponseMetadata"]["RequestId"].shouldnt.be.none
ex.value.response["Error"]["Code"].should.equal("MissingParameter")
instance.terminate()
# Has boto3 equivalent
@mock_ec2_deprecated
def test_eip_disassociate_bogus_association():
"""Disassociate bogus EIP"""
@ -354,6 +666,19 @@ def test_eip_disassociate_bogus_association():
cm.value.request_id.should_not.be.none
@mock_ec2
def test_eip_disassociate_bogus_association_boto3():
"""Disassociate bogus EIP"""
client = boto3.client("ec2", region_name="us-east-1")
with pytest.raises(ClientError) as ex:
client.disassociate_address(AssociationId="bogus")
ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
ex.value.response["ResponseMetadata"]["RequestId"].shouldnt.be.none
ex.value.response["Error"]["Code"].should.equal("InvalidAssociationID.NotFound")
# Has boto3 equivalent
@mock_ec2_deprecated
def test_eip_release_bogus_eip():
"""Release bogus EIP"""
@ -366,6 +691,19 @@ def test_eip_release_bogus_eip():
cm.value.request_id.should_not.be.none
@mock_ec2
def test_eip_release_bogus_eip_boto3():
"""Release bogus EIP"""
client = boto3.client("ec2", region_name="us-east-1")
with pytest.raises(ClientError) as ex:
client.release_address(AllocationId="bogus")
ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
ex.value.response["ResponseMetadata"]["RequestId"].shouldnt.be.none
ex.value.response["Error"]["Code"].should.equal("InvalidAllocationID.NotFound")
# Has boto3 equivalent
@mock_ec2_deprecated
def test_eip_disassociate_arg_error():
"""Invalid arguments disassociate address"""
@ -378,6 +716,19 @@ def test_eip_disassociate_arg_error():
cm.value.request_id.should_not.be.none
@mock_ec2
def test_eip_disassociate_arg_error_boto3():
"""Invalid arguments disassociate address"""
client = boto3.client("ec2", region_name="us-east-1")
with pytest.raises(ClientError) as ex:
client.disassociate_address()
ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
ex.value.response["ResponseMetadata"]["RequestId"].shouldnt.be.none
ex.value.response["Error"]["Code"].should.equal("MissingParameter")
# Has boto3 equivalent
@mock_ec2_deprecated
def test_eip_release_arg_error():
"""Invalid arguments release address"""
@ -390,6 +741,19 @@ def test_eip_release_arg_error():
cm.value.request_id.should_not.be.none
@mock_ec2
def test_eip_release_arg_error_boto3():
"""Invalid arguments release address"""
client = boto3.client("ec2", region_name="us-east-1")
with pytest.raises(ClientError) as ex:
client.release_address()
ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
ex.value.response["ResponseMetadata"]["RequestId"].shouldnt.be.none
ex.value.response["Error"]["Code"].should.equal("MissingParameter")
# Has boto3 equivalent
@mock_ec2_deprecated
def test_eip_describe():
"""Listing of allocated Elastic IP Addresses."""
@ -430,6 +794,51 @@ def test_eip_describe():
len(conn.get_all_addresses()).should.be.equal(0)
@mock_ec2
def test_eip_describe_boto3():
"""Listing of allocated Elastic IP Addresses."""
client = boto3.client("ec2", region_name="us-east-1")
ec2 = boto3.resource("ec2", region_name="us-east-1")
eips = []
number_of_classic_ips = 2
number_of_vpc_ips = 2
# allocate some IPs
for _ in range(number_of_classic_ips):
eips.append(ec2.ClassicAddress(client.allocate_address()["PublicIp"]))
for _ in range(number_of_vpc_ips):
eip_id = client.allocate_address(Domain="vpc")["AllocationId"]
eips.append(ec2.VpcAddress(eip_id))
eips.should.have.length_of(number_of_classic_ips + number_of_vpc_ips)
# Can we find each one individually?
for eip in eips:
if eip.allocation_id:
lookup_addresses = client.describe_addresses(
AllocationIds=[eip.allocation_id]
)["Addresses"]
else:
lookup_addresses = client.describe_addresses(PublicIps=[eip.public_ip])[
"Addresses"
]
len(lookup_addresses).should.be.equal(1)
lookup_addresses[0]["PublicIp"].should.be.equal(eip.public_ip)
# Can we find first two when we search for them?
lookup_addresses = client.describe_addresses(
PublicIps=[eips[0].public_ip, eips[1].public_ip]
)["Addresses"]
lookup_addresses.should.have.length_of(2)
lookup_addresses[0]["PublicIp"].should.be.equal(eips[0].public_ip)
lookup_addresses[1]["PublicIp"].should.be.equal(eips[1].public_ip)
# Release all IPs
for eip in eips:
eip.release()
client.describe_addresses()["Addresses"].should.have.length_of(0)
# Has boto3 equivalent
@mock_ec2_deprecated
def test_eip_describe_none():
"""Error when search for bogus IP"""
@ -442,6 +851,18 @@ def test_eip_describe_none():
cm.value.request_id.should_not.be.none
@mock_ec2
def test_eip_describe_none_boto3():
"""Error when search for bogus IP"""
client = boto3.client("ec2", region_name="us-east-1")
with pytest.raises(ClientError) as ex:
client.describe_addresses(PublicIps=["256.256.256.256"])
ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
ex.value.response["ResponseMetadata"]["RequestId"].shouldnt.be.none
ex.value.response["Error"]["Code"].should.equal("InvalidAddress.NotFound")
@mock_ec2
def test_eip_filters():
service = boto3.resource("ec2", region_name="us-west-1")

View File

@ -9,10 +9,11 @@ import boto.ec2
from boto.exception import EC2ResponseError
import sure # noqa
from moto import mock_ec2, mock_ec2_deprecated
from moto import mock_ec2, mock_ec2_deprecated, settings
from tests.helpers import requires_boto_gte
# Has boto3 equivalent
@mock_ec2_deprecated
def test_elastic_network_interfaces():
conn = boto.connect_vpc("the_key", "the_secret")
@ -56,6 +57,54 @@ def test_elastic_network_interfaces():
cm.value.request_id.should_not.be.none
@mock_ec2
def test_elastic_network_interfaces_boto3():
ec2 = boto3.resource("ec2", region_name="us-east-1")
client = boto3.client("ec2", "us-east-1")
vpc = ec2.create_vpc(CidrBlock="10.0.0.0/16")
subnet = ec2.create_subnet(VpcId=vpc.id, CidrBlock="10.0.0.0/18")
with pytest.raises(ClientError) as ex:
ec2.create_network_interface(SubnetId=subnet.id, DryRun=True)
ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(412)
ex.value.response["Error"]["Code"].should.equal("DryRunOperation")
ex.value.response["Error"]["Message"].should.equal(
"An error occurred (DryRunOperation) when calling the CreateNetworkInterface operation: Request would have succeeded, but DryRun flag is set"
)
eni_id = ec2.create_network_interface(SubnetId=subnet.id).id
all_enis = client.describe_network_interfaces()["NetworkInterfaces"]
all_enis.should.have.length_of(1)
eni = all_enis[0]
eni["Groups"].should.have.length_of(0)
eni["PrivateIpAddresses"].should.have.length_of(1)
eni["PrivateIpAddresses"][0]["PrivateIpAddress"].startswith("10.").should.be.true
with pytest.raises(ClientError) as ex:
client.delete_network_interface(NetworkInterfaceId=eni_id, DryRun=True)
ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(412)
ex.value.response["Error"]["Code"].should.equal("DryRunOperation")
ex.value.response["Error"]["Message"].should.equal(
"An error occurred (DryRunOperation) when calling the DeleteNetworkInterface operation: Request would have succeeded, but DryRun flag is set"
)
client.delete_network_interface(NetworkInterfaceId=eni_id)
all_enis = client.describe_network_interfaces()["NetworkInterfaces"]
all_enis.should.have.length_of(0)
with pytest.raises(ClientError) as ex:
client.delete_network_interface(NetworkInterfaceId=eni_id)
ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
ex.value.response["ResponseMetadata"].should.have.key("RequestId")
ex.value.response["Error"]["Code"].should.equal(
"InvalidNetworkInterfaceID.NotFound"
)
# Has boto3 equivalent
@mock_ec2_deprecated
def test_elastic_network_interfaces_subnet_validation():
conn = boto.connect_vpc("the_key", "the_secret")
@ -67,6 +116,18 @@ def test_elastic_network_interfaces_subnet_validation():
cm.value.request_id.should_not.be.none
@mock_ec2
def test_elastic_network_interfaces_subnet_validation_boto3():
client = boto3.client("ec2", "us-east-1")
with pytest.raises(ClientError) as ex:
client.create_network_interface(SubnetId="subnet-abcd1234")
ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
ex.value.response["ResponseMetadata"].should.have.key("RequestId")
ex.value.response["Error"]["Code"].should.equal("InvalidSubnetID.NotFound")
# Has boto3 equivalent
@mock_ec2_deprecated
def test_elastic_network_interfaces_with_private_ip():
conn = boto.connect_vpc("the_key", "the_secret")
@ -85,6 +146,28 @@ def test_elastic_network_interfaces_with_private_ip():
eni.private_ip_addresses[0].private_ip_address.should.equal(private_ip)
@mock_ec2
def test_elastic_network_interfaces_with_private_ip_boto3():
ec2 = boto3.resource("ec2", region_name="us-east-1")
client = boto3.client("ec2", "us-east-1")
vpc = ec2.create_vpc(CidrBlock="10.0.0.0/16")
subnet = ec2.create_subnet(VpcId=vpc.id, CidrBlock="10.0.0.0/18")
private_ip = "54.0.0.1"
ec2.create_network_interface(SubnetId=subnet.id, PrivateIpAddress=private_ip)
all_enis = client.describe_network_interfaces()["NetworkInterfaces"]
all_enis.should.have.length_of(1)
eni = all_enis[0]
eni["Groups"].should.have.length_of(0)
eni["PrivateIpAddresses"].should.have.length_of(1)
eni["PrivateIpAddresses"][0]["PrivateIpAddress"].should.equal(private_ip)
# Has boto3 equivalent
@mock_ec2_deprecated
def test_elastic_network_interfaces_with_groups():
conn = boto.connect_vpc("the_key", "the_secret")
@ -110,6 +193,29 @@ def test_elastic_network_interfaces_with_groups():
)
@mock_ec2
def test_elastic_network_interfaces_with_groups_boto3():
ec2 = boto3.resource("ec2", region_name="us-east-1")
client = boto3.client("ec2", "us-east-1")
vpc = ec2.create_vpc(CidrBlock="10.0.0.0/16")
subnet = ec2.create_subnet(VpcId=vpc.id, CidrBlock="10.0.0.0/18")
sec_group1 = ec2.create_security_group(GroupName="group #1", Description="n/a")
sec_group2 = ec2.create_security_group(GroupName="group #2", Description="n/a")
subnet.create_network_interface(Groups=[sec_group1.id, sec_group2.id])
all_enis = client.describe_network_interfaces()["NetworkInterfaces"]
all_enis.should.have.length_of(1)
eni = all_enis[0]
eni["Groups"].should.have.length_of(2)
set([group["GroupId"] for group in eni["Groups"]]).should.equal(
set([sec_group1.id, sec_group2.id])
)
# Has boto3 equivalent
@requires_boto_gte("2.12.0")
@mock_ec2_deprecated
def test_elastic_network_interfaces_modify_attribute():
@ -154,6 +260,47 @@ def test_elastic_network_interfaces_modify_attribute():
eni.groups[1].id.should.equal(security_group2.id)
@mock_ec2
def test_elastic_network_interfaces_modify_attribute_boto3():
ec2 = boto3.resource("ec2", region_name="us-east-1")
client = boto3.client("ec2", "us-east-1")
vpc = ec2.create_vpc(CidrBlock="10.0.0.0/16")
subnet = ec2.create_subnet(VpcId=vpc.id, CidrBlock="10.0.0.0/18")
sec_group1 = ec2.create_security_group(GroupName="group #1", Description="n/a")
sec_group2 = ec2.create_security_group(GroupName="group #2", Description="n/a")
eni_id = subnet.create_network_interface(Groups=[sec_group1.id]).id
all_enis = client.describe_network_interfaces()["NetworkInterfaces"]
all_enis.should.have.length_of(1)
eni = all_enis[0]
eni["Groups"].should.have.length_of(1)
eni["Groups"][0]["GroupId"].should.equal(sec_group1.id)
with pytest.raises(ClientError) as ex:
client.modify_network_interface_attribute(
NetworkInterfaceId=eni_id, Groups=[sec_group2.id], DryRun=True
)
ex.value.response["Error"]["Code"].should.equal("DryRunOperation")
ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(412)
ex.value.response["Error"]["Message"].should.equal(
"An error occurred (DryRunOperation) when calling the ModifyNetworkInterface operation: Request would have succeeded, but DryRun flag is set"
)
client.modify_network_interface_attribute(
NetworkInterfaceId=eni_id, Groups=[sec_group2.id]
)
all_enis = client.describe_network_interfaces()["NetworkInterfaces"]
all_enis.should.have.length_of(1)
eni = all_enis[0]
eni["Groups"].should.have.length_of(1)
eni["Groups"][0]["GroupId"].should.equal(sec_group2.id)
# Has boto3 equivalent
@mock_ec2_deprecated
def test_elastic_network_interfaces_filtering():
conn = boto.connect_vpc("the_key", "the_secret")
@ -215,6 +362,75 @@ def test_elastic_network_interfaces_filtering():
).should.throw(NotImplementedError)
@mock_ec2
def test_elastic_network_interfaces_filtering_boto3():
ec2 = boto3.resource("ec2", region_name="us-east-1")
client = boto3.client("ec2", "us-east-1")
vpc = ec2.create_vpc(CidrBlock="10.0.0.0/16")
subnet = ec2.create_subnet(VpcId=vpc.id, CidrBlock="10.0.0.0/18")
sec_group1 = ec2.create_security_group(GroupName="group #1", Description="n/a")
sec_group2 = ec2.create_security_group(GroupName="group #2", Description="n/a")
eni1 = subnet.create_network_interface(Groups=[sec_group1.id, sec_group2.id])
eni2 = subnet.create_network_interface(Groups=[sec_group1.id])
eni3 = subnet.create_network_interface(Description="test description")
all_enis = client.describe_network_interfaces()["NetworkInterfaces"]
all_enis.should.have.length_of(3)
# Filter by NetworkInterfaceId
enis_by_id = client.describe_network_interfaces(NetworkInterfaceIds=[eni1.id])[
"NetworkInterfaces"
]
enis_by_id.should.have.length_of(1)
set([eni["NetworkInterfaceId"] for eni in enis_by_id]).should.equal(set([eni1.id]))
# Filter by ENI ID
enis_by_id = client.describe_network_interfaces(
Filters=[{"Name": "network-interface-id", "Values": [eni1.id]}]
)["NetworkInterfaces"]
enis_by_id.should.have.length_of(1)
set([eni["NetworkInterfaceId"] for eni in enis_by_id]).should.equal(set([eni1.id]))
# Filter by Security Group
enis_by_group = client.describe_network_interfaces(
Filters=[{"Name": "group-id", "Values": [sec_group1.id]}]
)["NetworkInterfaces"]
enis_by_group.should.have.length_of(2)
set([eni["NetworkInterfaceId"] for eni in enis_by_group]).should.equal(
set([eni1.id, eni2.id])
)
# Filter by ENI ID and Security Group
enis_by_group = client.describe_network_interfaces(
Filters=[
{"Name": "network-interface-id", "Values": [eni1.id]},
{"Name": "group-id", "Values": [sec_group1.id]},
]
)["NetworkInterfaces"]
enis_by_group.should.have.length_of(1)
set([eni["NetworkInterfaceId"] for eni in enis_by_group]).should.equal(
set([eni1.id])
)
# Filter by Description
enis_by_description = client.describe_network_interfaces(
Filters=[{"Name": "description", "Values": [eni3.description]}]
)["NetworkInterfaces"]
enis_by_description.should.have.length_of(1)
enis_by_description[0]["Description"].should.equal(eni3.description)
# Unsupported filter
if not settings.TEST_SERVER_MODE:
# ServerMode will just throw a generic 500
filters = [{"Name": "not-implemented-filter", "Values": ["foobar"]}]
client.describe_network_interfaces.when.called_with(
Filters=filters
).should.throw(NotImplementedError)
@mock_ec2
def test_elastic_network_interfaces_get_by_tag_name():
ec2 = boto3.resource("ec2", region_name="us-west-2")

View File

@ -5,6 +5,7 @@ import pytest
import boto
import boto3
from boto.exception import EC2ResponseError
from botocore.exceptions import ClientError
import sure # noqa
from botocore.exceptions import ClientError
@ -12,6 +13,7 @@ from moto import mock_ec2_deprecated, mock_ec2
from tests import EXAMPLE_AMI_ID
# Has boto3 equivalent
@mock_ec2_deprecated
def test_console_output():
conn = boto.connect_ec2("the_key", "the_secret")
@ -21,6 +23,7 @@ def test_console_output():
output.output.should_not.equal(None)
# Has boto3 equivalent
@mock_ec2_deprecated
def test_console_output_without_instance():
conn = boto.connect_ec2("the_key", "the_secret")
@ -39,3 +42,14 @@ def test_console_output_boto3():
output = instances[0].console_output()
output.get("Output").should_not.equal(None)
@mock_ec2
def test_console_output_without_instance_boto3():
client = boto3.client("ec2", "us-east-1")
with pytest.raises(ClientError) as ex:
client.get_console_output(InstanceId="i-1234abcd")
ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
ex.value.response["ResponseMetadata"]["RequestId"].shouldnt.be.none
ex.value.response["Error"]["Code"].should.equal("InvalidInstanceID.NotFound")

File diff suppressed because it is too large Load Diff

View File

@ -8,6 +8,7 @@ import boto
import boto3
from boto.exception import EC2ResponseError
from botocore.exceptions import ClientError
import sure # noqa
@ -19,6 +20,7 @@ BAD_VPC = "vpc-deadbeef"
BAD_IGW = "igw-deadbeef"
# Has boto3 equivalent
@mock_ec2_deprecated
def test_igw_create():
"""internet gateway create"""
@ -42,6 +44,31 @@ def test_igw_create():
igw.attachments.should.have.length_of(0)
@mock_ec2
def test_igw_create_boto3():
""" internet gateway create """
ec2 = boto3.resource("ec2", "us-west-1")
client = boto3.client("ec2", "us-west-1")
client.describe_internet_gateways()["InternetGateways"].should.have.length_of(0)
with pytest.raises(ClientError) as ex:
client.create_internet_gateway(DryRun=True)
ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(412)
ex.value.response["Error"]["Code"].should.equal("DryRunOperation")
ex.value.response["Error"]["Message"].should.equal(
"An error occurred (DryRunOperation) when calling the CreateInternetGateway operation: Request would have succeeded, but DryRun flag is set"
)
igw = ec2.create_internet_gateway()
client.describe_internet_gateways()["InternetGateways"].should.have.length_of(1)
igw.id.should.match(r"igw-[0-9a-f]+")
igw = client.describe_internet_gateways()["InternetGateways"][0]
igw["Attachments"].should.have.length_of(0)
# Has boto3 equivalent
@mock_ec2_deprecated
def test_igw_attach():
"""internet gateway attach"""
@ -63,6 +90,30 @@ def test_igw_attach():
igw.attachments[0].vpc_id.should.be.equal(vpc.id)
@mock_ec2
def test_igw_attach_boto3():
""" internet gateway attach """
ec2 = boto3.resource("ec2", "us-west-1")
client = boto3.client("ec2", "us-west-1")
igw = ec2.create_internet_gateway()
vpc = ec2.create_vpc(CidrBlock=VPC_CIDR)
with pytest.raises(ClientError) as ex:
vpc.attach_internet_gateway(InternetGatewayId=igw.id, DryRun=True)
ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(412)
ex.value.response["Error"]["Code"].should.equal("DryRunOperation")
ex.value.response["Error"]["Message"].should.equal(
"An error occurred (DryRunOperation) when calling the AttachInternetGateway operation: Request would have succeeded, but DryRun flag is set"
)
vpc.attach_internet_gateway(InternetGatewayId=igw.id)
igw = client.describe_internet_gateways()["InternetGateways"][0]
igw["Attachments"].should.equal([{"State": "available", "VpcId": vpc.id}])
# Has boto3 equivalent
@mock_ec2_deprecated
def test_igw_attach_bad_vpc():
"""internet gateway fail to attach w/ bad vpc"""
@ -76,6 +127,20 @@ def test_igw_attach_bad_vpc():
cm.value.request_id.should_not.be.none
@mock_ec2
def test_igw_attach_bad_vpc_boto3():
""" internet gateway fail to attach w/ bad vpc """
ec2 = boto3.resource("ec2", "us-west-1")
igw = ec2.create_internet_gateway()
with pytest.raises(ClientError) as ex:
igw.attach_to_vpc(VpcId=BAD_VPC)
ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
ex.value.response["ResponseMetadata"].should.have.key("RequestId")
ex.value.response["Error"]["Code"].should.equal("InvalidVpcID.NotFound")
# Has boto3 equivalent
@mock_ec2_deprecated
def test_igw_attach_twice():
"""internet gateway fail to attach twice"""
@ -92,6 +157,24 @@ def test_igw_attach_twice():
cm.value.request_id.should_not.be.none
@mock_ec2
def test_igw_attach_twice_boto3():
""" internet gateway fail to attach twice """
ec2 = boto3.resource("ec2", "us-west-1")
client = boto3.client("ec2", region_name="us-west-1")
igw = ec2.create_internet_gateway()
vpc1 = ec2.create_vpc(CidrBlock=VPC_CIDR)
vpc2 = ec2.create_vpc(CidrBlock=VPC_CIDR)
client.attach_internet_gateway(InternetGatewayId=igw.id, VpcId=vpc1.id)
with pytest.raises(ClientError) as ex:
client.attach_internet_gateway(InternetGatewayId=igw.id, VpcId=vpc2.id)
ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
ex.value.response["ResponseMetadata"].should.have.key("RequestId")
ex.value.response["Error"]["Code"].should.equal("Resource.AlreadyAssociated")
# Has boto3 equivalent
@mock_ec2_deprecated
def test_igw_detach():
"""internet gateway detach"""
@ -113,6 +196,31 @@ def test_igw_detach():
igw.attachments.should.have.length_of(0)
@mock_ec2
def test_igw_detach_boto3():
""" internet gateway detach"""
ec2 = boto3.resource("ec2", "us-west-1")
client = boto3.client("ec2", region_name="us-west-1")
igw = ec2.create_internet_gateway()
vpc = ec2.create_vpc(CidrBlock=VPC_CIDR)
client.attach_internet_gateway(InternetGatewayId=igw.id, VpcId=vpc.id)
with pytest.raises(ClientError) as ex:
client.detach_internet_gateway(
InternetGatewayId=igw.id, VpcId=vpc.id, DryRun=True
)
ex.value.response["Error"]["Code"].should.equal("DryRunOperation")
ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(412)
ex.value.response["Error"]["Message"].should.equal(
"An error occurred (DryRunOperation) when calling the DetachInternetGateway operation: Request would have succeeded, but DryRun flag is set"
)
client.detach_internet_gateway(InternetGatewayId=igw.id, VpcId=vpc.id)
igw = client.describe_internet_gateways()["InternetGateways"][0]
igw["Attachments"].should.have.length_of(0)
# Has boto3 equivalent
@mock_ec2_deprecated
def test_igw_detach_wrong_vpc():
"""internet gateway fail to detach w/ wrong vpc"""
@ -129,6 +237,24 @@ def test_igw_detach_wrong_vpc():
cm.value.request_id.should_not.be.none
@mock_ec2
def test_igw_detach_wrong_vpc_boto3():
""" internet gateway fail to detach w/ wrong vpc """
ec2 = boto3.resource("ec2", "us-west-1")
client = boto3.client("ec2", region_name="us-west-1")
igw = ec2.create_internet_gateway()
vpc1 = ec2.create_vpc(CidrBlock=VPC_CIDR)
vpc2 = ec2.create_vpc(CidrBlock=VPC_CIDR)
client.attach_internet_gateway(InternetGatewayId=igw.id, VpcId=vpc1.id)
with pytest.raises(ClientError) as ex:
client.detach_internet_gateway(InternetGatewayId=igw.id, VpcId=vpc2.id)
ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
ex.value.response["ResponseMetadata"].should.have.key("RequestId")
ex.value.response["Error"]["Code"].should.equal("Gateway.NotAttached")
# Has boto3 equivalent
@mock_ec2_deprecated
def test_igw_detach_invalid_vpc():
"""internet gateway fail to detach w/ invalid vpc"""
@ -144,6 +270,23 @@ def test_igw_detach_invalid_vpc():
cm.value.request_id.should_not.be.none
@mock_ec2
def test_igw_detach_invalid_vpc_boto3():
""" internet gateway fail to detach w/ invalid vpc """
ec2 = boto3.resource("ec2", "us-west-1")
client = boto3.client("ec2", region_name="us-west-1")
igw = ec2.create_internet_gateway()
vpc = ec2.create_vpc(CidrBlock=VPC_CIDR)
client.attach_internet_gateway(InternetGatewayId=igw.id, VpcId=vpc.id)
with pytest.raises(ClientError) as ex:
client.detach_internet_gateway(InternetGatewayId=igw.id, VpcId=BAD_VPC)
ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
ex.value.response["ResponseMetadata"].should.have.key("RequestId")
ex.value.response["Error"]["Code"].should.equal("Gateway.NotAttached")
# Has boto3 equivalent
@mock_ec2_deprecated
def test_igw_detach_unattached():
"""internet gateway fail to detach unattached"""
@ -158,6 +301,22 @@ def test_igw_detach_unattached():
cm.value.request_id.should_not.be.none
@mock_ec2
def test_igw_detach_unattached_boto3():
""" internet gateway fail to detach unattached """
ec2 = boto3.resource("ec2", "us-west-1")
client = boto3.client("ec2", region_name="us-west-1")
igw = ec2.create_internet_gateway()
vpc = ec2.create_vpc(CidrBlock=VPC_CIDR)
with pytest.raises(ClientError) as ex:
client.detach_internet_gateway(InternetGatewayId=igw.id, VpcId=vpc.id)
ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
ex.value.response["ResponseMetadata"].should.have.key("RequestId")
ex.value.response["Error"]["Code"].should.equal("Gateway.NotAttached")
# Has boto3 equivalent
@mock_ec2_deprecated
def test_igw_delete():
"""internet gateway delete"""
@ -179,6 +338,30 @@ def test_igw_delete():
conn.get_all_internet_gateways().should.have.length_of(0)
@mock_ec2
def test_igw_delete_boto3():
""" internet gateway delete"""
ec2 = boto3.resource("ec2", "us-west-1")
client = boto3.client("ec2", region_name="us-west-1")
ec2.create_vpc(CidrBlock=VPC_CIDR)
client.describe_internet_gateways()["InternetGateways"].should.have.length_of(0)
igw = ec2.create_internet_gateway()
client.describe_internet_gateways()["InternetGateways"].should.have.length_of(1)
with pytest.raises(ClientError) as ex:
client.delete_internet_gateway(InternetGatewayId=igw.id, DryRun=True)
ex.value.response["Error"]["Code"].should.equal("DryRunOperation")
ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(412)
ex.value.response["Error"]["Message"].should.equal(
"An error occurred (DryRunOperation) when calling the DeleteInternetGateway operation: Request would have succeeded, but DryRun flag is set"
)
client.delete_internet_gateway(InternetGatewayId=igw.id)
client.describe_internet_gateways()["InternetGateways"].should.have.length_of(0)
# Has boto3 equivalent
@mock_ec2_deprecated
def test_igw_delete_attached():
"""internet gateway fail to delete attached"""
@ -194,6 +377,23 @@ def test_igw_delete_attached():
cm.value.request_id.should_not.be.none
@mock_ec2
def test_igw_delete_attached_boto3():
""" internet gateway fail to delete attached """
ec2 = boto3.resource("ec2", "us-west-1")
client = boto3.client("ec2", "us-west-1")
igw = ec2.create_internet_gateway()
vpc = ec2.create_vpc(CidrBlock=VPC_CIDR)
client.attach_internet_gateway(InternetGatewayId=igw.id, VpcId=vpc.id)
with pytest.raises(ClientError) as ex:
client.delete_internet_gateway(InternetGatewayId=igw.id)
ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
ex.value.response["ResponseMetadata"].should.have.key("RequestId")
ex.value.response["Error"]["Code"].should.equal("DependencyViolation")
# Has boto3 equivalent
@mock_ec2_deprecated
def test_igw_desribe():
"""internet gateway fetch by id"""
@ -203,6 +403,19 @@ def test_igw_desribe():
igw.id.should.equal(igw_by_search.id)
@mock_ec2
def test_igw_describe_boto3():
""" internet gateway fetch by id """
ec2 = boto3.resource("ec2", "us-west-1")
client = boto3.client("ec2", "us-west-1")
igw = ec2.create_internet_gateway()
igw_by_search = client.describe_internet_gateways(InternetGatewayIds=[igw.id])[
"InternetGateways"
][0]
igw.id.should.equal(igw_by_search["InternetGatewayId"])
# Has boto3 equivalent
@mock_ec2_deprecated
def test_igw_describe_bad_id():
"""internet gateway fail to fetch by bad id"""
@ -214,6 +427,18 @@ def test_igw_describe_bad_id():
cm.value.request_id.should_not.be.none
@mock_ec2
def test_igw_describe_bad_id_boto3():
""" internet gateway fail to fetch by bad id """
client = boto3.client("ec2", "us-west-1")
with pytest.raises(ClientError) as ex:
client.describe_internet_gateways(InternetGatewayIds=[BAD_IGW])
ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
ex.value.response["ResponseMetadata"].should.have.key("RequestId")
ex.value.response["Error"]["Code"].should.equal("InvalidInternetGatewayID.NotFound")
# Has boto3 equivalent
@mock_ec2_deprecated
def test_igw_filter_by_vpc_id():
"""internet gateway filter by vpc id"""
@ -229,6 +454,25 @@ def test_igw_filter_by_vpc_id():
result[0].id.should.equal(igw1.id)
@mock_ec2
def test_igw_filter_by_vpc_id_boto3():
""" internet gateway filter by vpc id """
ec2 = boto3.resource("ec2", "us-west-1")
client = boto3.client("ec2", "us-west-1")
igw1 = ec2.create_internet_gateway()
ec2.create_internet_gateway()
vpc = ec2.create_vpc(CidrBlock=VPC_CIDR)
client.attach_internet_gateway(InternetGatewayId=igw1.id, VpcId=vpc.id)
result = client.describe_internet_gateways(
Filters=[{"Name": "attachment.vpc-id", "Values": [vpc.id]}]
)
result["InternetGateways"].should.have.length_of(1)
result["InternetGateways"][0]["InternetGatewayId"].should.equal(igw1.id)
# Has boto3 equivalent
@mock_ec2_deprecated
def test_igw_filter_by_tags():
"""internet gateway filter by vpc id"""
@ -243,6 +487,24 @@ def test_igw_filter_by_tags():
result[0].id.should.equal(igw1.id)
@mock_ec2
def test_igw_filter_by_tags_boto3():
""" internet gateway filter by vpc id """
ec2 = boto3.resource("ec2", "us-west-1")
client = boto3.client("ec2", "us-west-1")
igw1 = ec2.create_internet_gateway()
igw2 = ec2.create_internet_gateway()
igw1.create_tags(Tags=[{"Key": "tests", "Value": "yes"}])
result = client.describe_internet_gateways(
Filters=[{"Name": "tag:tests", "Values": ["yes"]}]
)
result["InternetGateways"].should.have.length_of(1)
result["InternetGateways"][0]["InternetGatewayId"].should.equal(igw1.id)
# Has boto3 equivalent
@mock_ec2_deprecated
def test_igw_filter_by_internet_gateway_id():
"""internet gateway filter by internet gateway id"""
@ -256,6 +518,23 @@ def test_igw_filter_by_internet_gateway_id():
result[0].id.should.equal(igw1.id)
@mock_ec2
def test_igw_filter_by_internet_gateway_id_boto3():
""" internet gateway filter by internet gateway id """
ec2 = boto3.resource("ec2", "us-west-1")
client = boto3.client("ec2", "us-west-1")
igw1 = ec2.create_internet_gateway()
igw2 = ec2.create_internet_gateway()
result = client.describe_internet_gateways(
Filters=[{"Name": "internet-gateway-id", "Values": [igw1.id]}]
)
result["InternetGateways"].should.have.length_of(1)
result["InternetGateways"][0]["InternetGatewayId"].should.equal(igw1.id)
# Has boto3 equivalent
@mock_ec2_deprecated
def test_igw_filter_by_attachment_state():
"""internet gateway filter by attachment state"""
@ -271,6 +550,24 @@ def test_igw_filter_by_attachment_state():
result[0].id.should.equal(igw1.id)
@mock_ec2
def test_igw_filter_by_attachment_state_boto3():
""" internet gateway filter by attachment state """
ec2 = boto3.resource("ec2", "us-west-1")
client = boto3.client("ec2", "us-west-1")
igw1 = ec2.create_internet_gateway()
igw2 = ec2.create_internet_gateway()
vpc = ec2.create_vpc(CidrBlock=VPC_CIDR)
client.attach_internet_gateway(InternetGatewayId=igw1.id, VpcId=vpc.id)
result = client.describe_internet_gateways(
Filters=[{"Name": "attachment.state", "Values": ["available"]}]
)
result["InternetGateways"].should.have.length_of(1)
result["InternetGateways"][0]["InternetGatewayId"].should.equal(igw1.id)
@mock_ec2
def test_create_internet_gateway_with_tags():
ec2 = boto3.resource("ec2", region_name="eu-central-1")

View File

@ -3,10 +3,12 @@ from __future__ import unicode_literals
import pytest
import boto
import boto3
import sure # noqa
from boto.exception import EC2ResponseError
from moto import mock_ec2_deprecated
from botocore.exceptions import ClientError
from moto import mock_ec2, mock_ec2_deprecated
from .helpers import rsa_check_private_key
@ -44,12 +46,21 @@ ffsm7UIHtCBYERr9Nx0u20ldfhkgB1lhaJb5o0ZJ3pmJ38KChfyHe5EUcqRdEFo89Mp72VI2Z6UHyL17
moto@github.com"""
# Has boto3 equivalent
@mock_ec2_deprecated
def test_key_pairs_empty():
conn = boto.connect_ec2("the_key", "the_secret")
assert len(conn.get_all_key_pairs()) == 0
@mock_ec2
def test_key_pairs_empty_boto3():
ec2 = boto3.resource("ec2", "us-west-1")
client = boto3.client("ec2", "us-west-1")
client.describe_key_pairs()["KeyPairs"].should.be.empty
# Has boto3 equivalent
@mock_ec2_deprecated
def test_key_pairs_invalid_id():
conn = boto.connect_ec2("the_key", "the_secret")
@ -61,6 +72,19 @@ def test_key_pairs_invalid_id():
cm.value.request_id.should_not.be.none
@mock_ec2
def test_key_pairs_invalid_id_boto3():
ec2 = boto3.resource("ec2", "us-west-1")
client = boto3.client("ec2", "us-west-1")
with pytest.raises(ClientError) as ex:
client.describe_key_pairs(KeyNames=["foo"])
ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
ex.value.response["ResponseMetadata"].should.have.key("RequestId")
ex.value.response["Error"]["Code"].should.equal("InvalidKeyPair.NotFound")
# Has boto3 equivalent
@mock_ec2_deprecated
def test_key_pairs_create():
conn = boto.connect_ec2("the_key", "the_secret")
@ -81,6 +105,7 @@ def test_key_pairs_create():
assert kps[0].name == "foo"
# Has boto3 equivalent
@mock_ec2_deprecated
def test_key_pairs_create_two():
conn = boto.connect_ec2("the_key", "the_secret")
@ -102,6 +127,43 @@ def test_key_pairs_create_two():
kps[0].name.should.equal("foo")
@mock_ec2
def test_key_pairs_create_dryrun_boto3():
ec2 = boto3.resource("ec2", "us-west-1")
with pytest.raises(ClientError) as ex:
ec2.create_key_pair(KeyName="foo", DryRun=True)
ex.value.response["Error"]["Code"].should.equal("DryRunOperation")
ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(412)
ex.value.response["Error"]["Message"].should.equal(
"An error occurred (DryRunOperation) when calling the CreateKeyPair operation: Request would have succeeded, but DryRun flag is set"
)
@mock_ec2
def test_key_pairs_create_boto3():
ec2 = boto3.resource("ec2", "us-west-1")
client = boto3.client("ec2", "us-west-1")
kp = ec2.create_key_pair(KeyName="foo")
rsa_check_private_key(kp.key_material)
# Verify the client can create a key_pair as well - should behave the same
kp2 = client.create_key_pair(KeyName="foo2")
rsa_check_private_key(kp2["KeyMaterial"])
kp.key_material.shouldnt.equal(kp2["KeyMaterial"])
kps = client.describe_key_pairs()["KeyPairs"]
kps.should.have.length_of(2)
set([k["KeyName"] for k in kps]).should.equal(set(["foo", "foo2"]))
kps = client.describe_key_pairs(KeyNames=["foo"])["KeyPairs"]
kps.should.have.length_of(1)
kps[0].should.have.key("KeyName").equal("foo")
kps[0].should.have.key("KeyFingerprint")
# Has boto3 equivalent
@mock_ec2_deprecated
def test_key_pairs_create_exist():
conn = boto.connect_ec2("the_key", "the_secret")
@ -115,6 +177,19 @@ def test_key_pairs_create_exist():
cm.value.request_id.should_not.be.none
@mock_ec2
def test_key_pairs_create_exist_boto3():
client = boto3.client("ec2", "us-west-1")
client.create_key_pair(KeyName="foo")
with pytest.raises(ClientError) as ex:
client.create_key_pair(KeyName="foo")
ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
ex.value.response["ResponseMetadata"].should.have.key("RequestId")
ex.value.response["Error"]["Code"].should.equal("InvalidKeyPair.Duplicate")
# Has boto3 equivalent
@mock_ec2_deprecated
def test_key_pairs_delete_no_exist():
conn = boto.connect_ec2("the_key", "the_secret")
@ -123,6 +198,14 @@ def test_key_pairs_delete_no_exist():
r.should.be.ok
@mock_ec2
def test_key_pairs_delete_no_exist_boto3():
client = boto3.client("ec2", "us-west-1")
client.describe_key_pairs()["KeyPairs"].should.have.length_of(0)
client.delete_key_pair(KeyName="non-existing")
# Has boto3 equivalent
@mock_ec2_deprecated
def test_key_pairs_delete_exist():
conn = boto.connect_ec2("the_key", "the_secret")
@ -141,6 +224,25 @@ def test_key_pairs_delete_exist():
assert len(conn.get_all_key_pairs()) == 0
@mock_ec2
def test_key_pairs_delete_exist_boto3():
ec2 = boto3.resource("ec2", "us-west-1")
client = boto3.client("ec2", "us-west-1")
client.create_key_pair(KeyName="foo")
with pytest.raises(ClientError) as ex:
client.delete_key_pair(KeyName="foo", DryRun=True)
ex.value.response["Error"]["Code"].should.equal("DryRunOperation")
ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(412)
ex.value.response["Error"]["Message"].should.equal(
"An error occurred (DryRunOperation) when calling the DeleteKeyPair operation: Request would have succeeded, but DryRun flag is set"
)
client.delete_key_pair(KeyName="foo")
client.describe_key_pairs()["KeyPairs"].should.equal([])
# Has boto3 equivalent
@mock_ec2_deprecated
def test_key_pairs_import():
conn = boto.connect_ec2("the_key", "the_secret")
@ -167,6 +269,41 @@ def test_key_pairs_import():
assert kps[1].name == kp2.name
@mock_ec2
def test_key_pairs_import_boto3():
ec2 = boto3.resource("ec2", "us-west-1")
client = boto3.client("ec2", "us-west-1")
with pytest.raises(ClientError) as ex:
client.import_key_pair(
KeyName="foo", PublicKeyMaterial=RSA_PUBLIC_KEY_OPENSSH, DryRun=True
)
ex.value.response["Error"]["Code"].should.equal("DryRunOperation")
ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(412)
ex.value.response["Error"]["Message"].should.equal(
"An error occurred (DryRunOperation) when calling the ImportKeyPair operation: Request would have succeeded, but DryRun flag is set"
)
kp1 = client.import_key_pair(
KeyName="foo", PublicKeyMaterial=RSA_PUBLIC_KEY_OPENSSH
)
print(kp1)
kp1.should.have.key("KeyName").equal("foo")
kp1.should.have.key("KeyFingerprint").equal(RSA_PUBLIC_KEY_FINGERPRINT)
kp2 = client.import_key_pair(
KeyName="foo2", PublicKeyMaterial=RSA_PUBLIC_KEY_RFC4716
)
kp2.should.have.key("KeyName").equal("foo2")
kp2.should.have.key("KeyFingerprint").equal(RSA_PUBLIC_KEY_FINGERPRINT)
kps = client.describe_key_pairs()["KeyPairs"]
kps.should.have.length_of(2)
kps[0]["KeyName"].should.equal(kp1["KeyName"])
kps[1]["KeyName"].should.equal(kp2["KeyName"])
# Has boto3 equivalent
@mock_ec2_deprecated
def test_key_pairs_import_exist():
conn = boto.connect_ec2("the_key", "the_secret")
@ -181,6 +318,23 @@ def test_key_pairs_import_exist():
cm.value.request_id.should_not.be.none
@mock_ec2
def test_key_pairs_import_exist_boto3():
ec2 = boto3.resource("ec2", "us-west-1")
client = boto3.client("ec2", "us-west-1")
kp = client.import_key_pair(KeyName="foo", PublicKeyMaterial=RSA_PUBLIC_KEY_OPENSSH)
kp["KeyName"].should.equal("foo")
client.describe_key_pairs()["KeyPairs"].should.have.length_of(1)
with pytest.raises(ClientError) as ex:
client.create_key_pair(KeyName="foo")
ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
ex.value.response["ResponseMetadata"].should.have.key("RequestId")
ex.value.response["Error"]["Code"].should.equal("InvalidKeyPair.Duplicate")
# Has boto3 equivalent
@mock_ec2_deprecated
def test_key_pairs_invalid():
conn = boto.connect_ec2("the_key", "the_secret")
@ -204,6 +358,34 @@ def test_key_pairs_invalid():
ex.value.message.should.equal("Key is not in valid OpenSSH public key format")
@mock_ec2
def test_key_pairs_invalid_boto3():
ec2 = boto3.resource("ec2", "us-west-1")
client = boto3.client("ec2", "us-west-1")
with pytest.raises(ClientError) as ex:
client.import_key_pair(KeyName="foo", PublicKeyMaterial=b"")
ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
err = ex.value.response["Error"]
err["Code"].should.equal("InvalidKeyPair.Format")
err["Message"].should.equal("Key is not in valid OpenSSH public key format")
with pytest.raises(ClientError) as ex:
client.import_key_pair(KeyName="foo", PublicKeyMaterial=b"garbage")
ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
err = ex.value.response["Error"]
err["Code"].should.equal("InvalidKeyPair.Format")
err["Message"].should.equal("Key is not in valid OpenSSH public key format")
with pytest.raises(ClientError) as ex:
client.import_key_pair(KeyName="foo", PublicKeyMaterial=DSA_PUBLIC_KEY_OPENSSH)
ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
err = ex.value.response["Error"]
err["Code"].should.equal("InvalidKeyPair.Format")
err["Message"].should.equal("Key is not in valid OpenSSH public key format")
# Has boto3 equivalent
@mock_ec2_deprecated
def test_key_pair_filters():
conn = boto.connect_ec2("the_key", "the_secret")
@ -217,3 +399,23 @@ def test_key_pair_filters():
kp_by_name = conn.get_all_key_pairs(filters={"fingerprint": kp3.fingerprint})
set([kp.name for kp in kp_by_name]).should.equal(set([kp3.name]))
@mock_ec2
def test_key_pair_filters_boto3():
ec2 = boto3.resource("ec2", "us-west-1")
client = boto3.client("ec2", "us-west-1")
_ = ec2.create_key_pair(KeyName="kpfltr1")
kp2 = ec2.create_key_pair(KeyName="kpfltr2")
kp3 = ec2.create_key_pair(KeyName="kpfltr3")
kp_by_name = client.describe_key_pairs(
Filters=[{"Name": "key-name", "Values": ["kpfltr2"]}]
)["KeyPairs"]
set([kp["KeyName"] for kp in kp_by_name]).should.equal(set([kp2.name]))
kp_by_name = client.describe_key_pairs(
Filters=[{"Name": "fingerprint", "Values": [kp3.key_fingerprint]}]
)["KeyPairs"]
set([kp["KeyName"] for kp in kp_by_name]).should.equal(set([kp3.name]))

View File

@ -9,6 +9,7 @@ from moto import mock_ec2_deprecated, mock_ec2
from moto.ec2.models import OWNER_ID
# Has boto3 equivalent
@mock_ec2_deprecated
def test_default_network_acl_created_with_vpc():
conn = boto.connect_vpc("the_key", "the secret")
@ -17,6 +18,17 @@ def test_default_network_acl_created_with_vpc():
all_network_acls.should.have.length_of(2)
@mock_ec2
def test_default_network_acl_created_with_vpc_boto3():
client = boto3.client("ec2", region_name="us-east-1")
ec2 = boto3.resource("ec2", region_name="us-east-1")
ec2.create_vpc(CidrBlock="10.0.0.0/16")
all_network_acls = client.describe_network_acls()["NetworkAcls"]
all_network_acls.should.have.length_of(2)
# Has boto3 equivalent
@mock_ec2_deprecated
def test_network_acls():
conn = boto.connect_vpc("the_key", "the secret")
@ -26,6 +38,25 @@ def test_network_acls():
all_network_acls.should.have.length_of(3)
@mock_ec2
def test_network_create_and_list_acls_boto3():
client = boto3.client("ec2", region_name="us-east-1")
ec2 = boto3.resource("ec2", region_name="us-east-1")
vpc = ec2.create_vpc(CidrBlock="10.0.0.0/16")
created_acl = ec2.create_network_acl(VpcId=vpc.id)
all_network_acls = client.describe_network_acls()["NetworkAcls"]
all_network_acls.should.have.length_of(3)
acl_found = [
a for a in all_network_acls if a["NetworkAclId"] == created_acl.network_acl_id
][0]
acl_found["VpcId"].should.equal(vpc.id)
acl_found["Tags"].should.equal([])
acl_found["IsDefault"].should.equal(False)
# Has boto3 equivalent
@mock_ec2_deprecated
def test_new_subnet_associates_with_default_network_acl():
conn = boto.connect_vpc("the_key", "the secret")
@ -40,6 +71,22 @@ def test_new_subnet_associates_with_default_network_acl():
[a.subnet_id for a in acl.associations].should.contain(subnet.id)
@mock_ec2
def test_new_subnet_associates_with_default_network_acl_boto3():
client = boto3.client("ec2", region_name="us-east-1")
ec2 = boto3.resource("ec2", region_name="us-east-1")
default_vpc = client.describe_vpcs()["Vpcs"][0]
subnet = ec2.create_subnet(VpcId=default_vpc["VpcId"], CidrBlock="172.31.112.0/20")
all_network_acls = client.describe_network_acls()["NetworkAcls"]
all_network_acls.should.have.length_of(1)
acl = all_network_acls[0]
acl["Associations"].should.have.length_of(7)
[a["SubnetId"] for a in acl["Associations"]].should.contain(subnet.id)
# Has boto3 equivalent
@mock_ec2_deprecated
def test_network_acl_entries():
conn = boto.connect_vpc("the_key", "the secret")
@ -69,6 +116,43 @@ def test_network_acl_entries():
entries[0].rule_action.should.equal("ALLOW")
@mock_ec2
def test_network_acl_entries_boto3():
client = boto3.client("ec2", region_name="us-east-1")
ec2 = boto3.resource("ec2", region_name="us-east-1")
vpc = ec2.create_vpc(CidrBlock="10.0.0.0/16")
network_acl = ec2.create_network_acl(VpcId=vpc.id)
client.create_network_acl_entry(
NetworkAclId=network_acl.id,
RuleNumber=110,
Protocol="6", # TCP
RuleAction="ALLOW",
CidrBlock="0.0.0.0/0",
Egress=False,
PortRange={"From": 443, "To": 443},
)
all_network_acls = client.describe_network_acls()["NetworkAcls"]
all_network_acls.should.have.length_of(3)
test_network_acl = next(
na for na in all_network_acls if na["NetworkAclId"] == network_acl.id
)
test_network_acl.should.have.key("IsDefault").should.equal(False)
entries = test_network_acl["Entries"]
entries.should.have.length_of(1)
entries[0]["RuleNumber"].should.equal(110)
entries[0]["Protocol"].should.equal("6")
entries[0]["RuleAction"].should.equal("ALLOW")
entries[0]["Egress"].should.equal(False)
entries[0]["PortRange"].should.equal({"To": 443, "From": 443})
entries[0]["CidrBlock"].should.equal("0.0.0.0/0")
# Has boto3 equivalent
@mock_ec2_deprecated
def test_delete_network_acl_entry():
conn = boto.connect_vpc("the_key", "the secret")
@ -95,6 +179,36 @@ def test_delete_network_acl_entry():
entries.should.have.length_of(0)
@mock_ec2
def test_delete_network_acl_entry_boto3():
client = boto3.client("ec2", region_name="us-east-1")
ec2 = boto3.resource("ec2", region_name="us-east-1")
vpc = ec2.create_vpc(CidrBlock="10.0.0.0/16")
network_acl = ec2.create_network_acl(VpcId=vpc.id)
client.create_network_acl_entry(
NetworkAclId=network_acl.id,
RuleNumber=110,
Protocol="6", # TCP
RuleAction="ALLOW",
CidrBlock="0.0.0.0/0",
Egress=False,
PortRange={"From": 443, "To": 443},
)
client.delete_network_acl_entry(
NetworkAclId=network_acl.id, RuleNumber=110, Egress=False
)
all_network_acls = client.describe_network_acls()["NetworkAcls"]
test_network_acl = next(
na for na in all_network_acls if na["NetworkAclId"] == network_acl.id
)
test_network_acl["Entries"].should.have.length_of(0)
# Has boto3 equivalent
@mock_ec2_deprecated
def test_replace_network_acl_entry():
conn = boto.connect_vpc("the_key", "the secret")
@ -133,6 +247,47 @@ def test_replace_network_acl_entry():
entries[0].rule_action.should.equal("DENY")
@mock_ec2
def test_replace_network_acl_entry_boto3():
client = boto3.client("ec2", region_name="us-east-1")
ec2 = boto3.resource("ec2", region_name="us-east-1")
vpc = ec2.create_vpc(CidrBlock="10.0.0.0/16")
network_acl = ec2.create_network_acl(VpcId=vpc.id)
client.create_network_acl_entry(
NetworkAclId=network_acl.id,
RuleNumber=110,
Protocol="6", # TCP
RuleAction="ALLOW",
CidrBlock="0.0.0.0/0",
Egress=False,
PortRange={"From": 443, "To": 443},
)
client.replace_network_acl_entry(
NetworkAclId=network_acl.id,
RuleNumber=110,
Protocol="-1",
RuleAction="DENY",
CidrBlock="0.0.0.0/0",
Egress=False,
PortRange={"From": 22, "To": 22},
)
all_network_acls = client.describe_network_acls()["NetworkAcls"]
test_network_acl = next(
na for na in all_network_acls if na["NetworkAclId"] == network_acl.id
)
entries = test_network_acl["Entries"]
entries.should.have.length_of(1)
entries[0]["RuleNumber"].should.equal(110)
entries[0]["Protocol"].should.equal("-1")
entries[0]["RuleAction"].should.equal("DENY")
entries[0]["PortRange"].should.equal({"To": 22, "From": 22})
# TODO: How to convert 'associate_network_acl' to boto3?
@mock_ec2_deprecated
def test_associate_new_network_acl_with_subnet():
conn = boto.connect_vpc("the_key", "the secret")
@ -151,6 +306,7 @@ def test_associate_new_network_acl_with_subnet():
test_network_acl.associations[0].subnet_id.should.equal(subnet.id)
# Has boto3 equivalent
@mock_ec2_deprecated
def test_delete_network_acl():
conn = boto.connect_vpc("the_key", "the secret")
@ -171,6 +327,29 @@ def test_delete_network_acl():
any(acl.id == network_acl.id for acl in updated_network_acls).shouldnt.be.ok
@mock_ec2
def test_delete_network_acl_boto3():
client = boto3.client("ec2", region_name="us-east-1")
ec2 = boto3.resource("ec2", region_name="us-east-1")
vpc = ec2.create_vpc(CidrBlock="10.0.0.0/16")
network_acl = ec2.create_network_acl(VpcId=vpc.id)
all_network_acls = client.describe_network_acls()["NetworkAcls"]
all_network_acls.should.have.length_of(3)
any(acl["NetworkAclId"] == network_acl.id for acl in all_network_acls).should.be.ok
client.delete_network_acl(NetworkAclId=network_acl.id)
updated_network_acls = client.describe_network_acls()["NetworkAcls"]
updated_network_acls.should.have.length_of(2)
any(
acl["NetworkAclId"] == network_acl.id for acl in updated_network_acls
).shouldnt.be.ok
# Has boto3 equivalent
@mock_ec2_deprecated
def test_network_acl_tagging():
conn = boto.connect_vpc("the_key", "the secret")
@ -189,6 +368,27 @@ def test_network_acl_tagging():
test_network_acl.tags["a key"].should.equal("some value")
@mock_ec2
def test_network_acl_tagging_boto3():
client = boto3.client("ec2", region_name="us-east-1")
ec2 = boto3.resource("ec2", region_name="us-east-1")
vpc = ec2.create_vpc(CidrBlock="10.0.0.0/16")
network_acl = ec2.create_network_acl(VpcId=vpc.id)
network_acl.create_tags(Tags=[{"Key": "a key", "Value": "some value"}])
tag = client.describe_tags()["Tags"][0]
tag.should.have.key("ResourceId").equal(network_acl.id)
tag.should.have.key("Key").equal("a key")
tag.should.have.key("Value").equal("some value")
all_network_acls = client.describe_network_acls()["NetworkAcls"]
test_network_acl = next(
na for na in all_network_acls if na["NetworkAclId"] == network_acl.id
)
test_network_acl["Tags"].should.equal([{"Value": "some value", "Key": "a key"}])
@mock_ec2
def test_new_subnet_in_new_vpc_associates_with_default_network_acl():
ec2 = boto3.resource("ec2", region_name="us-west-1")

View File

@ -2,10 +2,12 @@ from __future__ import unicode_literals
import boto.ec2
import boto.ec2.autoscale
import boto.ec2.elb
import boto3
import sure
from boto3 import Session
from moto import mock_ec2_deprecated, mock_autoscaling_deprecated, mock_elb_deprecated
from moto import mock_autoscaling, mock_ec2, mock_elb
from moto.ec2 import ec2_backends
from tests import EXAMPLE_AMI_ID, EXAMPLE_AMI_ID2
@ -30,6 +32,12 @@ def add_servers_to_region(ami_id, count, region):
conn.run_instances(ami_id)
def add_servers_to_region_boto3(ami_id, count, region):
ec2 = boto3.resource("ec2", region_name=region)
ec2.create_instances(ImageId=ami_id, MinCount=count, MaxCount=count)
# Has boto3 equivalent
@mock_ec2_deprecated
def test_add_servers_to_a_single_region():
region = "ap-northeast-1"
@ -44,6 +52,21 @@ def test_add_servers_to_a_single_region():
image_ids.should.equal([EXAMPLE_AMI_ID, EXAMPLE_AMI_ID2])
@mock_ec2
def test_add_servers_to_a_single_region_boto3():
region = "ap-northeast-1"
add_servers_to_region_boto3(EXAMPLE_AMI_ID, 1, region)
add_servers_to_region_boto3(EXAMPLE_AMI_ID2, 1, region)
client = boto3.client("ec2", region_name=region)
reservations = client.describe_instances()["Reservations"]
reservations.should.have.length_of(2)
image_ids = [r["Instances"][0]["ImageId"] for r in reservations]
image_ids.should.equal([EXAMPLE_AMI_ID, EXAMPLE_AMI_ID2])
# Has boto3 equivalent
@mock_ec2_deprecated
def test_add_servers_to_multiple_regions():
region1 = "us-east-1"
@ -63,6 +86,26 @@ def test_add_servers_to_multiple_regions():
ap_reservations[0].instances[0].image_id.should.equal(EXAMPLE_AMI_ID2)
@mock_ec2
def test_add_servers_to_multiple_regions_boto3():
region1 = "us-east-1"
region2 = "ap-northeast-1"
add_servers_to_region_boto3(EXAMPLE_AMI_ID, 1, region1)
add_servers_to_region_boto3(EXAMPLE_AMI_ID2, 1, region2)
us_client = boto3.client("ec2", region_name=region1)
ap_client = boto3.client("ec2", region_name=region2)
us_reservations = us_client.describe_instances()["Reservations"]
ap_reservations = ap_client.describe_instances()["Reservations"]
us_reservations.should.have.length_of(1)
ap_reservations.should.have.length_of(1)
us_reservations[0]["Instances"][0]["ImageId"].should.equal(EXAMPLE_AMI_ID)
ap_reservations[0]["Instances"][0]["ImageId"].should.equal(EXAMPLE_AMI_ID2)
# Has boto3 equivalent
@mock_autoscaling_deprecated
@mock_elb_deprecated
def test_create_autoscaling_group():
@ -161,3 +204,69 @@ def test_create_autoscaling_group():
list(ap_group.termination_policies).should.equal(
["OldestInstance", "NewestInstance"]
)
@mock_autoscaling
@mock_elb
@mock_ec2
def test_create_autoscaling_group_boto3():
regions = [("us-east-1", "c"), ("ap-northeast-1", "a")]
for region, zone in regions:
a_zone = "{}{}".format(region, zone)
asg_name = "{}_tester_group".format(region)
lb_name = "{}_lb".format(region)
config_name = "{}_tester".format(region)
elb_client = boto3.client("elb", region_name=region)
elb_client.create_load_balancer(
LoadBalancerName=lb_name,
Listeners=[
{"Protocol": "http", "LoadBalancerPort": 80, "InstancePort": 8080}
],
AvailabilityZones=[],
)
as_client = boto3.client("autoscaling", region_name=region)
as_client.create_launch_configuration(
LaunchConfigurationName=config_name,
ImageId=EXAMPLE_AMI_ID,
InstanceType="m1.small",
)
ec2_client = boto3.client("ec2", region_name=region)
subnet_id = ec2_client.describe_subnets(
Filters=[{"Name": "availability-zone", "Values": [a_zone]}]
)["Subnets"][0]["SubnetId"]
as_client.create_auto_scaling_group(
AutoScalingGroupName=asg_name,
AvailabilityZones=[a_zone],
DefaultCooldown=60,
DesiredCapacity=2,
HealthCheckGracePeriod=100,
HealthCheckType="EC2",
LaunchConfigurationName=config_name,
LoadBalancerNames=[lb_name],
MinSize=2,
MaxSize=2,
PlacementGroup="us_test_placement",
VPCZoneIdentifier=subnet_id,
TerminationPolicies=["OldestInstance", "NewestInstance"],
)
groups = as_client.describe_auto_scaling_groups()["AutoScalingGroups"]
groups.should.have.length_of(1)
group = groups[0]
group["AutoScalingGroupName"].should.equal(asg_name)
group["DesiredCapacity"].should.equal(2)
group["MaxSize"].should.equal(2)
group["MinSize"].should.equal(2)
group["VPCZoneIdentifier"].should.equal(subnet_id)
group["LaunchConfigurationName"].should.equal(config_name)
group["DefaultCooldown"].should.equal(60)
group["HealthCheckGracePeriod"].should.equal(100)
group["HealthCheckType"].should.equal("EC2")
group["LoadBalancerNames"].should.equal([lb_name])
group["PlacementGroup"].should.equal("us_test_placement")
group["TerminationPolicies"].should.equal(["OldestInstance", "NewestInstance"])

View File

@ -8,11 +8,12 @@ from boto.exception import EC2ResponseError
from botocore.exceptions import ClientError
import sure # noqa
from moto import mock_ec2, mock_ec2_deprecated
from moto import mock_ec2, mock_ec2_deprecated, settings
from tests import EXAMPLE_AMI_ID
from tests.helpers import requires_boto_gte
# Has boto3 equivalent
@mock_ec2_deprecated
def test_route_tables_defaults():
conn = boto.connect_vpc("the_key", "the_secret")
@ -38,6 +39,37 @@ def test_route_tables_defaults():
all_route_tables.should.have.length_of(0)
@mock_ec2
def test_route_tables_defaults_boto3():
client = boto3.client("ec2", region_name="us-east-1")
ec2 = boto3.resource("ec2", region_name="us-east-1")
vpc = ec2.create_vpc(CidrBlock="10.0.0.0/16")
all_route_tables = client.describe_route_tables(
Filters=[{"Name": "vpc-id", "Values": [vpc.id]}]
)["RouteTables"]
all_route_tables.should.have.length_of(1)
main_route_table = all_route_tables[0]
main_route_table["VpcId"].should.equal(vpc.id)
routes = main_route_table["Routes"]
routes.should.have.length_of(1)
local_route = routes[0]
local_route["GatewayId"].should.equal("local")
local_route["State"].should.equal("active")
local_route["DestinationCidrBlock"].should.equal(vpc.cidr_block)
vpc.delete()
all_route_tables = client.describe_route_tables(
Filters=[{"Name": "vpc-id", "Values": [vpc.id]}]
)["RouteTables"]
all_route_tables.should.have.length_of(0)
# Has boto3 equivalent
@mock_ec2_deprecated
def test_route_tables_additional():
conn = boto.connect_vpc("the_key", "the_secret")
@ -78,6 +110,52 @@ def test_route_tables_additional():
cm.value.request_id.should_not.be.none
@mock_ec2
def test_route_tables_additional_boto3():
client = boto3.client("ec2", region_name="us-east-1")
ec2 = boto3.resource("ec2", region_name="us-east-1")
vpc = ec2.create_vpc(CidrBlock="10.0.0.0/16")
route_table = vpc.create_route_table()
all_route_tables = client.describe_route_tables(
Filters=[{"Name": "vpc-id", "Values": [vpc.id]}]
)["RouteTables"]
all_route_tables.should.have.length_of(2)
all_route_tables[0]["VpcId"].should.equal(vpc.id)
all_route_tables[1]["VpcId"].should.equal(vpc.id)
all_route_table_ids = [r["RouteTableId"] for r in all_route_tables]
all_route_table_ids.should.contain(route_table.route_table_id)
routes = route_table.routes
routes.should.have.length_of(1)
local_route = routes[0]
local_route.gateway_id.should.equal("local")
local_route.state.should.equal("active")
local_route.destination_cidr_block.should.equal(vpc.cidr_block)
with pytest.raises(ClientError) as ex:
client.delete_vpc(VpcId=vpc.id)
ex.value.response["Error"]["Code"].should.equal("DependencyViolation")
ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
ex.value.response["ResponseMetadata"].should.have.key("RequestId")
client.delete_route_table(RouteTableId=route_table.route_table_id)
all_route_tables = client.describe_route_tables(
Filters=[{"Name": "vpc-id", "Values": [vpc.id]}]
)["RouteTables"]
all_route_tables.should.have.length_of(1)
with pytest.raises(ClientError) as ex:
client.delete_route_table(RouteTableId="rtb-1234abcd")
ex.value.response["Error"]["Code"].should.equal("InvalidRouteTableID.NotFound")
ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
ex.value.response["ResponseMetadata"].should.have.key("RequestId")
# Has boto3 equivalent
@mock_ec2_deprecated
def test_route_tables_filters_standard():
conn = boto.connect_vpc("the_key", "the_secret")
@ -122,6 +200,66 @@ def test_route_tables_filters_standard():
).should.throw(NotImplementedError)
@mock_ec2
def test_route_tables_filters_standard_boto3():
client = boto3.client("ec2", region_name="us-east-1")
ec2 = boto3.resource("ec2", region_name="us-east-1")
vpc1 = ec2.create_vpc(CidrBlock="10.0.0.0/16")
route_table1 = ec2.create_route_table(VpcId=vpc1.id)
vpc2 = ec2.create_vpc(CidrBlock="10.0.0.0/16")
route_table2 = ec2.create_route_table(VpcId=vpc2.id)
all_route_tables = client.describe_route_tables()["RouteTables"]
all_route_tables.should.have.length_of(5)
# Filter by main route table
main_route_tables = client.describe_route_tables(
Filters=[{"Name": "association.main", "Values": ["true"]}]
)["RouteTables"]
main_route_tables.should.have.length_of(3)
main_route_table_ids = [
route_table["RouteTableId"] for route_table in main_route_tables
]
main_route_table_ids.should_not.contain(route_table1.id)
main_route_table_ids.should_not.contain(route_table2.id)
# Filter by VPC
vpc1_route_tables = client.describe_route_tables(
Filters=[{"Name": "vpc-id", "Values": [vpc1.id]}]
)["RouteTables"]
vpc1_route_tables.should.have.length_of(2)
vpc1_route_table_ids = [
route_table["RouteTableId"] for route_table in vpc1_route_tables
]
vpc1_route_table_ids.should.contain(route_table1.id)
vpc1_route_table_ids.should_not.contain(route_table2.id)
# Filter by VPC and main route table
vpc2_main_route_tables = client.describe_route_tables(
Filters=[
{"Name": "association.main", "Values": ["true"]},
{"Name": "vpc-id", "Values": [vpc2.id]},
]
)["RouteTables"]
vpc2_main_route_tables.should.have.length_of(1)
vpc2_main_route_table_ids = [
route_table["RouteTableId"] for route_table in vpc2_main_route_tables
]
vpc2_main_route_table_ids.should_not.contain(route_table1.id)
vpc2_main_route_table_ids.should_not.contain(route_table2.id)
# Unsupported filter
if not settings.TEST_SERVER_MODE:
# ServerMode will just throw a generic 500
filters = [{"Name": "not-implemented-filter", "Values": ["foobar"]}]
client.describe_route_tables.when.called_with(Filters=filters).should.throw(
NotImplementedError
)
# Has boto3 equivalent
@mock_ec2_deprecated
def test_route_tables_filters_associations():
conn = boto.connect_vpc("the_key", "the_secret")
@ -165,6 +303,58 @@ def test_route_tables_filters_associations():
association1_route_tables[0].associations.should.have.length_of(2)
@mock_ec2
def test_route_tables_filters_associations_boto3():
client = boto3.client("ec2", region_name="us-east-1")
ec2 = boto3.resource("ec2", region_name="us-east-1")
vpc = ec2.create_vpc(CidrBlock="10.0.0.0/16")
subnet1 = vpc.create_subnet(VpcId=vpc.id, CidrBlock="10.0.0.0/24")
subnet2 = vpc.create_subnet(VpcId=vpc.id, CidrBlock="10.0.1.0/24")
subnet3 = vpc.create_subnet(VpcId=vpc.id, CidrBlock="10.0.2.0/24")
route_table1 = ec2.create_route_table(VpcId=vpc.id)
route_table2 = ec2.create_route_table(VpcId=vpc.id)
association_id1 = client.associate_route_table(
RouteTableId=route_table1.id, SubnetId=subnet1.id
)["AssociationId"]
client.associate_route_table(RouteTableId=route_table1.id, SubnetId=subnet2.id)
client.associate_route_table(RouteTableId=route_table2.id, SubnetId=subnet3.id)
all_route_tables = client.describe_route_tables()["RouteTables"]
all_route_tables.should.have.length_of(4)
# Filter by association ID
association1_route_tables = client.describe_route_tables(
Filters=[
{
"Name": "association.route-table-association-id",
"Values": [association_id1],
}
]
)["RouteTables"]
association1_route_tables.should.have.length_of(1)
association1_route_tables[0]["RouteTableId"].should.equal(route_table1.id)
association1_route_tables[0]["Associations"].should.have.length_of(2)
# Filter by route table ID
route_table2_route_tables = client.describe_route_tables(
Filters=[{"Name": "association.route-table-id", "Values": [route_table2.id]}]
)["RouteTables"]
route_table2_route_tables.should.have.length_of(1)
route_table2_route_tables[0]["RouteTableId"].should.equal(route_table2.id)
route_table2_route_tables[0]["Associations"].should.have.length_of(1)
# Filter by subnet ID
subnet_route_tables = client.describe_route_tables(
Filters=[{"Name": "association.subnet-id", "Values": [subnet1.id]}]
)["RouteTables"]
subnet_route_tables.should.have.length_of(1)
subnet_route_tables[0]["RouteTableId"].should.equal(route_table1.id)
subnet_route_tables[0]["Associations"].should.have.length_of(2)
# Has boto3 equivalent
@mock_ec2_deprecated
def test_route_table_associations():
conn = boto.connect_vpc("the_key", "the_secret")
@ -231,6 +421,81 @@ def test_route_table_associations():
cm.value.request_id.should_not.be.none
@mock_ec2
def test_route_table_associations_boto3():
client = boto3.client("ec2", region_name="us-east-1")
ec2 = boto3.resource("ec2", region_name="us-east-1")
vpc = ec2.create_vpc(CidrBlock="10.0.0.0/16")
subnet = ec2.create_subnet(VpcId=vpc.id, CidrBlock="10.0.0.0/18")
route_table = ec2.create_route_table(VpcId=vpc.id)
all_route_tables = client.describe_route_tables()["RouteTables"]
all_route_tables.should.have.length_of(3)
# Refresh
r = client.describe_route_tables(RouteTableIds=[route_table.id])["RouteTables"][0]
r["Associations"].should.have.length_of(0)
# Associate
association_id = client.associate_route_table(
RouteTableId=route_table.id, SubnetId=subnet.id
)["AssociationId"]
# Refresh
r = client.describe_route_tables(RouteTableIds=[route_table.id])["RouteTables"][0]
r["Associations"].should.have.length_of(1)
r["Associations"][0]["RouteTableAssociationId"].should.equal(association_id)
r["Associations"][0]["Main"].should.equal(True)
r["Associations"][0]["RouteTableId"].should.equal(route_table.id)
r["Associations"][0]["SubnetId"].should.equal(subnet.id)
# Associate is idempotent
association_id_idempotent = client.associate_route_table(
RouteTableId=route_table.id, SubnetId=subnet.id
)["AssociationId"]
association_id_idempotent.should.equal(association_id)
# Error: Attempt delete associated route table.
with pytest.raises(ClientError) as ex:
client.delete_route_table(RouteTableId=route_table.id)
ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
ex.value.response["ResponseMetadata"].should.have.key("RequestId")
ex.value.response["Error"]["Code"].should.equal("DependencyViolation")
# Disassociate
client.disassociate_route_table(AssociationId=association_id)
# Refresh
r = client.describe_route_tables(RouteTableIds=[route_table.id])["RouteTables"][0]
r["Associations"].should.have.length_of(0)
# Error: Disassociate with invalid association ID
with pytest.raises(ClientError) as ex:
client.disassociate_route_table(AssociationId=association_id)
ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
ex.value.response["ResponseMetadata"].should.have.key("RequestId")
ex.value.response["Error"]["Code"].should.equal("InvalidAssociationID.NotFound")
# Error: Associate with invalid subnet ID
with pytest.raises(ClientError) as ex:
client.associate_route_table(
RouteTableId=route_table.id, SubnetId="subnet-1234abcd"
)
ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
ex.value.response["ResponseMetadata"].should.have.key("RequestId")
ex.value.response["Error"]["Code"].should.equal("InvalidSubnetID.NotFound")
# Error: Associate with invalid route table ID
with pytest.raises(ClientError) as ex:
client.associate_route_table(RouteTableId="rtb-1234abcd", SubnetId=subnet.id)
ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
ex.value.response["ResponseMetadata"].should.have.key("RequestId")
ex.value.response["Error"]["Code"].should.equal("InvalidRouteTableID.NotFound")
# Has boto3 equivalent
@requires_boto_gte("2.16.0")
@mock_ec2_deprecated
def test_route_table_replace_route_table_association():
@ -308,6 +573,99 @@ def test_route_table_replace_route_table_association():
cm.value.request_id.should_not.be.none
@mock_ec2
def test_route_table_replace_route_table_association_boto3():
client = boto3.client("ec2", region_name="us-east-1")
ec2 = boto3.resource("ec2", region_name="us-east-1")
vpc = ec2.create_vpc(CidrBlock="10.0.0.0/16")
subnet = ec2.create_subnet(VpcId=vpc.id, CidrBlock="10.0.0.0/18")
route_table1_id = ec2.create_route_table(VpcId=vpc.id).id
route_table2_id = ec2.create_route_table(VpcId=vpc.id).id
all_route_tables = client.describe_route_tables()["RouteTables"]
all_route_tables.should.have.length_of(4)
# Refresh
route_table1 = client.describe_route_tables(RouteTableIds=[route_table1_id])[
"RouteTables"
][0]
route_table1["Associations"].should.have.length_of(0)
# Associate
association_id1 = client.associate_route_table(
RouteTableId=route_table1_id, SubnetId=subnet.id
)["AssociationId"]
# Refresh
route_table1 = client.describe_route_tables(RouteTableIds=[route_table1_id])[
"RouteTables"
][0]
route_table2 = client.describe_route_tables(RouteTableIds=[route_table2_id])[
"RouteTables"
][0]
# Validate
route_table1["Associations"].should.have.length_of(1)
route_table2["Associations"].should.have.length_of(0)
route_table1["Associations"][0]["RouteTableAssociationId"].should.equal(
association_id1
)
route_table1["Associations"][0]["Main"].should.equal(True)
route_table1["Associations"][0]["RouteTableId"].should.equal(route_table1_id)
route_table1["Associations"][0]["SubnetId"].should.equal(subnet.id)
# Replace Association
association_id2 = client.replace_route_table_association(
AssociationId=association_id1, RouteTableId=route_table2_id
)["NewAssociationId"]
# Refresh
route_table1 = client.describe_route_tables(RouteTableIds=[route_table1_id])[
"RouteTables"
][0]
route_table2 = client.describe_route_tables(RouteTableIds=[route_table2_id])[
"RouteTables"
][0]
# Validate
route_table1["Associations"].should.have.length_of(0)
route_table2["Associations"].should.have.length_of(1)
route_table2["Associations"][0]["RouteTableAssociationId"].should.equal(
association_id2
)
route_table2["Associations"][0]["Main"].should.equal(True)
route_table2["Associations"][0]["RouteTableId"].should.equal(route_table2_id)
route_table2["Associations"][0]["SubnetId"].should.equal(subnet.id)
# Replace Association is idempotent
association_id_idempotent = client.replace_route_table_association(
AssociationId=association_id2, RouteTableId=route_table2_id
)["NewAssociationId"]
association_id_idempotent.should.equal(association_id2)
# Error: Replace association with invalid association ID
with pytest.raises(ClientError) as ex:
client.replace_route_table_association(
AssociationId="rtbassoc-1234abcd", RouteTableId=route_table1_id
)
ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
ex.value.response["ResponseMetadata"].should.have.key("RequestId")
ex.value.response["Error"]["Code"].should.equal("InvalidAssociationID.NotFound")
# Error: Replace association with invalid route table ID
with pytest.raises(ClientError) as ex:
client.replace_route_table_association(
AssociationId=association_id2, RouteTableId="rtb-1234abcd"
)
ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
ex.value.response["ResponseMetadata"].should.have.key("RequestId")
ex.value.response["Error"]["Code"].should.equal("InvalidRouteTableID.NotFound")
# Has boto3 equivalent
@mock_ec2_deprecated
def test_route_table_get_by_tag():
conn = boto.connect_vpc("the_key", "the_secret")
@ -345,6 +703,7 @@ def test_route_table_get_by_tag_boto3():
route_tables[0].tags[0].should.equal({"Key": "Name", "Value": "TestRouteTable"})
# Has boto3 equivalent
@mock_ec2_deprecated
def test_routes_additional():
conn = boto.connect_vpc("the_key", "the_secret")
@ -395,6 +754,60 @@ def test_routes_additional():
cm.value.request_id.should_not.be.none
@mock_ec2
def test_routes_additional_boto3():
client = boto3.client("ec2", region_name="us-east-1")
ec2 = boto3.resource("ec2", region_name="us-east-1")
vpc = ec2.create_vpc(CidrBlock="10.0.0.0/16")
main_route_table_id = client.describe_route_tables(
Filters=[{"Name": "vpc-id", "Values": [vpc.id]}]
)["RouteTables"][0]["RouteTableId"]
main_route_table = ec2.RouteTable(main_route_table_id)
main_route_table.routes.should.have.length_of(1)
igw = ec2.create_internet_gateway()
ROUTE_CIDR = "10.0.0.4/24"
main_route_table.create_route(DestinationCidrBlock=ROUTE_CIDR, GatewayId=igw.id)
main_route_table.routes.should.have.length_of(2)
new_routes = [
route
for route in main_route_table.routes
if route.destination_cidr_block != vpc.cidr_block
]
new_routes.should.have.length_of(1)
new_route = new_routes[0]
new_route.gateway_id.should.equal(igw.id)
new_route.instance_id.should.be.none
new_route.state.should.equal("active")
new_route.destination_cidr_block.should.equal(ROUTE_CIDR)
client.delete_route(
RouteTableId=main_route_table.id, DestinationCidrBlock=ROUTE_CIDR
)
main_route_table.reload()
main_route_table.routes.should.have.length_of(1)
new_routes = [
route
for route in main_route_table.routes
if route.destination_cidr_block != vpc.cidr_block
]
new_routes.should.have.length_of(0)
with pytest.raises(ClientError) as ex:
client.delete_route(
RouteTableId=main_route_table.id, DestinationCidrBlock=ROUTE_CIDR
)
ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
ex.value.response["ResponseMetadata"].should.have.key("RequestId")
ex.value.response["Error"]["Code"].should.equal("InvalidRoute.NotFound")
# Has boto3 equivalent
@mock_ec2_deprecated
def test_routes_replace():
conn = boto.connect_vpc("the_key", "the_secret")
@ -448,6 +861,78 @@ def test_routes_replace():
cm.value.request_id.should_not.be.none
@mock_ec2
def test_routes_replace_boto3():
client = boto3.client("ec2", region_name="us-east-1")
ec2 = boto3.resource("ec2", region_name="us-east-1")
vpc = ec2.create_vpc(CidrBlock="10.0.0.0/16")
main_route_table_id = client.describe_route_tables(
Filters=[
{"Name": "vpc-id", "Values": [vpc.id]},
{"Name": "association.main", "Values": ["true"]},
]
)["RouteTables"][0]["RouteTableId"]
main_route_table = ec2.RouteTable(main_route_table_id)
ROUTE_CIDR = "10.0.0.4/24"
# Various route targets
igw = ec2.create_internet_gateway()
instance = ec2.create_instances(ImageId=EXAMPLE_AMI_ID, MinCount=1, MaxCount=1)[0]
# Create initial route
main_route_table.create_route(DestinationCidrBlock=ROUTE_CIDR, GatewayId=igw.id)
# Replace...
def get_target_route():
route_table = client.describe_route_tables(RouteTableIds=[main_route_table.id])[
"RouteTables"
][0]
routes = [
route
for route in route_table["Routes"]
if route["DestinationCidrBlock"] != vpc.cidr_block
]
routes.should.have.length_of(1)
return routes[0]
client.replace_route(
RouteTableId=main_route_table.id,
DestinationCidrBlock=ROUTE_CIDR,
InstanceId=instance.id,
)
target_route = get_target_route()
target_route.shouldnt.have.key("GatewayId")
target_route["InstanceId"].should.equal(instance.id)
target_route["State"].should.equal("active")
target_route["DestinationCidrBlock"].should.equal(ROUTE_CIDR)
client.replace_route(
RouteTableId=main_route_table.id,
DestinationCidrBlock=ROUTE_CIDR,
GatewayId=igw.id,
)
target_route = get_target_route()
target_route["GatewayId"].should.equal(igw.id)
target_route.shouldnt.have.key("InstanceId")
target_route["State"].should.equal("active")
target_route["DestinationCidrBlock"].should.equal(ROUTE_CIDR)
with pytest.raises(ClientError) as ex:
client.replace_route(
RouteTableId="rtb-1234abcd",
DestinationCidrBlock=ROUTE_CIDR,
GatewayId=igw.id,
)
ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
ex.value.response["ResponseMetadata"].should.have.key("RequestId")
ex.value.response["Error"]["Code"].should.equal("InvalidRouteTableID.NotFound")
# Has boto3 equivalent
@requires_boto_gte("2.19.0")
@mock_ec2_deprecated
def test_routes_not_supported():
@ -471,6 +956,48 @@ def test_routes_not_supported():
).should.throw(NotImplementedError)
@mock_ec2
def test_routes_not_supported_boto3():
client = boto3.client("ec2", region_name="us-east-1")
ec2 = boto3.resource("ec2", region_name="us-east-1")
main_route_table_id = client.describe_route_tables()["RouteTables"][0][
"RouteTableId"
]
main_route_table = ec2.RouteTable(main_route_table_id)
ROUTE_CIDR = "10.0.0.4/24"
# Create
with pytest.raises(ClientError) as ex:
client.create_route(
RouteTableId=main_route_table_id,
DestinationCidrBlock=ROUTE_CIDR,
NetworkInterfaceId="eni-1234abcd",
)
ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
ex.value.response["ResponseMetadata"].should.have.key("RequestId")
ex.value.response["Error"]["Code"].should.equal(
"InvalidNetworkInterfaceID.NotFound"
)
igw = ec2.create_internet_gateway()
client.create_route(
RouteTableId=main_route_table_id,
DestinationCidrBlock=ROUTE_CIDR,
GatewayId=igw.id,
)
# Replace
if not settings.TEST_SERVER_MODE:
args = {
"RouteTableId": main_route_table.id,
"DestinationCidrBlock": ROUTE_CIDR,
"NetworkInterfaceId": "eni-1234abcd",
}
client.replace_route.when.called_with(**args).should.throw(NotImplementedError)
# Has boto3 equivalent
@requires_boto_gte("2.34.0")
@mock_ec2_deprecated
def test_routes_vpc_peering_connection():
@ -506,6 +1033,45 @@ def test_routes_vpc_peering_connection():
new_route.destination_cidr_block.should.equal(ROUTE_CIDR)
@mock_ec2
def test_routes_vpc_peering_connection_boto3():
client = boto3.client("ec2", region_name="us-east-1")
ec2 = boto3.resource("ec2", region_name="us-east-1")
vpc = ec2.create_vpc(CidrBlock="10.0.0.0/16")
main_route_table_id = client.describe_route_tables(
Filters=[
{"Name": "vpc-id", "Values": [vpc.id]},
{"Name": "association.main", "Values": ["true"]},
]
)["RouteTables"][0]["RouteTableId"]
main_route_table = ec2.RouteTable(main_route_table_id)
ROUTE_CIDR = "10.0.0.4/24"
peer_vpc = ec2.create_vpc(CidrBlock="11.0.0.0/16")
vpc_pcx = ec2.create_vpc_peering_connection(VpcId=vpc.id, PeerVpcId=peer_vpc.id)
main_route_table.create_route(
DestinationCidrBlock=ROUTE_CIDR, VpcPeeringConnectionId=vpc_pcx.id
)
# Refresh route table
main_route_table.reload()
new_routes = [
route
for route in main_route_table.routes
if route.destination_cidr_block != vpc.cidr_block
]
new_routes.should.have.length_of(1)
new_route = new_routes[0]
new_route.gateway_id.should.be.none
new_route.instance_id.should.be.none
new_route.vpc_peering_connection_id.should.equal(vpc_pcx.id)
new_route.state.should.equal("active")
new_route.destination_cidr_block.should.equal(ROUTE_CIDR)
# Has boto3 equivalent
@requires_boto_gte("2.34.0")
@mock_ec2_deprecated
def test_routes_vpn_gateway():
@ -535,6 +1101,40 @@ def test_routes_vpn_gateway():
new_route.vpc_peering_connection_id.should.be.none
@mock_ec2
def test_routes_vpn_gateway_boto3():
client = boto3.client("ec2", region_name="us-east-1")
ec2 = boto3.resource("ec2", region_name="us-east-1")
vpc = ec2.create_vpc(CidrBlock="10.0.0.0/16")
main_route_table_id = client.describe_route_tables(
Filters=[
{"Name": "vpc-id", "Values": [vpc.id]},
{"Name": "association.main", "Values": ["true"]},
]
)["RouteTables"][0]["RouteTableId"]
main_route_table = ec2.RouteTable(main_route_table_id)
ROUTE_CIDR = "10.0.0.4/24"
vpn_gw_id = client.create_vpn_gateway(Type="ipsec.1")["VpnGateway"]["VpnGatewayId"]
main_route_table.create_route(DestinationCidrBlock=ROUTE_CIDR, GatewayId=vpn_gw_id)
main_route_table.reload()
new_routes = [
route
for route in main_route_table.routes
if route.destination_cidr_block != vpc.cidr_block
]
new_routes.should.have.length_of(1)
new_route = new_routes[0]
new_route.gateway_id.should.equal(vpn_gw_id)
new_route.instance_id.should.be.none
new_route.vpc_peering_connection_id.should.be.none
# Has boto3 equivalent
@mock_ec2_deprecated
def test_network_acl_tagging():
@ -554,6 +1154,27 @@ def test_network_acl_tagging():
test_route_table.tags["a key"].should.equal("some value")
@mock_ec2
def test_network_acl_tagging_boto3():
client = boto3.client("ec2", region_name="us-east-1")
ec2 = boto3.resource("ec2", region_name="us-east-1")
vpc = ec2.create_vpc(CidrBlock="10.0.0.0/16")
route_table = ec2.create_route_table(VpcId=vpc.id)
route_table.create_tags(Tags=[{"Key": "a key", "Value": "some value"}])
tag = client.describe_tags()["Tags"][0]
tag.should.have.key("ResourceType").equal("route-table")
tag.should.have.key("Key").equal("a key")
tag.should.have.key("Value").equal("some value")
all_route_tables = client.describe_route_tables()["RouteTables"]
test_route_table = next(
na for na in all_route_tables if na["RouteTableId"] == route_table.id
)
test_route_table["Tags"].should.equal([{"Value": "some value", "Key": "a key"}])
@mock_ec2
def test_create_route_with_invalid_destination_cidr_block_parameter():
ec2 = boto3.resource("ec2", region_name="us-west-1")

View File

@ -16,6 +16,7 @@ from moto import mock_ec2, mock_ec2_deprecated, settings
from moto.ec2 import ec2_backend
# Has boto3 equivalent
@mock_ec2_deprecated
def test_create_and_describe_security_group():
conn = boto.connect_ec2("the_key", "the_secret")
@ -53,6 +54,41 @@ def test_create_and_describe_security_group():
set(group_names).should.equal(set(["default", "test security group"]))
@mock_ec2
def test_create_and_describe_security_group_boto3():
ec2 = boto3.resource("ec2", "us-west-1")
client = boto3.client("ec2", "us-west-1")
with pytest.raises(ClientError) as ex:
client.create_security_group(GroupName="test", Description="test", DryRun=True)
ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(412)
ex.value.response["Error"]["Code"].should.equal("DryRunOperation")
ex.value.response["Error"]["Message"].should.equal(
"An error occurred (DryRunOperation) when calling the CreateSecurityGroup operation: Request would have succeeded, but DryRun flag is set"
)
security_group = ec2.create_security_group(
GroupName="test security group", Description="test"
)
security_group.group_name.should.equal("test security group")
security_group.description.should.equal("test")
# Trying to create another group with the same name should throw an error
with pytest.raises(ClientError) as ex:
client.create_security_group(GroupName="test security group", Description="n/a")
ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
ex.value.response["ResponseMetadata"].should.have.key("RequestId")
ex.value.response["Error"]["Code"].should.equal("InvalidGroup.Duplicate")
all_groups = client.describe_security_groups()["SecurityGroups"]
# The default group gets created automatically
all_groups.should.have.length_of(2)
group_names = [group["GroupName"] for group in all_groups]
set(group_names).should.equal(set(["default", "test security group"]))
# Has boto3 equivalent
@mock_ec2_deprecated
def test_create_security_group_without_description_raises_error():
conn = boto.connect_ec2("the_key", "the_secret")
@ -64,6 +100,18 @@ def test_create_security_group_without_description_raises_error():
cm.value.request_id.should_not.be.none
@mock_ec2
def test_create_security_group_without_description_raises_error_boto3():
ec2 = boto3.resource("ec2", "us-west-1")
with pytest.raises(ClientError) as ex:
ec2.create_security_group(GroupName="test security group", Description="")
ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
ex.value.response["ResponseMetadata"].should.have.key("RequestId")
ex.value.response["Error"]["Code"].should.equal("MissingParameter")
# Has boto3 equivalent
@mock_ec2_deprecated
def test_default_security_group():
conn = boto.ec2.connect_to_region("us-east-1")
@ -72,6 +120,15 @@ def test_default_security_group():
groups[0].name.should.equal("default")
@mock_ec2
def test_default_security_group_boto3():
client = boto3.client("ec2", "us-west-1")
groups = client.describe_security_groups()["SecurityGroups"]
groups.should.have.length_of(1)
groups[0]["GroupName"].should.equal("default")
# Has boto3 equivalent
@mock_ec2_deprecated
def test_create_and_describe_vpc_security_group():
conn = boto.connect_ec2("the_key", "the_secret")
@ -103,6 +160,46 @@ def test_create_and_describe_vpc_security_group():
all_groups[0].name.should.equal("test security group")
@mock_ec2
def test_create_and_describe_vpc_security_group_boto3():
ec2 = boto3.resource("ec2", "us-west-1")
client = boto3.client("ec2", "us-west-1")
name = "test secgr"
vpc_id = "vpc-5300000c"
security_group = ec2.create_security_group(
GroupName=name, Description="test", VpcId=vpc_id
)
security_group.vpc_id.should.equal(vpc_id)
security_group.group_name.should.equal(name)
security_group.description.should.equal("test")
# Trying to create another group with the same name in the same VPC should
# throw an error
with pytest.raises(ClientError) as ex:
ec2.create_security_group(GroupName=name, Description="n/a", VpcId=vpc_id)
ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
ex.value.response["ResponseMetadata"].should.have.key("RequestId")
ex.value.response["Error"]["Code"].should.equal("InvalidGroup.Duplicate")
# Trying to create another group in the same name without VPC should pass
ec2.create_security_group(GroupName=name, Description="non-vpc-group")
all_groups = client.describe_security_groups()["SecurityGroups"]
all_groups.should.have.length_of(3) # 1 default, 1 vpc, 1 no-vpc
all_groups = client.describe_security_groups(
Filters=[{"Name": "vpc_id", "Values": [vpc_id]}]
)["SecurityGroups"]
all_groups.should.have.length_of(1)
all_groups[0]["VpcId"].should.equal(vpc_id)
all_groups[0]["GroupName"].should.equal(name)
# Has boto3 equivalent
@mock_ec2_deprecated
def test_create_two_security_groups_with_same_name_in_different_vpc():
conn = boto.connect_ec2("the_key", "the_secret")
@ -124,6 +221,26 @@ def test_create_two_security_groups_with_same_name_in_different_vpc():
set(group_names).should.equal(set(["default", "test security group"]))
@mock_ec2
def test_create_two_security_groups_with_same_name_in_different_vpc_boto3():
ec2 = boto3.resource("ec2", "us-east-1")
client = boto3.client("ec2", "us-east-1")
name = "test security group"
vpc_id = "vpc-5300000c"
vpc_id2 = "vpc-5300000d"
ec2.create_security_group(GroupName=name, Description="n/a 1", VpcId=vpc_id)
ec2.create_security_group(GroupName=name, Description="n/a 2", VpcId=vpc_id2)
all_groups = client.describe_security_groups()["SecurityGroups"]
all_groups.should.have.length_of(3)
group_names = [group["GroupName"] for group in all_groups]
# The default group is created automatically
set(group_names).should.equal(set(["default", name]))
@mock_ec2
def test_create_two_security_groups_in_vpc_with_ipv6_enabled():
ec2 = boto3.resource("ec2", region_name="us-west-1")
@ -137,6 +254,7 @@ def test_create_two_security_groups_in_vpc_with_ipv6_enabled():
security_group.ip_permissions_egress.should.have.length_of(2)
# Has boto3 equivalent
@mock_ec2_deprecated
def test_deleting_security_groups():
conn = boto.connect_ec2("the_key", "the_secret")
@ -169,6 +287,40 @@ def test_deleting_security_groups():
conn.get_all_security_groups().should.have.length_of(1)
@mock_ec2
def test_deleting_security_groups_boto3():
ec2 = boto3.resource("ec2", "us-west-1")
client = boto3.client("ec2", "us-west-1")
security_group1 = ec2.create_security_group(GroupName="test1", Description="test1")
ec2.create_security_group(GroupName="test2", Description="test2")
client.describe_security_groups()["SecurityGroups"].should.have.length_of(3)
# Deleting a group that doesn't exist should throw an error
with pytest.raises(ClientError) as ex:
client.delete_security_group(GroupName="foobar")
ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
ex.value.response["ResponseMetadata"].should.have.key("RequestId")
ex.value.response["Error"]["Code"].should.equal("InvalidGroup.NotFound")
# Delete by name
with pytest.raises(ClientError) as ex:
client.delete_security_group(GroupName="test2", DryRun=True)
ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(412)
ex.value.response["Error"]["Code"].should.equal("DryRunOperation")
ex.value.response["Error"]["Message"].should.equal(
"An error occurred (DryRunOperation) when calling the DeleteSecurityGroup operation: Request would have succeeded, but DryRun flag is set"
)
client.delete_security_group(GroupName="test2")
client.describe_security_groups()["SecurityGroups"].should.have.length_of(2)
# Delete by group id
client.delete_security_group(GroupId=security_group1.id)
client.describe_security_groups()["SecurityGroups"].should.have.length_of(1)
# Has boto3 equivalent
@mock_ec2_deprecated
def test_delete_security_group_in_vpc():
conn = boto.connect_ec2("the_key", "the_secret")
@ -179,6 +331,26 @@ def test_delete_security_group_in_vpc():
conn.delete_security_group(group_id=security_group1.id)
@mock_ec2
def test_delete_security_group_in_vpc_boto3():
ec2 = boto3.resource("ec2", "us-west-1")
client = boto3.client("ec2", "us-west-1")
client.describe_security_groups()["SecurityGroups"].should.have.length_of(1)
group = ec2.create_security_group(
GroupName="test1", Description="test1", VpcId="vpc-12345"
)
client.describe_security_groups()["SecurityGroups"].should.have.length_of(2)
# this should not throw an exception
client.delete_security_group(GroupId=group.id)
client.describe_security_groups()["SecurityGroups"].should.have.length_of(1)
# Has boto3 equivalent
@mock_ec2_deprecated
def test_authorize_ip_range_and_revoke():
conn = boto.connect_ec2("the_key", "the_secret")
@ -316,6 +488,126 @@ def test_authorize_ip_range_and_revoke():
egress_security_group.rules_egress.should.have.length_of(1)
@mock_ec2
def test_authorize_ip_range_and_revoke_boto3():
ec2 = boto3.resource("ec2", "us-west-1")
client = boto3.client("ec2", "us-west-1")
security_group = ec2.create_security_group(GroupName="test", Description="test")
with pytest.raises(ClientError) as ex:
security_group.authorize_ingress(
IpProtocol="tcp",
FromPort=22,
ToPort=2222,
CidrIp="123.123.123.123/32",
DryRun=True,
)
ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(412)
ex.value.response["Error"]["Code"].should.equal("DryRunOperation")
ex.value.response["Error"]["Message"].should.equal(
"An error occurred (DryRunOperation) when calling the GrantSecurityGroupIngress operation: Request would have succeeded, but DryRun flag is set"
)
ingress_permissions = [
{
"IpProtocol": "tcp",
"FromPort": 22,
"ToPort": 2222,
"IpRanges": [{"CidrIp": "123.123.123.123/32"}],
}
]
security_group.authorize_ingress(IpPermissions=ingress_permissions)
security_group.ip_permissions.should.have.length_of(1)
security_group.ip_permissions[0]["ToPort"].should.equal(2222)
security_group.ip_permissions[0]["IpProtocol"].should.equal("tcp")
security_group.ip_permissions[0]["IpRanges"].should.equal(
[{"CidrIp": "123.123.123.123/32"}]
)
# Wrong Cidr should throw error
with pytest.raises(ClientError) as ex:
wrong_permissions = copy.deepcopy(ingress_permissions)
wrong_permissions[0]["IpRanges"][0]["CidrIp"] = "123.123.123.122/32"
security_group.revoke_ingress(IpPermissions=wrong_permissions)
ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
ex.value.response["ResponseMetadata"].should.have.key("RequestId")
ex.value.response["Error"]["Code"].should.equal("InvalidPermission.NotFound")
# Actually revoke
with pytest.raises(ClientError) as ex:
security_group.revoke_ingress(IpPermissions=ingress_permissions, DryRun=True)
ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(412)
ex.value.response["Error"]["Code"].should.equal("DryRunOperation")
ex.value.response["Error"]["Message"].should.equal(
"An error occurred (DryRunOperation) when calling the RevokeSecurityGroupIngress operation: Request would have succeeded, but DryRun flag is set"
)
security_group.revoke_ingress(IpPermissions=ingress_permissions)
security_group.ip_permissions.should.have.length_of(0)
# Test for egress as well
egress_security_group = ec2.create_security_group(
GroupName="testegress", Description="testegress", VpcId="vpc-3432589"
)
egress_permissions = [
{
"IpProtocol": "tcp",
"FromPort": 22,
"ToPort": 2222,
"IpRanges": [{"CidrIp": "123.123.123.123/32"}],
}
]
with pytest.raises(ClientError) as ex:
egress_security_group.authorize_egress(
IpPermissions=egress_permissions, DryRun=True
)
ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(412)
ex.value.response["Error"]["Code"].should.equal("DryRunOperation")
ex.value.response["Error"]["Message"].should.equal(
"An error occurred (DryRunOperation) when calling the GrantSecurityGroupEgress operation: Request would have succeeded, but DryRun flag is set"
)
egress_security_group.authorize_egress(IpPermissions=egress_permissions)
egress_security_group.ip_permissions_egress[0]["FromPort"].should.equal(22)
egress_security_group.ip_permissions_egress[0]["IpProtocol"].should.equal("tcp")
egress_security_group.ip_permissions_egress[0]["ToPort"].should.equal(2222)
egress_security_group.ip_permissions_egress[0]["IpRanges"].should.equal(
[{"CidrIp": "123.123.123.123/32"}]
)
# Wrong Cidr should throw error
with pytest.raises(ClientError) as ex:
wrong_permissions = copy.deepcopy(egress_permissions)
wrong_permissions[0]["IpRanges"][0]["CidrIp"] = "123.123.123.122/32"
security_group.revoke_egress(IpPermissions=wrong_permissions)
ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
ex.value.response["ResponseMetadata"].should.have.key("RequestId")
ex.value.response["Error"]["Code"].should.equal("InvalidPermission.NotFound")
# Actually revoke
with pytest.raises(ClientError) as ex:
egress_security_group.revoke_egress(
IpPermissions=egress_permissions, DryRun=True,
)
ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(412)
ex.value.response["Error"]["Code"].should.equal("DryRunOperation")
ex.value.response["Error"]["Message"].should.equal(
"An error occurred (DryRunOperation) when calling the RevokeSecurityGroupEgress operation: Request would have succeeded, but DryRun flag is set"
)
egress_security_group.revoke_egress(IpPermissions=egress_permissions)
egress_security_group = client.describe_security_groups()["SecurityGroups"][0]
# There is still the default outbound rule
egress_security_group["IpPermissionsEgress"].should.have.length_of(1)
# Has boto3 equivalent
@mock_ec2_deprecated
def test_authorize_other_group_and_revoke():
conn = boto.connect_ec2("the_key", "the_secret")
@ -360,6 +652,59 @@ def test_authorize_other_group_and_revoke():
security_group.rules.should.have.length_of(0)
@mock_ec2
def test_authorize_other_group_and_revoke_boto3():
ec2 = boto3.resource("ec2", "us-west-1")
client = boto3.client("ec2", "us-west-1")
security_group = ec2.create_security_group(GroupName="test", Description="test")
other_security_group = ec2.create_security_group(
GroupName="other", Description="other"
)
ec2.create_security_group(GroupName="wrong", Description="wrong")
# Note: Should be easier to use the SourceSecurityGroupNames-parameter, but that's not supported atm
permissions = [
{
"IpProtocol": "tcp",
"FromPort": 22,
"ToPort": 2222,
"UserIdGroupPairs": [
{
"GroupId": other_security_group.id,
"GroupName": other_security_group.group_name,
"UserId": other_security_group.owner_id,
}
],
}
]
security_group.authorize_ingress(IpPermissions=permissions)
found_sec_group = client.describe_security_groups(GroupNames=["test"])[
"SecurityGroups"
][0]
found_sec_group["IpPermissions"][0]["ToPort"].should.equal(2222)
found_sec_group["IpPermissions"][0]["UserIdGroupPairs"][0]["GroupId"].should.equal(
other_security_group.id
)
# Wrong source group should throw error
with pytest.raises(ClientError) as ex:
wrong_permissions = copy.deepcopy(permissions)
wrong_permissions[0]["UserIdGroupPairs"][0]["GroupId"] = "unknown"
security_group.revoke_ingress(IpPermissions=wrong_permissions)
ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
ex.value.response["ResponseMetadata"].should.have.key("RequestId")
ex.value.response["Error"]["Code"].should.equal("InvalidGroup.NotFound")
# Actually revoke
security_group.revoke_ingress(IpPermissions=permissions)
found_sec_group = client.describe_security_groups(GroupNames=["test"])[
"SecurityGroups"
][0]
found_sec_group["IpPermissions"].should.have.length_of(0)
@mock_ec2
def test_authorize_other_group_egress_and_revoke():
ec2 = boto3.resource("ec2", region_name="us-west-1")
@ -395,6 +740,7 @@ def test_authorize_other_group_egress_and_revoke():
sg01.ip_permissions_egress.should.have.length_of(1)
# Has boto3 equivalent
@mock_ec2_deprecated
def test_authorize_group_in_vpc():
conn = boto.connect_ec2("the_key", "the_secret")
@ -435,6 +781,56 @@ def test_authorize_group_in_vpc():
security_group.rules.should.have.length_of(0)
@mock_ec2
def test_authorize_group_in_vpc_boto3():
ec2 = boto3.resource("ec2", "ap-south-1")
client = boto3.client("ec2", region_name="ap-south-1")
vpc_id = "vpc-12345"
# create 2 groups in a vpc
security_group = ec2.create_security_group(
GroupName="test1", Description="test1", VpcId=vpc_id
)
other_security_group = ec2.create_security_group(
GroupName="test2", Description="test2", VpcId=vpc_id
)
permissions = [
{
"IpProtocol": "tcp",
"FromPort": 22,
"ToPort": 2222,
"UserIdGroupPairs": [
{
"GroupId": other_security_group.id,
"GroupName": other_security_group.group_name,
"UserId": other_security_group.owner_id,
}
],
}
]
security_group.authorize_ingress(IpPermissions=permissions)
# Check that the rule is accurate
found_sec_group = client.describe_security_groups(GroupNames=["test1"])[
"SecurityGroups"
][0]
found_sec_group["IpPermissions"][0]["ToPort"].should.equal(2222)
found_sec_group["IpPermissions"][0]["UserIdGroupPairs"][0]["GroupId"].should.equal(
other_security_group.id
)
# Now remove the rule
security_group.revoke_ingress(IpPermissions=permissions)
# And check that it gets revoked
found_sec_group = client.describe_security_groups(GroupNames=["test1"])[
"SecurityGroups"
][0]
found_sec_group["IpPermissions"].should.have.length_of(0)
# Has boto3 equivalent
@mock_ec2_deprecated
def test_get_all_security_groups():
conn = boto.connect_ec2()
@ -472,6 +868,43 @@ def test_get_all_security_groups():
resp.should.have.length_of(3)
@mock_ec2
def test_describe_security_groups():
ec2 = boto3.resource("ec2", "us-west-1")
client = boto3.client("ec2", "us-west-1")
vpc_id = "vpc-mjm05d27"
sg1 = ec2.create_security_group(
GroupName="test1", Description="test1", VpcId=vpc_id
)
ec2.create_security_group(GroupName="test2", Description="test2")
resp = client.describe_security_groups(GroupNames=["test1"])["SecurityGroups"]
resp.should.have.length_of(1)
resp[0].should.have.key("GroupId").equal(sg1.id)
with pytest.raises(ClientError) as ex:
client.describe_security_groups(GroupNames=["does_not_exist"])
ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
ex.value.response["ResponseMetadata"].should.have.key("RequestId")
ex.value.response["Error"]["Code"].should.equal("InvalidGroup.NotFound")
resp = client.describe_security_groups(
Filters=[{"Name": "vpc-id", "Values": [vpc_id]}]
)["SecurityGroups"]
resp.should.have.length_of(1)
resp[0].should.have.key("GroupId").equal(sg1.id)
resp = client.describe_security_groups(
Filters=[{"Name": "description", "Values": ["test1"]}]
)["SecurityGroups"]
resp.should.have.length_of(1)
resp[0].should.have.key("GroupId").equal(sg1.id)
resp = client.describe_security_groups()["SecurityGroups"]
resp.should.have.length_of(3)
# Has boto3 equivalent
@mock_ec2_deprecated
def test_authorize_bad_cidr_throws_invalid_parameter_value():
conn = boto.connect_ec2("the_key", "the_secret")
@ -485,6 +918,26 @@ def test_authorize_bad_cidr_throws_invalid_parameter_value():
cm.value.request_id.should_not.be.none
@mock_ec2
def test_authorize_bad_cidr_throws_invalid_parameter_value_boto3():
ec2 = boto3.resource("ec2", "us-west-1")
sec_group = ec2.create_security_group(GroupName="test", Description="test")
with pytest.raises(ClientError) as ex:
permissions = [
{
"IpProtocol": "tcp",
"FromPort": 22,
"ToPort": 2222,
"IpRanges": [{"CidrIp": "123.123.123.123"}],
}
]
sec_group.authorize_ingress(IpPermissions=permissions)
ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
ex.value.response["ResponseMetadata"].should.have.key("RequestId")
ex.value.response["Error"]["Code"].should.equal("InvalidParameterValue")
# Has boto3 equivalent
@mock_ec2_deprecated
def test_security_group_tagging():
conn = boto.connect_vpc()
@ -511,6 +964,7 @@ def test_security_group_tagging():
group.tags["Test"].should.equal("Tag")
# Has boto3 equivalent
@mock_ec2_deprecated
def test_security_group_tag_filtering():
conn = boto.connect_ec2()
@ -521,6 +975,25 @@ def test_security_group_tag_filtering():
groups.should.have.length_of(1)
@mock_ec2
def test_security_group_tag_filtering_boto3():
ec2 = boto3.resource("ec2", region_name="us-east-1")
client = boto3.client("ec2", region_name="us-east-1")
sg = ec2.create_security_group(GroupName="test-sg", Description="Test SG")
sg.create_tags(Tags=[{"Key": "test-tag", "Value": "test-value"}])
groups = client.describe_security_groups(
Filters=[{"Name": "tag:test-tag", "Values": ["test-value"]}]
)["SecurityGroups"]
groups.should.have.length_of(1)
groups = client.describe_security_groups(
Filters=[{"Name": "tag:test-tag", "Values": ["unknown"]}]
)["SecurityGroups"]
groups.should.have.length_of(0)
# Has boto3 equivalent
@mock_ec2_deprecated
def test_authorize_all_protocols_with_no_port_specification():
conn = boto.connect_ec2()
@ -534,6 +1007,24 @@ def test_authorize_all_protocols_with_no_port_specification():
sg.rules[0].to_port.should.equal(None)
@mock_ec2
def test_authorize_all_protocols_with_no_port_specification_boto3():
ec2 = boto3.resource("ec2", region_name="us-east-1")
client = boto3.client("ec2", region_name="us-east-1")
sg = ec2.create_security_group(GroupName="test", Description="test")
permissions = [{"IpProtocol": "-1", "IpRanges": [{"CidrIp": "0.0.0.0/0"}]}]
sg.authorize_ingress(IpPermissions=permissions)
sg = client.describe_security_groups(GroupNames=["test"])["SecurityGroups"][0]
permission = sg["IpPermissions"][0]
permission.should.have.key("IpProtocol").equal("-1")
permission.should.have.key("IpRanges").equal([{"CidrIp": "0.0.0.0/0"}])
permission.shouldnt.have.key("FromPort")
permission.shouldnt.have.key("ToPort")
# Has boto3 equivalent
@mock_ec2_deprecated
def test_sec_group_rule_limit():
ec2_conn = boto.connect_ec2()
@ -599,6 +1090,123 @@ def test_sec_group_rule_limit():
cm.value.error_code.should.equal("RulesPerSecurityGroupLimitExceeded")
@mock_ec2
@pytest.mark.parametrize(
"use_vpc", [True, False], ids=["Use VPC", "Without VPC"],
)
def test_sec_group_rule_limit_boto3(use_vpc):
ec2 = boto3.resource("ec2", region_name="us-west-1")
client = boto3.client("ec2", region_name="us-west-1")
limit = 60
if use_vpc:
vpc = ec2.create_vpc(CidrBlock="10.0.0.0/16")
sg = ec2.create_security_group(
GroupName="test", Description="test", VpcId=vpc.id
)
other_sg = ec2.create_security_group(
GroupName="test_2", Description="test_other", VpcId=vpc.id
)
else:
sg = ec2.create_security_group(GroupName="test", Description="test")
other_sg = ec2.create_security_group(
GroupName="test_2", Description="test_other"
)
# INGRESS
with pytest.raises(ClientError) as ex:
ip_permissions = [
{
"IpProtocol": "-1",
"IpRanges": [{"CidrIp": "{}.0.0.0/0".format(i)} for i in range(110)],
}
]
client.authorize_security_group_ingress(
GroupId=sg.id, IpPermissions=ip_permissions
)
ex.value.response["Error"]["Code"].should.equal(
"RulesPerSecurityGroupLimitExceeded"
)
sg.reload()
sg.ip_permissions.should.be.empty
# authorize a rule targeting a different sec group (because this count too)
other_permissions = [
{
"IpProtocol": "-1",
"UserIdGroupPairs": [
{
"GroupId": other_sg.id,
"GroupName": other_sg.group_name,
"UserId": other_sg.owner_id,
}
],
}
]
client.authorize_security_group_ingress(
GroupId=sg.id, IpPermissions=other_permissions
)
# fill the rules up the limit
permissions = [
{
"IpProtocol": "-1",
"IpRanges": [{"CidrIp": "{}.0.0.0/0".format(i)} for i in range(limit - 1)],
}
]
client.authorize_security_group_ingress(GroupId=sg.id, IpPermissions=permissions)
# verify that we cannot authorize past the limit for a CIDR IP
with pytest.raises(ClientError) as ex:
permissions = [{"IpProtocol": "-1", "IpRanges": [{"CidrIp": "100.0.0.0/0"}],}]
client.authorize_security_group_ingress(
GroupId=sg.id, IpPermissions=permissions
)
ex.value.response["Error"]["Code"].should.equal(
"RulesPerSecurityGroupLimitExceeded"
)
# verify that we cannot authorize past the limit for a different sec group
with pytest.raises(ClientError) as ex:
client.authorize_security_group_ingress(
GroupId=sg.id, IpPermissions=other_permissions
)
ex.value.response["Error"]["Code"].should.equal(
"RulesPerSecurityGroupLimitExceeded"
)
# EGRESS
# authorize a rule targeting a different sec group (because this count too)
client.authorize_security_group_egress(
GroupId=sg.id, IpPermissions=other_permissions
)
# fill the rules up the limit
# remember that by default, when created a sec group contains 1 egress rule
# so our other_sg rule + 98 CIDR IP rules + 1 by default == 100 the limit
permissions = [
{
"IpProtocol": "-1",
"IpRanges": [
{"CidrIp": "{}.0.0.0/0".format(i)} for i in range(1, limit - 1)
],
}
]
client.authorize_security_group_egress(GroupId=sg.id, IpPermissions=permissions)
# verify that we cannot authorize past the limit for a CIDR IP
with pytest.raises(ClientError) as ex:
permissions = [{"IpProtocol": "-1", "IpRanges": [{"CidrIp": "101.0.0.0/0"}],}]
client.authorize_security_group_egress(GroupId=sg.id, IpPermissions=permissions)
ex.value.response["Error"]["Code"].should.equal(
"RulesPerSecurityGroupLimitExceeded"
)
# verify that we cannot authorize past the limit for a different sec group
with pytest.raises(ClientError) as ex:
client.authorize_security_group_egress(
GroupId=sg.id, IpPermissions=other_permissions
)
ex.value.response["Error"]["Code"].should.equal(
"RulesPerSecurityGroupLimitExceeded"
)
# Has boto3 equivalent
@mock_ec2_deprecated
def test_sec_group_rule_limit_vpc():
ec2_conn = boto.connect_ec2()
@ -1013,6 +1621,7 @@ def test_security_group_ingress_without_multirule_after_reload():
assert len(sg_after.ip_permissions) == 1
# Has boto3 equivalent
@mock_ec2_deprecated
def test_get_all_security_groups_filter_with_same_vpc_id():
conn = boto.connect_ec2("the_key", "the_secret")
@ -1035,6 +1644,33 @@ def test_get_all_security_groups_filter_with_same_vpc_id():
cm.value.request_id.should_not.be.none
@mock_ec2
def test_get_all_security_groups_filter_with_same_vpc_id_boto3():
ec2 = boto3.resource("ec2", region_name="us-east-1")
client = boto3.client("ec2", region_name="us-east-1")
vpc_id = "vpc-5300000c"
security_group = ec2.create_security_group(
GroupName="test1", Description="test1", VpcId=vpc_id
)
security_group2 = ec2.create_security_group(
GroupName="test2", Description="test2", VpcId=vpc_id
)
security_group.vpc_id.should.equal(vpc_id)
security_group2.vpc_id.should.equal(vpc_id)
security_groups = client.describe_security_groups(
GroupIds=[security_group.id], Filters=[{"Name": "vpc-id", "Values": [vpc_id]}]
)["SecurityGroups"]
security_groups.should.have.length_of(1)
with pytest.raises(ClientError) as ex:
client.describe_security_groups(GroupIds=["does_not_exist"])
ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
ex.value.response["ResponseMetadata"].should.have.key("RequestId")
ex.value.response["Error"]["Code"].should.equal("InvalidGroup.NotFound")
@mock_ec2
def test_revoke_security_group_egress():
ec2 = boto3.resource("ec2", "us-east-1")

View File

@ -147,6 +147,7 @@ def test_request_spot_instances_default_arguments():
request.shouldnt.contain("SubnetId")
# Has boto3 equivalent
@mock_ec2_deprecated
def test_cancel_spot_instance_request():
conn = boto.connect_ec2()
@ -170,6 +171,42 @@ def test_cancel_spot_instance_request():
requests.should.have.length_of(0)
@mock_ec2
def test_cancel_spot_instance_request_boto3():
client = boto3.client("ec2", region_name="us-west-1")
client.request_spot_instances(
SpotPrice="0.5", LaunchSpecification={"ImageId": EXAMPLE_AMI_ID}
)
requests = client.describe_spot_instance_requests()["SpotInstanceRequests"]
requests.should.have.length_of(1)
request = requests[0]
request.should.have.key("CreateTime")
request.should.have.key("Type").equal("one-time")
request.should.have.key("SpotInstanceRequestId")
request.should.have.key("SpotPrice").equal("0.5")
request["LaunchSpecification"]["ImageId"].should.equal(EXAMPLE_AMI_ID)
with pytest.raises(ClientError) as ex:
client.cancel_spot_instance_requests(
SpotInstanceRequestIds=[request["SpotInstanceRequestId"]], DryRun=True
)
ex.value.response["Error"]["Code"].should.equal("DryRunOperation")
ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(412)
ex.value.response["Error"]["Message"].should.equal(
"An error occurred (DryRunOperation) when calling the CancelSpotInstance operation: Request would have succeeded, but DryRun flag is set"
)
client.cancel_spot_instance_requests(
SpotInstanceRequestIds=[request["SpotInstanceRequestId"]]
)
requests = client.describe_spot_instance_requests()["SpotInstanceRequests"]
requests.should.have.length_of(0)
# Has boto3 equivalent
@mock_ec2_deprecated
def test_request_spot_instances_fulfilled():
"""
@ -195,6 +232,36 @@ def test_request_spot_instances_fulfilled():
request.state.should.equal("active")
@mock_ec2
def test_request_spot_instances_fulfilled_boto3():
"""
Test that moto correctly fullfills a spot instance request
"""
ec2 = boto3.resource("ec2", region_name="us-east-1")
client = boto3.client("ec2", region_name="us-east-1")
request = client.request_spot_instances(
SpotPrice="0.5", LaunchSpecification={"ImageId": EXAMPLE_AMI_ID}
)
request_id = request["SpotInstanceRequests"][0]["SpotInstanceRequestId"]
requests = client.describe_spot_instance_requests()["SpotInstanceRequests"]
requests.should.have.length_of(1)
request = requests[0]
request["State"].should.equal("open")
if not settings.TEST_SERVER_MODE:
ec2_backends["us-east-1"].spot_instance_requests[request_id].state = "active"
requests = client.describe_spot_instance_requests()["SpotInstanceRequests"]
requests.should.have.length_of(1)
request = requests[0]
request["State"].should.equal("active")
# Has boto3 equivalent
@mock_ec2_deprecated
def test_tag_spot_instance_request():
"""
@ -214,6 +281,32 @@ def test_tag_spot_instance_request():
tag_dict.should.equal({"tag1": "value1", "tag2": "value2"})
@mock_ec2
def test_tag_spot_instance_request_boto3():
"""
Test that moto correctly tags a spot instance request
"""
client = boto3.client("ec2", region_name="us-west-1")
request = client.request_spot_instances(
SpotPrice="0.5", LaunchSpecification={"ImageId": EXAMPLE_AMI_ID}
)
request_id = request["SpotInstanceRequests"][0]["SpotInstanceRequestId"]
client.create_tags(
Resources=[request_id],
Tags=[{"Key": "tag1", "Value": "value1"}, {"Key": "tag2", "Value": "value2"}],
)
requests = client.describe_spot_instance_requests()["SpotInstanceRequests"]
requests.should.have.length_of(1)
request = requests[0]
request["Tags"].should.have.length_of(2)
request["Tags"].should.contain({"Key": "tag1", "Value": "value1"})
request["Tags"].should.contain({"Key": "tag2", "Value": "value2"})
# Has boto3 equivalent
@mock_ec2_deprecated
def test_get_all_spot_instance_requests_filtering():
"""
@ -244,6 +337,58 @@ def test_get_all_spot_instance_requests_filtering():
requests.should.have.length_of(1)
@mock_ec2
def test_get_all_spot_instance_requests_filtering_boto3():
"""
Test that moto correctly filters spot instance requests
"""
client = boto3.client("ec2", region_name="us-west-1")
request1 = client.request_spot_instances(
SpotPrice="0.5", LaunchSpecification={"ImageId": EXAMPLE_AMI_ID}
)
request1_id = request1["SpotInstanceRequests"][0]["SpotInstanceRequestId"]
request2 = client.request_spot_instances(
SpotPrice="0.5", LaunchSpecification={"ImageId": EXAMPLE_AMI_ID}
)
request2_id = request2["SpotInstanceRequests"][0]["SpotInstanceRequestId"]
client.request_spot_instances(
SpotPrice="0.5", LaunchSpecification={"ImageId": EXAMPLE_AMI_ID}
)
client.create_tags(
Resources=[request1_id],
Tags=[{"Key": "tag1", "Value": "value1"}, {"Key": "tag2", "Value": "value2"}],
)
client.create_tags(
Resources=[request2_id],
Tags=[{"Key": "tag1", "Value": "value1"}, {"Key": "tag2", "Value": "wrong"}],
)
requests = client.describe_spot_instance_requests(
Filters=[{"Name": "state", "Values": ["active"]}]
)["SpotInstanceRequests"]
requests.should.have.length_of(0)
requests = client.describe_spot_instance_requests(
Filters=[{"Name": "state", "Values": ["open"]}]
)["SpotInstanceRequests"]
requests.should.have.length_of(3)
requests = client.describe_spot_instance_requests(
Filters=[{"Name": "tag:tag1", "Values": ["value1"]}]
)["SpotInstanceRequests"]
requests.should.have.length_of(2)
requests = client.describe_spot_instance_requests(
Filters=[
{"Name": "tag:tag1", "Values": ["value1"]},
{"Name": "tag:tag2", "Values": ["value2"]},
]
)["SpotInstanceRequests"]
requests.should.have.length_of(1)
# Has boto3 equivalent
@mock_ec2_deprecated
def test_request_spot_instances_setting_instance_id():
conn = boto.ec2.connect_to_region("us-east-1")
@ -334,3 +479,21 @@ def test_spot_price_history():
response = client.describe_spot_price_history(InstanceTypes=i_types)
price = response["SpotPriceHistory"][0]
assert price["InstanceType"] in i_types
@mock_ec2
def test_request_spot_instances_setting_instance_id_boto3():
client = boto3.client("ec2", region_name="us-east-1")
request = client.request_spot_instances(
SpotPrice="0.5", LaunchSpecification={"ImageId": EXAMPLE_AMI_ID}
)
request_id = request["SpotInstanceRequests"][0]["SpotInstanceRequestId"]
if not settings.TEST_SERVER_MODE:
req = ec2_backends["us-east-1"].spot_instance_requests[request_id]
req.state = "active"
req.instance_id = "i-12345678"
request = client.describe_spot_instance_requests()["SpotInstanceRequests"][0]
assert request["State"] == "active"
assert request["InstanceId"] == "i-12345678"

View File

@ -10,10 +10,11 @@ import pytest
import sure # noqa
from boto.exception import EC2ResponseError
from botocore.exceptions import ClientError
from moto import mock_ec2, mock_ec2_deprecated
from moto import mock_ec2, mock_ec2_deprecated, settings
from tests import EXAMPLE_AMI_ID
# Has boto3 equivalent
@mock_ec2_deprecated
def test_subnets():
ec2 = boto.connect_ec2("the_key", "the_secret")
@ -36,6 +37,30 @@ def test_subnets():
cm.value.request_id.should_not.be.none
@mock_ec2
def test_subnets_boto3():
ec2 = boto3.resource("ec2", region_name="us-east-1")
client = boto3.client("ec2", region_name="us-east-1")
vpc = ec2.create_vpc(CidrBlock="10.0.0.0/16")
subnet = ec2.create_subnet(VpcId=vpc.id, CidrBlock="10.0.0.0/18")
all_subnets = client.describe_subnets()["Subnets"]
nr_of_a_zones = len(client.describe_availability_zones()["AvailabilityZones"])
all_subnets.should.have.length_of(1 + nr_of_a_zones)
client.delete_subnet(SubnetId=subnet.id)
all_subnets = client.describe_subnets()["Subnets"]
all_subnets.should.have.length_of(nr_of_a_zones)
with pytest.raises(ClientError) as ex:
client.delete_subnet(SubnetId=subnet.id)
ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
ex.value.response["ResponseMetadata"].should.have.key("RequestId")
ex.value.response["Error"]["Code"].should.equal("InvalidSubnetID.NotFound")
# Has boto3 equivalent
@mock_ec2_deprecated
def test_subnet_create_vpc_validation():
conn = boto.connect_vpc("the_key", "the_secret")
@ -47,6 +72,18 @@ def test_subnet_create_vpc_validation():
cm.value.request_id.should_not.be.none
@mock_ec2
def test_subnet_create_vpc_validation_boto3():
ec2 = boto3.resource("ec2", region_name="us-east-1")
with pytest.raises(ClientError) as ex:
ec2.create_subnet(VpcId="vpc-abcd1234", CidrBlock="10.0.0.0/18")
ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
ex.value.response["ResponseMetadata"].should.have.key("RequestId")
ex.value.response["Error"]["Code"].should.equal("InvalidVpcID.NotFound")
# Has boto3 equivalent
@mock_ec2_deprecated
def test_subnet_tagging():
conn = boto.connect_vpc("the_key", "the_secret")
@ -65,6 +102,25 @@ def test_subnet_tagging():
subnet.tags["a key"].should.equal("some value")
@mock_ec2
def test_subnet_tagging_boto3():
ec2 = boto3.resource("ec2", region_name="us-east-1")
client = boto3.client("ec2", region_name="us-east-1")
vpc = ec2.create_vpc(CidrBlock="10.0.0.0/16")
subnet = ec2.create_subnet(VpcId=vpc.id, CidrBlock="10.0.0.0/18")
subnet.create_tags(Tags=[{"Key": "a key", "Value": "some value"}])
tag = client.describe_tags()["Tags"][0]
tag["Key"].should.equal("a key")
tag["Value"].should.equal("some value")
# Refresh the subnet
subnet = client.describe_subnets(SubnetIds=[subnet.id])["Subnets"][0]
subnet["Tags"].should.equal([{"Key": "a key", "Value": "some value"}])
# Has boto3 equivalent
@mock_ec2_deprecated
def test_subnet_should_have_proper_availability_zone_set():
conn = boto.vpc.connect_to_region("us-west-1")
@ -73,6 +129,16 @@ def test_subnet_should_have_proper_availability_zone_set():
subnetA.availability_zone.should.equal("us-west-1b")
@mock_ec2
def test_subnet_should_have_proper_availability_zone_set_boto3():
ec2 = boto3.resource("ec2", region_name="us-west-1")
vpcA = ec2.create_vpc(CidrBlock="10.0.0.0/16")
subnetA = ec2.create_subnet(
VpcId=vpcA.id, CidrBlock="10.0.0.0/24", AvailabilityZone="us-west-1b"
)
subnetA.availability_zone.should.equal("us-west-1b")
@mock_ec2
def test_availability_zone_in_create_subnet():
ec2 = boto3.resource("ec2", region_name="us-west-1")
@ -101,6 +167,7 @@ def test_default_subnet():
subnet.map_public_ip_on_launch.shouldnt.be.ok
# Has boto3 equivalent
@mock_ec2_deprecated
def test_non_default_subnet():
vpc_cli = boto.vpc.connect_to_region("us-west-1")
@ -203,6 +270,7 @@ def test_modify_subnet_attribute_validation():
)
# Has boto3 equivalent
@mock_ec2_deprecated
def test_subnet_get_by_id():
ec2 = boto.ec2.connect_to_region("us-west-1")
@ -230,6 +298,38 @@ def test_subnet_get_by_id():
cm.value.request_id.should_not.be.none
@mock_ec2
def test_subnet_get_by_id_boto3():
ec2 = boto3.resource("ec2", region_name="us-west-1")
client = boto3.client("ec2", region_name="us-west-1")
vpcA = ec2.create_vpc(CidrBlock="10.0.0.0/16")
subnetA = ec2.create_subnet(
VpcId=vpcA.id, CidrBlock="10.0.0.0/24", AvailabilityZone="us-west-1a"
)
vpcB = ec2.create_vpc(CidrBlock="10.0.0.0/16")
subnetB1 = ec2.create_subnet(
VpcId=vpcB.id, CidrBlock="10.0.0.0/24", AvailabilityZone="us-west-1a"
)
subnetB2 = ec2.create_subnet(
VpcId=vpcB.id, CidrBlock="10.0.1.0/24", AvailabilityZone="us-west-1b"
)
subnets_by_id = client.describe_subnets(SubnetIds=[subnetA.id, subnetB1.id])[
"Subnets"
]
subnets_by_id.should.have.length_of(2)
subnets_by_id = tuple(map(lambda s: s["SubnetId"], subnets_by_id))
subnetA.id.should.be.within(subnets_by_id)
subnetB1.id.should.be.within(subnets_by_id)
with pytest.raises(ClientError) as ex:
client.describe_subnets(SubnetIds=["subnet-does_not_exist"])
ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
ex.value.response["ResponseMetadata"].should.have.key("RequestId")
ex.value.response["Error"]["Code"].should.equal("InvalidSubnetID.NotFound")
# Has boto3 equivalent
@mock_ec2_deprecated
def test_get_subnets_filtering():
ec2 = boto.ec2.connect_to_region("us-west-1")
@ -305,6 +405,101 @@ def test_get_subnets_filtering():
).should.throw(NotImplementedError)
@mock_ec2
def test_get_subnets_filtering_boto3():
ec2 = boto3.resource("ec2", region_name="us-west-1")
client = boto3.client("ec2", region_name="us-west-1")
vpcA = ec2.create_vpc(CidrBlock="10.0.0.0/16")
subnetA = ec2.create_subnet(
VpcId=vpcA.id, CidrBlock="10.0.0.0/24", AvailabilityZone="us-west-1a"
)
vpcB = ec2.create_vpc(CidrBlock="10.0.0.0/16")
subnetB1 = ec2.create_subnet(
VpcId=vpcB.id, CidrBlock="10.0.0.0/24", AvailabilityZone="us-west-1a"
)
subnetB2 = ec2.create_subnet(
VpcId=vpcB.id, CidrBlock="10.0.1.0/24", AvailabilityZone="us-west-1b"
)
nr_of_a_zones = len(client.describe_availability_zones()["AvailabilityZones"])
all_subnets = client.describe_subnets()["Subnets"]
all_subnets.should.have.length_of(3 + nr_of_a_zones)
# Filter by VPC ID
subnets_by_vpc = client.describe_subnets(
Filters=[{"Name": "vpc-id", "Values": [vpcB.id]}]
)["Subnets"]
subnets_by_vpc.should.have.length_of(2)
set([subnet["SubnetId"] for subnet in subnets_by_vpc]).should.equal(
set([subnetB1.id, subnetB2.id])
)
# Filter by CIDR variations
subnets_by_cidr1 = client.describe_subnets(
Filters=[{"Name": "cidr", "Values": ["10.0.0.0/24"]}]
)["Subnets"]
subnets_by_cidr1.should.have.length_of(2)
set([subnet["SubnetId"] for subnet in subnets_by_cidr1]).should.equal(
set([subnetA.id, subnetB1.id])
)
subnets_by_cidr2 = client.describe_subnets(
Filters=[{"Name": "cidr-block", "Values": ["10.0.0.0/24"]}]
)["Subnets"]
subnets_by_cidr2.should.have.length_of(2)
set([subnet["SubnetId"] for subnet in subnets_by_cidr2]).should.equal(
set([subnetA.id, subnetB1.id])
)
subnets_by_cidr3 = client.describe_subnets(
Filters=[{"Name": "cidrBlock", "Values": ["10.0.0.0/24"]}]
)["Subnets"]
subnets_by_cidr3.should.have.length_of(2)
set([subnet["SubnetId"] for subnet in subnets_by_cidr3]).should.equal(
set([subnetA.id, subnetB1.id])
)
# Filter by VPC ID and CIDR
subnets_by_vpc_and_cidr = client.describe_subnets(
Filters=[
{"Name": "vpc-id", "Values": [vpcB.id]},
{"Name": "cidr", "Values": ["10.0.0.0/24"]},
]
)["Subnets"]
subnets_by_vpc_and_cidr.should.have.length_of(1)
subnets_by_vpc_and_cidr[0]["SubnetId"].should.equal(subnetB1.id)
# Filter by subnet ID
subnets_by_id = client.describe_subnets(
Filters=[{"Name": "subnet-id", "Values": [subnetA.id]}]
)["Subnets"]
subnets_by_id.should.have.length_of(1)
subnets_by_id[0]["SubnetId"].should.equal(subnetA.id)
# Filter by availabilityZone
subnets_by_az = client.describe_subnets(
Filters=[
{"Name": "availabilityZone", "Values": ["us-west-1a"]},
{"Name": "vpc-id", "Values": [vpcB.id]},
]
)["Subnets"]
subnets_by_az.should.have.length_of(1)
subnets_by_az[0]["SubnetId"].should.equal(subnetB1.id)
# Filter by defaultForAz
subnets_by_az = client.describe_subnets(
Filters=[{"Name": "defaultForAz", "Values": ["true"]}]
)["Subnets"]
subnets_by_az.should.have.length_of(nr_of_a_zones)
# Unsupported filter
if not settings.TEST_SERVER_MODE:
filters = [{"Name": "not-implemented-filter", "Values": ["foobar"]}]
client.describe_subnets.when.called_with(Filters=filters).should.throw(
NotImplementedError
)
@mock_ec2
def test_create_subnet_response_fields():
ec2 = boto3.resource("ec2", region_name="us-west-1")

View File

@ -15,6 +15,7 @@ import pytest
from tests import EXAMPLE_AMI_ID
# Has boto3 equivalent
@mock_ec2_deprecated
def test_add_tag():
conn = boto.connect_ec2("the_key", "the_secret")
@ -39,6 +40,33 @@ def test_add_tag():
existing_instance.tags["a key"].should.equal("some value")
@mock_ec2
def test_instance_create_tags():
ec2 = boto3.resource("ec2", "us-west-1")
client = boto3.client("ec2", "us-west-1")
instance = ec2.create_instances(ImageId=EXAMPLE_AMI_ID, MinCount=1, MaxCount=1)[0]
with pytest.raises(ClientError) as ex:
instance.create_tags(
Tags=[{"Key": "a key", "Value": "some value"}], DryRun=True
)
ex.value.response["Error"]["Code"].should.equal("DryRunOperation")
ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(412)
ex.value.response["Error"]["Message"].should.equal(
"An error occurred (DryRunOperation) when calling the CreateTags operation: Request would have succeeded, but DryRun flag is set"
)
instance.create_tags(Tags=[{"Key": "a key", "Value": "some value"}])
chain = itertools.chain.from_iterable
existing_instances = list(
chain([res["Instances"] for res in client.describe_instances()["Reservations"]])
)
existing_instances.should.have.length_of(1)
existing_instance = existing_instances[0]
existing_instance["Tags"].should.equal([{"Key": "a key", "Value": "some value"}])
# Has boto3 equivalent
@mock_ec2_deprecated
def test_remove_tag():
conn = boto.connect_ec2("the_key", "the_secret")
@ -68,6 +96,40 @@ def test_remove_tag():
instance.remove_tag("a key", "some value")
@mock_ec2
def test_instance_delete_tags():
ec2 = boto3.resource("ec2", region_name="us-east-1")
client = boto3.client("ec2", region_name="us-east-1")
instance = ec2.create_instances(ImageId=EXAMPLE_AMI_ID, MinCount=1, MaxCount=1)[0]
instance.create_tags(Tags=[{"Key": "a key", "Value": "some value"}])
tags = client.describe_tags()["Tags"]
tag = tags[0]
tag.should.have.key("Key").equal("a key")
tag.should.have.key("Value").equal("some value")
with pytest.raises(ClientError) as ex:
instance.delete_tags(DryRun=True)
ex.value.response["Error"]["Code"].should.equal("DryRunOperation")
ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(412)
ex.value.response["Error"]["Message"].should.equal(
"An error occurred (DryRunOperation) when calling the DeleteTags operation: Request would have succeeded, but DryRun flag is set"
)
# Specifying key only
instance.delete_tags(Tags=[{"Key": "a key"}])
client.describe_tags()["Tags"].should.have.length_of(0)
instance.create_tags(Tags=[{"Key": "a key", "Value": "some value"}])
client.describe_tags()["Tags"].should.have.length_of(1)
# Specifying key and value
instance.delete_tags(Tags=[{"Key": "a key", "Value": "some value"}])
client.describe_tags()["Tags"].should.have.length_of(0)
# Has boto3 equivalent
@mock_ec2_deprecated
def test_get_all_tags():
conn = boto.connect_ec2("the_key", "the_secret")
@ -82,6 +144,7 @@ def test_get_all_tags():
tag.value.should.equal("some value")
# Has boto3 equivalent
@mock_ec2_deprecated
def test_get_all_tags_with_special_characters():
conn = boto.connect_ec2("the_key", "the_secret")
@ -96,6 +159,20 @@ def test_get_all_tags_with_special_characters():
tag.value.should.equal("some<> value")
@mock_ec2
def test_get_all_tags_with_special_characters_boto3():
ec2 = boto3.resource("ec2", region_name="us-east-1")
client = boto3.client("ec2", region_name="us-east-1")
instance = ec2.create_instances(ImageId=EXAMPLE_AMI_ID, MinCount=1, MaxCount=1)[0]
instance.create_tags(Tags=[{"Key": "a key", "Value": "some<> value"}])
tag = client.describe_tags()["Tags"][0]
tag.should.have.key("Key").equal("a key")
tag.should.have.key("Value").equal("some<> value")
# Has boto3 equivalent
@mock_ec2_deprecated
def test_create_tags():
conn = boto.connect_ec2("the_key", "the_secret")
@ -123,6 +200,40 @@ def test_create_tags():
)
@mock_ec2
def test_create_tags_boto3():
ec2 = boto3.resource("ec2", region_name="us-east-1")
client = boto3.client("ec2", region_name="us-east-1")
instance = ec2.create_instances(ImageId=EXAMPLE_AMI_ID, MinCount=1, MaxCount=1)[0]
tag_list = [
{"Key": "a key", "Value": "some value"},
{"Key": "another key", "Value": "some other value"},
{"Key": "blank key", "Value": ""},
]
with pytest.raises(ClientError) as ex:
client.create_tags(Resources=[instance.id], Tags=tag_list, DryRun=True)
ex.value.response["Error"]["Code"].should.equal("DryRunOperation")
ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(412)
ex.value.response["Error"]["Message"].should.equal(
"An error occurred (DryRunOperation) when calling the CreateTags operation: Request would have succeeded, but DryRun flag is set"
)
client.create_tags(Resources=[instance.id], Tags=tag_list)
tags = client.describe_tags()["Tags"]
tags.should.have.length_of(3)
for expected_tag in tag_list:
tags.should.contain(
{
"Key": expected_tag["Key"],
"ResourceId": instance.id,
"ResourceType": "instance",
"Value": expected_tag["Value"],
}
)
# Has boto3 equivalent
@mock_ec2_deprecated
def test_tag_limit_exceeded():
conn = boto.connect_ec2("the_key", "the_secret")
@ -152,6 +263,35 @@ def test_tag_limit_exceeded():
tag.value.should.equal("a value")
@mock_ec2
def test_tag_limit_exceeded_boto3():
ec2 = boto3.resource("ec2", region_name="us-east-1")
client = boto3.client("ec2", region_name="us-east-1")
instance = ec2.create_instances(ImageId=EXAMPLE_AMI_ID, MinCount=1, MaxCount=1)[0]
tag_list = []
for i in range(51):
tag_list.append({"Key": "{0:02d}".format(i + 1), "Value": ""})
with pytest.raises(ClientError) as ex:
client.create_tags(Resources=[instance.id], Tags=tag_list)
ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
ex.value.response["ResponseMetadata"].should.have.key("RequestId")
ex.value.response["Error"]["Code"].should.equal("TagLimitExceeded")
instance.create_tags(Tags=[{"Key": "a key", "Value": "a value"}])
with pytest.raises(ClientError) as ex:
client.create_tags(Resources=[instance.id], Tags=tag_list)
ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
ex.value.response["ResponseMetadata"].should.have.key("RequestId")
ex.value.response["Error"]["Code"].should.equal("TagLimitExceeded")
tags = client.describe_tags()["Tags"]
tags.should.have.length_of(1)
tags[0].should.have.key("Key").equal("a key")
tags[0].should.have.key("Value").equal("a value")
# Has boto3 equivalent
@mock_ec2_deprecated
def test_invalid_parameter_tag_null():
conn = boto.connect_ec2("the_key", "the_secret")
@ -165,6 +305,7 @@ def test_invalid_parameter_tag_null():
cm.value.request_id.should_not.be.none
# Has boto3 equivalent
@mock_ec2_deprecated
def test_invalid_id():
conn = boto.connect_ec2("the_key", "the_secret")
@ -181,6 +322,27 @@ def test_invalid_id():
cm.value.request_id.should_not.be.none
@mock_ec2
def test_invalid_id_boto3():
client = boto3.client("ec2", region_name="us-east-1")
with pytest.raises(ClientError) as ex:
client.create_tags(
Resources=["ami-blah"], Tags=[{"Key": "key", "Value": "tag"}]
)
ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
ex.value.response["ResponseMetadata"].should.have.key("RequestId")
ex.value.response["Error"]["Code"].should.equal("InvalidID")
with pytest.raises(ClientError) as ex:
client.create_tags(
Resources=["blah-blah"], Tags=[{"Key": "key", "Value": "tag"}]
)
ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
ex.value.response["ResponseMetadata"].should.have.key("RequestId")
ex.value.response["Error"]["Code"].should.equal("InvalidID")
# Has boto3 equivalent
@mock_ec2_deprecated
def test_get_all_tags_resource_id_filter():
conn = boto.connect_ec2("the_key", "the_secret")
@ -208,6 +370,59 @@ def test_get_all_tags_resource_id_filter():
tag.value.should.equal("some value")
@mock_ec2
def test_get_all_tags_resource_filter_boto3():
ec2 = boto3.resource("ec2", region_name="us-east-1")
client = boto3.client("ec2", region_name="us-east-1")
instance = ec2.create_instances(ImageId=EXAMPLE_AMI_ID, MinCount=1, MaxCount=1)[0]
client.create_tags(
Resources=[instance.id],
Tags=[{"Key": "an instance key", "Value": "some value"}],
)
image = instance.create_image(Name="test-ami", Description="this is a test ami")
image.create_tags(Tags=[{"Key": "an image key", "Value": "some value"}])
expected = {
"Key": "an instance key",
"ResourceId": instance.id,
"ResourceType": "instance",
"Value": "some value",
}
tags = client.describe_tags(
Filters=[{"Name": "resource-id", "Values": [instance.id]}]
)["Tags"]
tags.should.equal([expected])
tags = client.describe_tags(
Filters=[{"Name": "resource-type", "Values": ["instance"]}]
)["Tags"]
tags.should.equal([expected])
tags = client.describe_tags(
Filters=[{"Name": "key", "Values": ["an instance key"]}]
)["Tags"]
tags.should.equal([expected])
expected = {
"Key": "an image key",
"ResourceId": image.id,
"ResourceType": "image",
"Value": "some value",
}
tags = client.describe_tags(
Filters=[{"Name": "resource-id", "Values": [image.id]}]
)["Tags"]
tags.should.equal([expected])
tags = client.describe_tags(
Filters=[{"Name": "resource-type", "Values": ["image"]}]
)["Tags"]
tags.should.equal([expected])
tags = client.describe_tags(
Filters=[{"Name": "resource-type", "Values": ["unknown"]}]
)["Tags"]
tags.should.equal([])
# Has boto3 equivalent
@mock_ec2_deprecated
def test_get_all_tags_resource_type_filter():
conn = boto.connect_ec2("the_key", "the_secret")
@ -235,6 +450,7 @@ def test_get_all_tags_resource_type_filter():
tag.value.should.equal("some value")
# Has boto3 equivalent
@mock_ec2_deprecated
def test_get_all_tags_key_filter():
conn = boto.connect_ec2("the_key", "the_secret")
@ -254,6 +470,7 @@ def test_get_all_tags_key_filter():
tag.value.should.equal("some value")
# Has boto3 equivalent
@mock_ec2_deprecated
def test_get_all_tags_value_filter():
conn = boto.connect_ec2("the_key", "the_secret")
@ -298,6 +515,43 @@ def test_get_all_tags_value_filter():
tags.should.have.length_of(1)
@mock_ec2
def test_get_all_tags_value_filter_boto3():
ec2 = boto3.resource("ec2", region_name="us-east-1")
client = boto3.client("ec2", region_name="us-east-1")
def create_instance_with_tag(value):
instance = ec2.create_instances(ImageId=EXAMPLE_AMI_ID, MinCount=1, MaxCount=1)[
0
]
tag = {"Key": "an instance key", "Value": value}
client.create_tags(Resources=[instance.id], Tags=[tag])
return instance
instance_a = create_instance_with_tag("some value")
instance_b = create_instance_with_tag("some other value")
instance_c = create_instance_with_tag("other value*")
instance_d = create_instance_with_tag("other value**")
instance_e = create_instance_with_tag("other value*?")
image = instance_a.create_image(Name="test-ami", Description="this is a test ami")
image.create_tags(Tags=[{"Key": "an image key", "Value": "some value"}])
def filter_by_value(query, expected):
filter = {"Name": "value", "Values": [query]}
tags = client.describe_tags(Filters=[filter])["Tags"]
set([t["ResourceId"] for t in tags]).should.equal(set(expected))
filter_by_value("some value", [instance_a.id, image.id])
filter_by_value("some*value", [instance_a.id, instance_b.id, image.id])
filter_by_value("*some*value", [instance_a.id, instance_b.id, image.id])
filter_by_value("*some*value*", [instance_a.id, instance_b.id, image.id])
filter_by_value("*value\*", [instance_c.id])
filter_by_value("*value\*\*", [instance_d.id])
filter_by_value("*value\*\?", [instance_e.id])
# Has boto3 equivalent
@mock_ec2_deprecated
def test_retrieved_instances_must_contain_their_tags():
tag_key = "Tag name"
@ -329,6 +583,33 @@ def test_retrieved_instances_must_contain_their_tags():
retrieved_tags[tag_key].should.equal(tag_value)
@mock_ec2
def test_retrieved_instances_must_contain_their_tags_boto3():
tag_key = "Tag name"
tag_value = "Tag value"
tags_to_be_set = {"Key": tag_key, "Value": tag_value}
ec2 = boto3.resource("ec2", region_name="us-east-1")
client = boto3.client("ec2", region_name="us-east-1")
instance = ec2.create_instances(ImageId=EXAMPLE_AMI_ID, MinCount=1, MaxCount=1)[0]
reservations = client.describe_instances()["Reservations"]
reservations.should.have.length_of(1)
instances = reservations[0]["Instances"]
instances.should.have.length_of(1)
instances[0]["InstanceId"].should.equal(instance.id)
instances[0].shouldnt.have.key("Tags")
client.create_tags(Resources=[instance.id], Tags=[tags_to_be_set])
reservations = client.describe_instances()["Reservations"]
instance = reservations[0]["Instances"][0]
retrieved_tags = instance["Tags"]
# Check whether tag is present with correct value
retrieved_tags.should.equal([{"Key": tag_key, "Value": tag_value}])
# Has boto3 equivalent
@mock_ec2_deprecated
def test_retrieved_volumes_must_contain_their_tags():
tag_key = "Tag name"
@ -352,6 +633,24 @@ def test_retrieved_volumes_must_contain_their_tags():
retrieved_tags[tag_key].should.equal(tag_value)
@mock_ec2
def test_retrieved_volumes_must_contain_their_tags_boto3():
tag_key = "Tag name"
tag_value = "Tag value"
tags_to_be_set = {"Key": tag_key, "Value": tag_value}
ec2 = boto3.resource("ec2", region_name="eu-west-1")
client = boto3.client("ec2", region_name="eu-west-1")
volume = ec2.create_volume(Size=80, AvailabilityZone="us-east-1a")
volume.tags.should.be.none
client.create_tags(Resources=[volume.id], Tags=[tags_to_be_set])
volume.reload()
volume.tags.should.equal([{"Key": tag_key, "Value": tag_value}])
# Has boto3 equivalent
@mock_ec2_deprecated
def test_retrieved_snapshots_must_contain_their_tags():
tag_key = "Tag name"
@ -376,6 +675,24 @@ def test_retrieved_snapshots_must_contain_their_tags():
retrieved_tags[tag_key].should.equal(tag_value)
@mock_ec2
def test_retrieved_snapshots_must_contain_their_tags_boto3():
tag_key = "Tag name"
tag_value = "Tag value"
tags_to_be_set = {"Key": tag_key, "Value": tag_value}
ec2 = boto3.resource("ec2", region_name="eu-west-1")
client = boto3.client("ec2", region_name="eu-west-1")
volume = ec2.create_volume(Size=80, AvailabilityZone="eu-west-1a")
snapshot = ec2.create_snapshot(VolumeId=volume.id)
client.create_tags(Resources=[snapshot.id], Tags=[tags_to_be_set])
snapshot = client.describe_snapshots(SnapshotIds=[snapshot.id])["Snapshots"][0]
snapshot["Tags"].should.equal([{"Key": tag_key, "Value": tag_value}])
# Has boto3 equivalent
@mock_ec2_deprecated
def test_filter_instances_by_wildcard_tags():
conn = boto.connect_ec2(
@ -398,6 +715,36 @@ def test_filter_instances_by_wildcard_tags():
reservations.should.have.length_of(2)
@mock_ec2
def test_filter_instances_by_wildcard_tags_boto3():
ec2 = boto3.resource("ec2", region_name="eu-west-1")
client = boto3.client("ec2", region_name="eu-west-1")
reservations = ec2.create_instances(ImageId=EXAMPLE_AMI_ID, MinCount=2, MaxCount=2)
instance_a, instance_b = reservations
instance_a.create_tags(Tags=[{"Key": "Key1", "Value": "Value1"}])
instance_b.create_tags(Tags=[{"Key": "Key1", "Value": "Value2"}])
res = client.describe_instances(
Filters=[{"Name": "tag:Key1", "Values": ["Value*"]}]
)
res["Reservations"][0]["Instances"].should.have.length_of(2)
res = client.describe_instances(Filters=[{"Name": "tag-key", "Values": ["Key*"]}])
res["Reservations"][0]["Instances"].should.have.length_of(2)
res = client.describe_instances(
Filters=[{"Name": "tag-value", "Values": ["Value*"]}]
)
res["Reservations"][0]["Instances"].should.have.length_of(2)
res = client.describe_instances(
Filters=[{"Name": "tag-value", "Values": ["Value2*"]}]
)
res["Reservations"][0]["Instances"].should.have.length_of(1)
@mock_ec2
def test_create_volume_with_tags():
client = boto3.client("ec2", "us-west-2")

View File

@ -1,276 +1,390 @@
from __future__ import unicode_literals
import boto
import boto3
import pytest
import sure # noqa
from moto import mock_ec2_deprecated, mock_ec2
from botocore.exceptions import ClientError
@mock_ec2_deprecated
def test_virtual_private_gateways():
conn = boto.connect_vpc("the_key", "the_secret")
vpn_gateway = conn.create_vpn_gateway("ipsec.1", "us-east-1a")
vpn_gateway.should_not.be.none
vpn_gateway.id.should.match(r"vgw-\w+")
vpn_gateway.type.should.equal("ipsec.1")
vpn_gateway.state.should.equal("available")
vpn_gateway.availability_zone.should.equal("us-east-1a")
@mock_ec2_deprecated
def test_describe_vpn_gateway():
conn = boto.connect_vpc("the_key", "the_secret")
vpn_gateway = conn.create_vpn_gateway("ipsec.1", "us-east-1a")
vgws = conn.get_all_vpn_gateways()
vgws.should.have.length_of(1)
gateway = vgws[0]
gateway.id.should.match(r"vgw-\w+")
gateway.id.should.equal(vpn_gateway.id)
vpn_gateway.type.should.equal("ipsec.1")
vpn_gateway.state.should.equal("available")
vpn_gateway.availability_zone.should.equal("us-east-1a")
@mock_ec2
def test_attach_unknown_vpn_gateway():
"""describe_vpn_gateways attachment.vpc-id filter"""
ec2 = boto3.client("ec2", region_name="us-east-1")
vpc = ec2.create_vpc(CidrBlock="10.0.0.0/16")["Vpc"]
with pytest.raises(ClientError) as ex:
ec2.attach_vpn_gateway(VpcId=vpc["VpcId"], VpnGatewayId="?")
err = ex.value.response["Error"]
err["Message"].should.equal("The virtual private gateway ID '?' does not exist")
err["Code"].should.equal("InvalidVpnGatewayID.NotFound")
@mock_ec2
def test_delete_unknown_vpn_gateway():
"""describe_vpn_gateways attachment.vpc-id filter"""
ec2 = boto3.client("ec2", region_name="us-east-1")
with pytest.raises(ClientError) as ex:
ec2.delete_vpn_gateway(VpnGatewayId="?")
err = ex.value.response["Error"]
err["Message"].should.equal("The virtual private gateway ID '?' does not exist")
err["Code"].should.equal("InvalidVpnGatewayID.NotFound")
@mock_ec2
def test_detach_unknown_vpn_gateway():
"""describe_vpn_gateways attachment.vpc-id filter"""
ec2 = boto3.client("ec2", region_name="us-east-1")
vpc = ec2.create_vpc(CidrBlock="10.0.0.0/16")["Vpc"]
with pytest.raises(ClientError) as ex:
ec2.detach_vpn_gateway(VpcId=vpc["VpcId"], VpnGatewayId="?")
err = ex.value.response["Error"]
err["Message"].should.equal("The virtual private gateway ID '?' does not exist")
err["Code"].should.equal("InvalidVpnGatewayID.NotFound")
@mock_ec2
def test_describe_vpn_connections_attachment_vpc_id_filter():
"""describe_vpn_gateways attachment.vpc-id filter"""
ec2 = boto3.client("ec2", region_name="us-east-1")
vpc = ec2.create_vpc(CidrBlock="10.0.0.0/16")
vpc_id = vpc["Vpc"]["VpcId"]
gateway = ec2.create_vpn_gateway(AvailabilityZone="us-east-1a", Type="ipsec.1")
gateway_id = gateway["VpnGateway"]["VpnGatewayId"]
ec2.attach_vpn_gateway(VpcId=vpc_id, VpnGatewayId=gateway_id)
gateways = ec2.describe_vpn_gateways(
Filters=[{"Name": "attachment.vpc-id", "Values": [vpc_id]}]
)
gateways["VpnGateways"].should.have.length_of(1)
gateways["VpnGateways"][0]["VpnGatewayId"].should.equal(gateway_id)
gateways["VpnGateways"][0]["VpcAttachments"].should.contain(
{"State": "attached", "VpcId": vpc_id}
)
@mock_ec2
def test_describe_vpn_connections_state_filter_attached():
"""describe_vpn_gateways attachment.state filter - match attached"""
ec2 = boto3.client("ec2", region_name="us-east-1")
vpc = ec2.create_vpc(CidrBlock="10.0.0.0/16")
vpc_id = vpc["Vpc"]["VpcId"]
gateway = ec2.create_vpn_gateway(AvailabilityZone="us-east-1a", Type="ipsec.1")
gateway_id = gateway["VpnGateway"]["VpnGatewayId"]
ec2.attach_vpn_gateway(VpcId=vpc_id, VpnGatewayId=gateway_id)
gateways = ec2.describe_vpn_gateways(
Filters=[{"Name": "attachment.state", "Values": ["attached"]}]
)
gateways["VpnGateways"].should.have.length_of(1)
gateways["VpnGateways"][0]["VpnGatewayId"].should.equal(gateway_id)
gateways["VpnGateways"][0]["VpcAttachments"].should.contain(
{"State": "attached", "VpcId": vpc_id}
)
@mock_ec2
def test_describe_vpn_connections_state_filter_deatched():
"""describe_vpn_gateways attachment.state filter - don't match detatched"""
ec2 = boto3.client("ec2", region_name="us-east-1")
vpc = ec2.create_vpc(CidrBlock="10.0.0.0/16")
vpc_id = vpc["Vpc"]["VpcId"]
gateway = ec2.create_vpn_gateway(AvailabilityZone="us-east-1a", Type="ipsec.1")
gateway_id = gateway["VpnGateway"]["VpnGatewayId"]
ec2.attach_vpn_gateway(VpcId=vpc_id, VpnGatewayId=gateway_id)
gateways = ec2.describe_vpn_gateways(
Filters=[{"Name": "attachment.state", "Values": ["detached"]}]
)
gateways["VpnGateways"].should.have.length_of(0)
@mock_ec2
def test_describe_vpn_connections_id_filter_match():
"""describe_vpn_gateways vpn-gateway-id filter - match correct id"""
ec2 = boto3.client("ec2", region_name="us-east-1")
gateway = ec2.create_vpn_gateway(AvailabilityZone="us-east-1a", Type="ipsec.1")
gateway_id = gateway["VpnGateway"]["VpnGatewayId"]
gateways = ec2.describe_vpn_gateways(
Filters=[{"Name": "vpn-gateway-id", "Values": [gateway_id]}]
)
gateways["VpnGateways"].should.have.length_of(1)
gateways["VpnGateways"][0]["VpnGatewayId"].should.equal(gateway_id)
@mock_ec2
def test_describe_vpn_connections_id_filter_miss():
"""describe_vpn_gateways vpn-gateway-id filter - don't match"""
ec2 = boto3.client("ec2", region_name="us-east-1")
ec2.create_vpn_gateway(AvailabilityZone="us-east-1a", Type="ipsec.1")
gateways = ec2.describe_vpn_gateways(
Filters=[{"Name": "vpn-gateway-id", "Values": ["unknown_gateway_id"]}]
)
gateways["VpnGateways"].should.have.length_of(0)
@mock_ec2
def test_describe_vpn_connections_type_filter_match():
"""describe_vpn_gateways type filter - match"""
ec2 = boto3.client("ec2", region_name="us-east-1")
gateway = ec2.create_vpn_gateway(AvailabilityZone="us-east-1a", Type="ipsec.1")
gateway_id = gateway["VpnGateway"]["VpnGatewayId"]
gateways = ec2.describe_vpn_gateways(
Filters=[{"Name": "type", "Values": ["ipsec.1"]}]
)
gateways["VpnGateways"].should.have.length_of(1)
gateways["VpnGateways"][0]["VpnGatewayId"].should.equal(gateway_id)
@mock_ec2
def test_describe_vpn_connections_type_filter_miss():
"""describe_vpn_gateways type filter - don't match"""
ec2 = boto3.client("ec2", region_name="us-east-1")
ec2.create_vpn_gateway(AvailabilityZone="us-east-1a", Type="ipsec.1")
gateways = ec2.describe_vpn_gateways(
Filters=[{"Name": "type", "Values": ["unknown_type"]}]
)
gateways["VpnGateways"].should.have.length_of(0)
@mock_ec2_deprecated
def test_vpn_gateway_vpc_attachment():
conn = boto.connect_vpc("the_key", "the_secret")
vpc = conn.create_vpc("10.0.0.0/16")
vpn_gateway = conn.create_vpn_gateway("ipsec.1", "us-east-1a")
conn.attach_vpn_gateway(vpn_gateway_id=vpn_gateway.id, vpc_id=vpc.id)
gateway = conn.get_all_vpn_gateways()[0]
attachments = gateway.attachments
attachments.should.have.length_of(1)
attachments[0].vpc_id.should.equal(vpc.id)
attachments[0].state.should.equal("attached")
@mock_ec2_deprecated
def test_delete_vpn_gateway():
conn = boto.connect_vpc("the_key", "the_secret")
vpn_gateway = conn.create_vpn_gateway("ipsec.1", "us-east-1a")
conn.delete_vpn_gateway(vpn_gateway.id)
vgws = conn.get_all_vpn_gateways()
vgws.should.have.length_of(1)
vgws[0].state.should.equal("deleted")
@mock_ec2_deprecated
def test_vpn_gateway_tagging():
conn = boto.connect_vpc("the_key", "the_secret")
vpn_gateway = conn.create_vpn_gateway("ipsec.1", "us-east-1a")
vpn_gateway.add_tag("a key", "some value")
tag = conn.get_all_tags()[0]
tag.name.should.equal("a key")
tag.value.should.equal("some value")
# Refresh the subnet
vpn_gateway = conn.get_all_vpn_gateways()[0]
vpn_gateway.tags.should.have.length_of(1)
vpn_gateway.tags["a key"].should.equal("some value")
@mock_ec2_deprecated
def test_detach_vpn_gateway():
conn = boto.connect_vpc("the_key", "the_secret")
vpc = conn.create_vpc("10.0.0.0/16")
vpn_gateway = conn.create_vpn_gateway("ipsec.1", "us-east-1a")
conn.attach_vpn_gateway(vpn_gateway_id=vpn_gateway.id, vpc_id=vpc.id)
gateway = conn.get_all_vpn_gateways()[0]
attachments = gateway.attachments
attachments.should.have.length_of(1)
attachments[0].vpc_id.should.equal(vpc.id)
attachments[0].state.should.equal("attached")
conn.detach_vpn_gateway(vpn_gateway_id=vpn_gateway.id, vpc_id=vpc.id)
gateway = conn.get_all_vpn_gateways()[0]
attachments = gateway.attachments
attachments.should.have.length_of(1)
attachments[0].state.should.equal("detached")
from __future__ import unicode_literals
import boto
import boto3
import pytest
import sure # noqa
from moto import mock_ec2_deprecated, mock_ec2
from botocore.exceptions import ClientError
@mock_ec2
def test_attach_unknown_vpn_gateway():
"""describe_vpn_gateways attachment.vpc-id filter"""
ec2 = boto3.client("ec2", region_name="us-east-1")
vpc = ec2.create_vpc(CidrBlock="10.0.0.0/16")["Vpc"]
with pytest.raises(ClientError) as ex:
ec2.attach_vpn_gateway(VpcId=vpc["VpcId"], VpnGatewayId="?")
err = ex.value.response["Error"]
err["Message"].should.equal("The virtual private gateway ID '?' does not exist")
err["Code"].should.equal("InvalidVpnGatewayID.NotFound")
@mock_ec2
def test_delete_unknown_vpn_gateway():
"""describe_vpn_gateways attachment.vpc-id filter"""
ec2 = boto3.client("ec2", region_name="us-east-1")
with pytest.raises(ClientError) as ex:
ec2.delete_vpn_gateway(VpnGatewayId="?")
err = ex.value.response["Error"]
err["Message"].should.equal("The virtual private gateway ID '?' does not exist")
err["Code"].should.equal("InvalidVpnGatewayID.NotFound")
@mock_ec2
def test_detach_unknown_vpn_gateway():
"""describe_vpn_gateways attachment.vpc-id filter"""
ec2 = boto3.client("ec2", region_name="us-east-1")
vpc = ec2.create_vpc(CidrBlock="10.0.0.0/16")["Vpc"]
with pytest.raises(ClientError) as ex:
ec2.detach_vpn_gateway(VpcId=vpc["VpcId"], VpnGatewayId="?")
err = ex.value.response["Error"]
err["Message"].should.equal("The virtual private gateway ID '?' does not exist")
err["Code"].should.equal("InvalidVpnGatewayID.NotFound")
@mock_ec2
def test_describe_vpn_connections_attachment_vpc_id_filter():
"""describe_vpn_gateways attachment.vpc-id filter"""
ec2 = boto3.client("ec2", region_name="us-east-1")
vpc = ec2.create_vpc(CidrBlock="10.0.0.0/16")
vpc_id = vpc["Vpc"]["VpcId"]
gateway = ec2.create_vpn_gateway(AvailabilityZone="us-east-1a", Type="ipsec.1")
gateway_id = gateway["VpnGateway"]["VpnGatewayId"]
ec2.attach_vpn_gateway(VpcId=vpc_id, VpnGatewayId=gateway_id)
gateways = ec2.describe_vpn_gateways(
Filters=[{"Name": "attachment.vpc-id", "Values": [vpc_id]}]
)
gateways["VpnGateways"].should.have.length_of(1)
gateways["VpnGateways"][0]["VpnGatewayId"].should.equal(gateway_id)
gateways["VpnGateways"][0]["VpcAttachments"].should.contain(
{"State": "attached", "VpcId": vpc_id}
)
@mock_ec2
def test_describe_vpn_connections_state_filter_deatched():
"""describe_vpn_gateways attachment.state filter - don't match detatched"""
ec2 = boto3.client("ec2", region_name="us-east-1")
vpc = ec2.create_vpc(CidrBlock="10.0.0.0/16")
vpc_id = vpc["Vpc"]["VpcId"]
gateway = ec2.create_vpn_gateway(AvailabilityZone="us-east-1a", Type="ipsec.1")
gateway_id = gateway["VpnGateway"]["VpnGatewayId"]
ec2.attach_vpn_gateway(VpcId=vpc_id, VpnGatewayId=gateway_id)
gateways = ec2.describe_vpn_gateways(
Filters=[{"Name": "attachment.state", "Values": ["detached"]}]
)
gateways["VpnGateways"].should.have.length_of(0)
# Has boto3 equivalent
@mock_ec2_deprecated
def test_virtual_private_gateways():
conn = boto.connect_vpc("the_key", "the_secret")
vpn_gateway = conn.create_vpn_gateway("ipsec.1", "us-east-1a")
vpn_gateway.should_not.be.none
vpn_gateway.id.should.match(r"vgw-\w+")
vpn_gateway.type.should.equal("ipsec.1")
vpn_gateway.state.should.equal("available")
vpn_gateway.availability_zone.should.equal("us-east-1a")
@mock_ec2
def test_virtual_private_gateways_boto3():
client = boto3.client("ec2", region_name="us-west-1")
vpn_gateway = client.create_vpn_gateway(
Type="ipsec.1", AvailabilityZone="us-east-1a"
)["VpnGateway"]
vpn_gateway["VpnGatewayId"].should.match(r"vgw-\w+")
vpn_gateway["Type"].should.equal("ipsec.1")
vpn_gateway["State"].should.equal("available")
vpn_gateway["AvailabilityZone"].should.equal("us-east-1a")
# Has boto3 equivalent
@mock_ec2_deprecated
def test_describe_vpn_gateway():
conn = boto.connect_vpc("the_key", "the_secret")
vpn_gateway = conn.create_vpn_gateway("ipsec.1", "us-east-1a")
vgws = conn.get_all_vpn_gateways()
vgws.should.have.length_of(1)
gateway = vgws[0]
gateway.id.should.match(r"vgw-\w+")
gateway.id.should.equal(vpn_gateway.id)
vpn_gateway.type.should.equal("ipsec.1")
vpn_gateway.state.should.equal("available")
vpn_gateway.availability_zone.should.equal("us-east-1a")
@mock_ec2
def test_describe_vpn_gateway_boto3():
client = boto3.client("ec2", region_name="us-west-1")
vpn_gateway = client.create_vpn_gateway(
Type="ipsec.1", AvailabilityZone="us-east-1a"
)["VpnGateway"]
vgws = client.describe_vpn_gateways()["VpnGateways"]
vgws.should.have.length_of(1)
gateway = vgws[0]
gateway["VpnGatewayId"].should.match(r"vgw-\w+")
gateway["VpnGatewayId"].should.equal(vpn_gateway["VpnGatewayId"])
# TODO: fixme. This currently returns the ID
# gateway["Type"].should.equal("ipsec.1")
gateway["State"].should.equal("available")
gateway["AvailabilityZone"].should.equal("us-east-1a")
@mock_ec2
def test_describe_vpn_connections_state_filter_attached():
""" describe_vpn_gateways attachment.state filter - match attached """
ec2 = boto3.client("ec2", region_name="us-east-1")
vpc = ec2.create_vpc(CidrBlock="10.0.0.0/16")
vpc_id = vpc["Vpc"]["VpcId"]
gateway = ec2.create_vpn_gateway(AvailabilityZone="us-east-1a", Type="ipsec.1")
gateway_id = gateway["VpnGateway"]["VpnGatewayId"]
ec2.attach_vpn_gateway(VpcId=vpc_id, VpnGatewayId=gateway_id)
gateways = ec2.describe_vpn_gateways(
Filters=[{"Name": "attachment.state", "Values": ["attached"]}]
)
gateways["VpnGateways"].should.have.length_of(1)
gateways["VpnGateways"][0]["VpnGatewayId"].should.equal(gateway_id)
gateways["VpnGateways"][0]["VpcAttachments"].should.contain(
{"State": "attached", "VpcId": vpc_id}
)
@mock_ec2
def test_describe_vpn_connections_id_filter_match():
""" describe_vpn_gateways vpn-gateway-id filter - match correct id """
ec2 = boto3.client("ec2", region_name="us-east-1")
gateway = ec2.create_vpn_gateway(AvailabilityZone="us-east-1a", Type="ipsec.1")
gateway_id = gateway["VpnGateway"]["VpnGatewayId"]
gateways = ec2.describe_vpn_gateways(
Filters=[{"Name": "vpn-gateway-id", "Values": [gateway_id]}]
)
gateways["VpnGateways"].should.have.length_of(1)
gateways["VpnGateways"][0]["VpnGatewayId"].should.equal(gateway_id)
@mock_ec2
def test_describe_vpn_connections_id_filter_miss():
""" describe_vpn_gateways vpn-gateway-id filter - don't match """
ec2 = boto3.client("ec2", region_name="us-east-1")
ec2.create_vpn_gateway(AvailabilityZone="us-east-1a", Type="ipsec.1")
gateways = ec2.describe_vpn_gateways(
Filters=[{"Name": "vpn-gateway-id", "Values": ["unknown_gateway_id"]}]
)
gateways["VpnGateways"].should.have.length_of(0)
@mock_ec2
def test_describe_vpn_connections_type_filter_match():
""" describe_vpn_gateways type filter - match """
ec2 = boto3.client("ec2", region_name="us-east-1")
gateway = ec2.create_vpn_gateway(AvailabilityZone="us-east-1a", Type="ipsec.1")
gateway_id = gateway["VpnGateway"]["VpnGatewayId"]
gateways = ec2.describe_vpn_gateways(
Filters=[{"Name": "type", "Values": ["ipsec.1"]}]
)
gateways["VpnGateways"].should.have.length_of(1)
gateways["VpnGateways"][0]["VpnGatewayId"].should.equal(gateway_id)
@mock_ec2
def test_describe_vpn_connections_type_filter_miss():
""" describe_vpn_gateways type filter - don't match """
ec2 = boto3.client("ec2", region_name="us-east-1")
ec2.create_vpn_gateway(AvailabilityZone="us-east-1a", Type="ipsec.1")
gateways = ec2.describe_vpn_gateways(
Filters=[{"Name": "type", "Values": ["unknown_type"]}]
)
gateways["VpnGateways"].should.have.length_of(0)
# Has boto3 equivalent
@mock_ec2_deprecated
def test_vpn_gateway_vpc_attachment():
conn = boto.connect_vpc("the_key", "the_secret")
vpc = conn.create_vpc("10.0.0.0/16")
vpn_gateway = conn.create_vpn_gateway("ipsec.1", "us-east-1a")
conn.attach_vpn_gateway(vpn_gateway_id=vpn_gateway.id, vpc_id=vpc.id)
gateway = conn.get_all_vpn_gateways()[0]
attachments = gateway.attachments
attachments.should.have.length_of(1)
attachments[0].vpc_id.should.equal(vpc.id)
attachments[0].state.should.equal("attached")
@mock_ec2
def test_vpn_gateway_vpc_attachment_boto3():
ec2 = boto3.resource("ec2", region_name="us-west-1")
client = boto3.client("ec2", region_name="us-west-1")
vpc = ec2.create_vpc(CidrBlock="10.0.0.0/16")
vpn_gateway = client.create_vpn_gateway(
Type="ipsec.1", AvailabilityZone="us-east-1a"
)["VpnGateway"]
client.attach_vpn_gateway(VpnGatewayId=vpn_gateway["VpnGatewayId"], VpcId=vpc.id)
gateway = client.describe_vpn_gateways()["VpnGateways"][0]
attachments = gateway["VpcAttachments"]
attachments.should.equal([{"State": "attached", "VpcId": vpc.id}])
# Has boto3 equivalent
@mock_ec2_deprecated
def test_delete_vpn_gateway():
conn = boto.connect_vpc("the_key", "the_secret")
vpn_gateway = conn.create_vpn_gateway("ipsec.1", "us-east-1a")
conn.delete_vpn_gateway(vpn_gateway.id)
vgws = conn.get_all_vpn_gateways()
vgws.should.have.length_of(1)
vgws[0].state.should.equal("deleted")
@mock_ec2
def test_delete_vpn_gateway_boto3():
ec2 = boto3.resource("ec2", region_name="us-west-1")
client = boto3.client("ec2", region_name="us-west-1")
vpn_gateway = client.create_vpn_gateway(
Type="ipsec.1", AvailabilityZone="us-east-1a"
)["VpnGateway"]
client.delete_vpn_gateway(VpnGatewayId=vpn_gateway["VpnGatewayId"])
gateways = client.describe_vpn_gateways()["VpnGateways"]
gateways.should.have.length_of(1)
gateways[0].should.have.key("State").equal("deleted")
# Has boto3 equivalent
@mock_ec2_deprecated
def test_vpn_gateway_tagging():
conn = boto.connect_vpc("the_key", "the_secret")
vpn_gateway = conn.create_vpn_gateway("ipsec.1", "us-east-1a")
vpn_gateway.add_tag("a key", "some value")
tag = conn.get_all_tags()[0]
tag.name.should.equal("a key")
tag.value.should.equal("some value")
# Refresh the subnet
vpn_gateway = conn.get_all_vpn_gateways()[0]
vpn_gateway.tags.should.have.length_of(1)
vpn_gateway.tags["a key"].should.equal("some value")
@mock_ec2
def test_vpn_gateway_tagging_boto3():
ec2 = boto3.resource("ec2", region_name="us-west-1")
client = boto3.client("ec2", region_name="us-west-1")
vpn_gateway = client.create_vpn_gateway(
Type="ipsec.1", AvailabilityZone="us-east-1a"
)["VpnGateway"]
client.create_tags(
Resources=[vpn_gateway["VpnGatewayId"]],
Tags=[{"Key": "a key", "Value": "some value"}],
)
tag = client.describe_tags()["Tags"][0]
tag.should.have.key("Key").equal("a key")
tag.should.have.key("Value").equal("some value")
vpn_gateway = client.describe_vpn_gateways()["VpnGateways"][0]
# TODO: Fixme: Tags is currently empty
# vpn_gateway["Tags"].should.equal([{'Key': 'a key', 'Value': 'some value'}])
# Has boto3 equivalent
@mock_ec2_deprecated
def test_detach_vpn_gateway():
conn = boto.connect_vpc("the_key", "the_secret")
vpc = conn.create_vpc("10.0.0.0/16")
vpn_gateway = conn.create_vpn_gateway("ipsec.1", "us-east-1a")
conn.attach_vpn_gateway(vpn_gateway_id=vpn_gateway.id, vpc_id=vpc.id)
gateway = conn.get_all_vpn_gateways()[0]
attachments = gateway.attachments
attachments.should.have.length_of(1)
attachments[0].vpc_id.should.equal(vpc.id)
attachments[0].state.should.equal("attached")
conn.detach_vpn_gateway(vpn_gateway_id=vpn_gateway.id, vpc_id=vpc.id)
gateway = conn.get_all_vpn_gateways()[0]
attachments = gateway.attachments
attachments.should.have.length_of(1)
attachments[0].state.should.equal("detached")
@mock_ec2
def test_detach_vpn_gateway_boto3():
ec2 = boto3.resource("ec2", region_name="us-west-1")
client = boto3.client("ec2", region_name="us-west-1")
vpc = ec2.create_vpc(CidrBlock="10.0.0.0/16")
vpn_gateway = client.create_vpn_gateway(
Type="ipsec.1", AvailabilityZone="us-east-1a"
)
vpn_gateway = vpn_gateway["VpnGateway"]
client.attach_vpn_gateway(VpnGatewayId=vpn_gateway["VpnGatewayId"], VpcId=vpc.id)
gateway = client.describe_vpn_gateways()["VpnGateways"][0]
attachments = gateway["VpcAttachments"]
attachments.should.equal([{"State": "attached", "VpcId": vpc.id}])
client.detach_vpn_gateway(VpnGatewayId=vpn_gateway["VpnGatewayId"], VpcId=vpc.id)
gateway = client.describe_vpn_gateways()["VpnGateways"][0]
attachments = gateway["VpcAttachments"]
attachments.should.equal([{"State": "detached", "VpcId": vpc.id}])

View File

@ -13,6 +13,7 @@ from moto import mock_ec2, mock_ec2_deprecated
from tests.helpers import requires_boto_gte
# Has boto3 equivalent
@requires_boto_gte("2.32.0")
@mock_ec2_deprecated
def test_vpc_peering_connections():
@ -26,6 +27,26 @@ def test_vpc_peering_connections():
return vpc_pcx
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)
vpc_pcx.should.have.key("VpcPeeringConnectionId")
vpc_pcx["Status"]["Code"].should.equal("initiating-request")
# Has boto3 equivalent
@requires_boto_gte("2.32.0")
@mock_ec2_deprecated
def test_vpc_peering_connections_get_all():
@ -38,6 +59,18 @@ def test_vpc_peering_connections_get_all():
all_vpc_pcxs[0]._status.code.should.equal("pending-acceptance")
@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)
all_vpc_pcxs = client.describe_vpc_peering_connections()["VpcPeeringConnections"]
all_vpc_pcxs.should.have.length_of(1)
all_vpc_pcxs[0]["Status"]["Code"].should.equal("pending-acceptance")
# Has boto3 equivalent
@requires_boto_gte("2.32.0")
@mock_ec2_deprecated
def test_vpc_peering_connections_accept():
@ -58,6 +91,29 @@ def test_vpc_peering_connections_accept():
all_vpc_pcxs[0]._status.code.should.equal("active")
@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"]
vpc_pcx["Status"]["Code"].should.equal("active")
with pytest.raises(ClientError) as ex:
client.reject_vpc_peering_connection(VpcPeeringConnectionId=vpc_pcx_id)
ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
ex.value.response["ResponseMetadata"].should.have.key("RequestId")
ex.value.response["Error"]["Code"].should.equal("InvalidStateTransition")
all_vpc_pcxs = client.describe_vpc_peering_connections()["VpcPeeringConnections"]
all_vpc_pcxs.should.have.length_of(1)
all_vpc_pcxs[0]["Status"]["Code"].should.equal("active")
# Has boto3 equivalent
@requires_boto_gte("2.32.0")
@mock_ec2_deprecated
def test_vpc_peering_connections_reject():
@ -78,6 +134,27 @@ def test_vpc_peering_connections_reject():
all_vpc_pcxs[0]._status.code.should.equal("rejected")
@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)
ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
ex.value.response["ResponseMetadata"].should.have.key("RequestId")
ex.value.response["Error"]["Code"].should.equal("InvalidStateTransition")
all_vpc_pcxs = client.describe_vpc_peering_connections()["VpcPeeringConnections"]
all_vpc_pcxs.should.have.length_of(1)
all_vpc_pcxs[0]["Status"]["Code"].should.equal("rejected")
# Has boto3 equivalent
@requires_boto_gte("2.32.1")
@mock_ec2_deprecated
def test_vpc_peering_connections_delete():
@ -98,6 +175,28 @@ def test_vpc_peering_connections_delete():
cm.value.request_id.should_not.be.none
@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 = client.describe_vpc_peering_connections()["VpcPeeringConnections"]
all_vpc_pcxs.should.have.length_of(1)
all_vpc_pcxs[0]["Status"]["Code"].should.equal("deleted")
with pytest.raises(ClientError) as ex:
client.delete_vpc_peering_connection(VpcPeeringConnectionId="pcx-1234abcd")
ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
ex.value.response["ResponseMetadata"].should.have.key("RequestId")
ex.value.response["Error"]["Code"].should.equal(
"InvalidVpcPeeringConnectionId.NotFound"
)
@mock_ec2
def test_vpc_peering_connections_cross_region():
# create vpc in us-west-1 and ap-northeast-1

View File

@ -16,6 +16,7 @@ SAMPLE_DOMAIN_NAME = "example.com"
SAMPLE_NAME_SERVERS = ["10.0.0.6", "10.0.0.7"]
# Has boto3 equivalent
@mock_ec2_deprecated
def test_vpcs():
conn = boto.connect_vpc("the_key", "the_secret")
@ -37,6 +38,29 @@ def test_vpcs():
cm.value.request_id.should_not.be.none
@mock_ec2
def test_create_and_delete_vpc():
ec2 = boto3.resource("ec2", region_name="eu-north-1")
client = boto3.client("ec2", region_name="eu-north-1")
vpc = ec2.create_vpc(CidrBlock="10.0.0.0/16")
vpc.cidr_block.should.equal("10.0.0.0/16")
all_vpcs = client.describe_vpcs()["Vpcs"]
all_vpcs.should.have.length_of(2)
vpc.delete()
all_vpcs = client.describe_vpcs()["Vpcs"]
all_vpcs.should.have.length_of(1)
with pytest.raises(ClientError) as ex:
client.delete_vpc(VpcId="vpc-1234abcd")
ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
ex.value.response["ResponseMetadata"].should.have.key("RequestId")
ex.value.response["Error"]["Code"].should.equal("InvalidVpcID.NotFound")
# Has boto3 equivalent
@mock_ec2_deprecated
def test_vpc_defaults():
conn = boto.connect_vpc("the_key", "the_secret")
@ -53,6 +77,28 @@ def test_vpc_defaults():
conn.get_all_security_groups(filters={"vpc-id": [vpc.id]}).should.have.length_of(0)
@mock_ec2
def test_vpc_defaults_boto3():
ec2 = boto3.resource("ec2", region_name="eu-north-1")
client = boto3.client("ec2", region_name="eu-north-1")
vpc = ec2.create_vpc(CidrBlock="10.0.0.0/16")
client.describe_vpcs()["Vpcs"].should.have.length_of(2)
client.describe_route_tables()["RouteTables"].should.have.length_of(2)
client.describe_security_groups(Filters=[{"Name": "vpc-id", "Values": [vpc.id]}])[
"SecurityGroups"
].should.have.length_of(1)
vpc.delete()
client.describe_vpcs()["Vpcs"].should.have.length_of(1)
client.describe_route_tables()["RouteTables"].should.have.length_of(1)
client.describe_security_groups(Filters=[{"Name": "vpc-id", "Values": [vpc.id]}])[
"SecurityGroups"
].should.have.length_of(0)
# Has boto3 equivalent
@mock_ec2_deprecated
def test_vpc_isdefault_filter():
conn = boto.connect_vpc("the_key", "the_secret")
@ -62,6 +108,23 @@ def test_vpc_isdefault_filter():
conn.get_all_vpcs(filters={"isDefault": "true"}).should.have.length_of(1)
@mock_ec2
def test_vpc_isdefault_filter_boto3():
ec2 = boto3.resource("ec2", region_name="eu-west-1")
client = boto3.client("ec2", region_name="eu-west-1")
vpc = ec2.create_vpc(CidrBlock="10.0.0.0/16")
client.describe_vpcs(Filters=[{"Name": "isDefault", "Values": ["true"]}])[
"Vpcs"
].should.have.length_of(1)
vpc.delete()
client.describe_vpcs(Filters=[{"Name": "isDefault", "Values": ["true"]}])[
"Vpcs"
].should.have.length_of(1)
# Has boto3 equivalent
@mock_ec2_deprecated
def test_multiple_vpcs_default_filter():
conn = boto.connect_vpc("the_key", "the_secret")
@ -74,6 +137,22 @@ def test_multiple_vpcs_default_filter():
vpc[0].cidr_block.should.equal("172.31.0.0/16")
@mock_ec2
def test_multiple_vpcs_default_filter_boto3():
ec2 = boto3.resource("ec2", region_name="eu-west-1")
client = boto3.client("ec2", region_name="eu-west-1")
ec2.create_vpc(CidrBlock="10.8.0.0/16")
ec2.create_vpc(CidrBlock="10.0.0.0/16")
ec2.create_vpc(CidrBlock="192.168.0.0/16")
client.describe_vpcs()["Vpcs"].should.have.length_of(4)
vpc = client.describe_vpcs(Filters=[{"Name": "isDefault", "Values": ["true"]}])[
"Vpcs"
]
vpc.should.have.length_of(1)
vpc[0]["CidrBlock"].should.equal("172.31.0.0/16")
# Has boto3 equivalent
@mock_ec2_deprecated
def test_vpc_state_available_filter():
conn = boto.connect_vpc("the_key", "the_secret")
@ -84,6 +163,22 @@ def test_vpc_state_available_filter():
conn.get_all_vpcs(filters={"state": "available"}).should.have.length_of(2)
@mock_ec2
def test_vpc_state_available_filter_boto3():
ec2 = boto3.resource("ec2", region_name="eu-west-1")
client = boto3.client("ec2", region_name="eu-west-1")
vpc = ec2.create_vpc(CidrBlock="10.0.0.0/16")
ec2.create_vpc(CidrBlock="10.1.0.0/16")
client.describe_vpcs(Filters=[{"Name": "state", "Values": ["available"]}])[
"Vpcs"
].should.have.length_of(3)
vpc.delete()
client.describe_vpcs(Filters=[{"Name": "state", "Values": ["available"]}])[
"Vpcs"
].should.have.length_of(2)
# Has boto3 equivalent
@mock_ec2_deprecated
def test_vpc_tagging():
conn = boto.connect_vpc()
@ -100,6 +195,23 @@ def test_vpc_tagging():
vpc.tags["a key"].should.equal("some value")
@mock_ec2
def test_vpc_tagging_boto3():
ec2 = boto3.resource("ec2", region_name="eu-west-1")
client = boto3.client("ec2", region_name="eu-west-1")
vpc = ec2.create_vpc(CidrBlock="10.0.0.0/16")
vpc.create_tags(Tags=[{"Key": "a key", "Value": "some value"}])
tag = client.describe_tags()["Tags"][0]
tag.should.have.key("Key").equal("a key")
tag.should.have.key("Value").equal("some value")
# Refresh the vpc
vpc = client.describe_vpcs(VpcIds=[vpc.id])["Vpcs"][0]
vpc["Tags"].should.equal([{"Key": "a key", "Value": "some value"}])
# Has boto3 equivalent
@mock_ec2_deprecated
def test_vpc_get_by_id():
conn = boto.connect_vpc()
@ -120,6 +232,28 @@ def test_vpc_get_by_id():
cm.value.request_id.should_not.be.none
@mock_ec2
def test_vpc_get_by_id_boto3():
ec2 = boto3.resource("ec2", region_name="eu-west-1")
client = boto3.client("ec2", region_name="eu-west-1")
vpc1 = ec2.create_vpc(CidrBlock="10.0.0.0/16")
vpc2 = ec2.create_vpc(CidrBlock="10.0.0.0/16")
ec2.create_vpc(CidrBlock="10.0.0.0/16")
vpcs = client.describe_vpcs(VpcIds=[vpc1.id, vpc2.id])["Vpcs"]
vpcs.should.have.length_of(2)
vpc_ids = tuple(map(lambda v: v["VpcId"], vpcs))
vpc1.id.should.be.within(vpc_ids)
vpc2.id.should.be.within(vpc_ids)
with pytest.raises(ClientError) as ex:
client.describe_vpcs(VpcIds=["vpc-does_not_exist"])
ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
ex.value.response["ResponseMetadata"].should.have.key("RequestId")
ex.value.response["Error"]["Code"].should.equal("InvalidVpcID.NotFound")
# Has boto3 equivalent
@mock_ec2_deprecated
def test_vpc_get_by_cidr_block():
conn = boto.connect_vpc()
@ -134,6 +268,24 @@ def test_vpc_get_by_cidr_block():
vpc2.id.should.be.within(vpc_ids)
@mock_ec2
def test_vpc_get_by_cidr_block_boto3():
ec2 = boto3.resource("ec2", region_name="eu-west-1")
client = boto3.client("ec2", region_name="eu-west-1")
vpc1 = ec2.create_vpc(CidrBlock="10.0.0.0/16")
vpc2 = ec2.create_vpc(CidrBlock="10.0.0.0/16")
ec2.create_vpc(CidrBlock="10.0.0.0/24")
vpcs = client.describe_vpcs(Filters=[{"Name": "cidr", "Values": ["10.0.0.0/16"]}])[
"Vpcs"
]
vpcs.should.have.length_of(2)
vpc_ids = tuple(map(lambda v: v["VpcId"], vpcs))
vpc1.id.should.be.within(vpc_ids)
vpc2.id.should.be.within(vpc_ids)
# Has boto3 equivalent
@mock_ec2_deprecated
def test_vpc_get_by_dhcp_options_id():
conn = boto.connect_vpc()
@ -152,6 +304,33 @@ def test_vpc_get_by_dhcp_options_id():
vpc2.id.should.be.within(vpc_ids)
@mock_ec2
def test_vpc_get_by_dhcp_options_id_boto3():
ec2 = boto3.resource("ec2", region_name="us-east-1")
client = boto3.client("ec2", region_name="us-east-1")
dhcp_options = ec2.create_dhcp_options(
DhcpConfigurations=[
{"Key": "domain-name", "Values": [SAMPLE_DOMAIN_NAME]},
{"Key": "domain-name-servers", "Values": SAMPLE_NAME_SERVERS},
]
)
vpc1 = ec2.create_vpc(CidrBlock="10.0.0.0/16")
vpc2 = ec2.create_vpc(CidrBlock="10.0.0.0/16")
ec2.create_vpc(CidrBlock="10.0.0.0/24")
client.associate_dhcp_options(DhcpOptionsId=dhcp_options.id, VpcId=vpc1.id)
client.associate_dhcp_options(DhcpOptionsId=dhcp_options.id, VpcId=vpc2.id)
vpcs = client.describe_vpcs(
Filters=[{"Name": "dhcp-options-id", "Values": [dhcp_options.id]}]
)["Vpcs"]
vpcs.should.have.length_of(2)
vpc_ids = tuple(map(lambda v: v["VpcId"], vpcs))
vpc1.id.should.be.within(vpc_ids)
vpc2.id.should.be.within(vpc_ids)
# Has boto3 equivalent
@mock_ec2_deprecated
def test_vpc_get_by_tag():
conn = boto.connect_vpc()
@ -170,6 +349,28 @@ def test_vpc_get_by_tag():
vpc2.id.should.be.within(vpc_ids)
@mock_ec2
def test_vpc_get_by_tag_boto3():
ec2 = boto3.resource("ec2", region_name="us-east-1")
client = boto3.client("ec2", region_name="us-east-1")
vpc1 = ec2.create_vpc(CidrBlock="10.0.0.0/16")
vpc2 = ec2.create_vpc(CidrBlock="10.0.0.0/16")
vpc3 = ec2.create_vpc(CidrBlock="10.0.0.0/24")
vpc1.create_tags(Tags=[{"Key": "Name", "Value": "TestVPC"}])
vpc2.create_tags(Tags=[{"Key": "Name", "Value": "TestVPC"}])
vpc3.create_tags(Tags=[{"Key": "Name", "Value": "TestVPC2"}])
vpcs = client.describe_vpcs(Filters=[{"Name": "tag:Name", "Values": ["TestVPC"]}])[
"Vpcs"
]
vpcs.should.have.length_of(2)
vpc_ids = tuple(map(lambda v: v["VpcId"], vpcs))
vpc1.id.should.be.within(vpc_ids)
vpc2.id.should.be.within(vpc_ids)
# Has boto3 equivalent
@mock_ec2_deprecated
def test_vpc_get_by_tag_key_superset():
conn = boto.connect_vpc()
@ -190,6 +391,30 @@ def test_vpc_get_by_tag_key_superset():
vpc2.id.should.be.within(vpc_ids)
@mock_ec2
def test_vpc_get_by_tag_key_superset_boto3():
ec2 = boto3.resource("ec2", region_name="us-east-1")
client = boto3.client("ec2", region_name="us-east-1")
vpc1 = ec2.create_vpc(CidrBlock="10.0.0.0/16")
vpc2 = ec2.create_vpc(CidrBlock="10.0.0.0/16")
vpc3 = ec2.create_vpc(CidrBlock="10.0.0.0/24")
vpc1.create_tags(Tags=[{"Key": "Name", "Value": "TestVPC"}])
vpc1.create_tags(Tags=[{"Key": "Key", "Value": "TestVPC2"}])
vpc2.create_tags(Tags=[{"Key": "Name", "Value": "TestVPC"}])
vpc2.create_tags(Tags=[{"Key": "Key", "Value": "TestVPC2"}])
vpc3.create_tags(Tags=[{"Key": "Key", "Value": "TestVPC2"}])
vpcs = client.describe_vpcs(Filters=[{"Name": "tag-key", "Values": ["Name"]}])[
"Vpcs"
]
vpcs.should.have.length_of(2)
vpc_ids = tuple(map(lambda v: v["VpcId"], vpcs))
vpc1.id.should.be.within(vpc_ids)
vpc2.id.should.be.within(vpc_ids)
# Has boto3 equivalent
@mock_ec2_deprecated
def test_vpc_get_by_tag_key_subset():
conn = boto.connect_vpc()
@ -210,6 +435,30 @@ def test_vpc_get_by_tag_key_subset():
vpc2.id.should.be.within(vpc_ids)
@mock_ec2
def test_vpc_get_by_tag_key_subset_boto3():
ec2 = boto3.resource("ec2", region_name="us-east-1")
client = boto3.client("ec2", region_name="us-east-1")
vpc1 = ec2.create_vpc(CidrBlock="10.0.0.0/16")
vpc2 = ec2.create_vpc(CidrBlock="10.0.0.0/16")
vpc3 = ec2.create_vpc(CidrBlock="10.0.0.0/24")
vpc1.create_tags(Tags=[{"Key": "Name", "Value": "TestVPC"}])
vpc1.create_tags(Tags=[{"Key": "Key", "Value": "TestVPC2"}])
vpc2.create_tags(Tags=[{"Key": "Name", "Value": "TestVPC"}])
vpc2.create_tags(Tags=[{"Key": "Key", "Value": "TestVPC2"}])
vpc3.create_tags(Tags=[{"Key": "Test", "Value": "TestVPC2"}])
vpcs = client.describe_vpcs(
Filters=[{"Name": "tag-key", "Values": ["Name", "Key"]}]
)["Vpcs"]
vpcs.should.have.length_of(2)
vpc_ids = tuple(map(lambda v: v["VpcId"], vpcs))
vpc1.id.should.be.within(vpc_ids)
vpc2.id.should.be.within(vpc_ids)
# Has boto3 equivalent
@mock_ec2_deprecated
def test_vpc_get_by_tag_value_superset():
conn = boto.connect_vpc()
@ -230,6 +479,30 @@ def test_vpc_get_by_tag_value_superset():
vpc2.id.should.be.within(vpc_ids)
@mock_ec2
def test_vpc_get_by_tag_value_superset_boto3():
ec2 = boto3.resource("ec2", region_name="us-east-1")
client = boto3.client("ec2", region_name="us-east-1")
vpc1 = ec2.create_vpc(CidrBlock="10.0.0.0/16")
vpc2 = ec2.create_vpc(CidrBlock="10.0.0.0/16")
vpc3 = ec2.create_vpc(CidrBlock="10.0.0.0/24")
vpc1.create_tags(Tags=[{"Key": "Name", "Value": "TestVPC"}])
vpc1.create_tags(Tags=[{"Key": "Key", "Value": "TestVPC2"}])
vpc2.create_tags(Tags=[{"Key": "Name", "Value": "TestVPC"}])
vpc2.create_tags(Tags=[{"Key": "Key", "Value": "TestVPC2"}])
vpc3.create_tags(Tags=[{"Key": "Key", "Value": "TestVPC2"}])
vpcs = client.describe_vpcs(Filters=[{"Name": "tag-value", "Values": ["TestVPC"]}])[
"Vpcs"
]
vpcs.should.have.length_of(2)
vpc_ids = tuple(map(lambda v: v["VpcId"], vpcs))
vpc1.id.should.be.within(vpc_ids)
vpc2.id.should.be.within(vpc_ids)
# Has boto3 equivalent
@mock_ec2_deprecated
def test_vpc_get_by_tag_value_subset():
conn = boto.connect_vpc()
@ -249,6 +522,28 @@ def test_vpc_get_by_tag_value_subset():
vpc2.id.should.be.within(vpc_ids)
@mock_ec2
def test_vpc_get_by_tag_value_subset_boto3():
ec2 = boto3.resource("ec2", region_name="us-east-1")
client = boto3.client("ec2", region_name="us-east-1")
vpc1 = ec2.create_vpc(CidrBlock="10.0.0.0/16")
vpc2 = ec2.create_vpc(CidrBlock="10.0.0.0/16")
ec2.create_vpc(CidrBlock="10.0.0.0/24")
vpc1.create_tags(Tags=[{"Key": "Name", "Value": "TestVPC"}])
vpc1.create_tags(Tags=[{"Key": "Key", "Value": "TestVPC2"}])
vpc2.create_tags(Tags=[{"Key": "Name", "Value": "TestVPC"}])
vpc2.create_tags(Tags=[{"Key": "Key", "Value": "TestVPC2"}])
vpcs = client.describe_vpcs(
Filters=[{"Name": "tag-value", "Values": ["TestVPC", "TestVPC2"]}]
)["Vpcs"]
vpcs.should.have.length_of(2)
vpc_ids = tuple(map(lambda v: v["VpcId"], vpcs))
vpc1.id.should.be.within(vpc_ids)
vpc2.id.should.be.within(vpc_ids)
@mock_ec2
def test_default_vpc():
ec2 = boto3.resource("ec2", region_name="us-west-1")
@ -382,6 +677,7 @@ def test_vpc_modify_enable_dns_hostnames():
attr.get("Value").should.be.ok
# Has boto3 equivalent
@mock_ec2_deprecated
def test_vpc_associate_dhcp_options():
conn = boto.connect_vpc()
@ -394,6 +690,24 @@ def test_vpc_associate_dhcp_options():
dhcp_options.id.should.equal(vpc.dhcp_options_id)
@mock_ec2
def test_vpc_associate_dhcp_options_boto3():
ec2 = boto3.resource("ec2", region_name="us-west-1")
client = boto3.client("ec2", region_name="us-west-1")
dhcp_options = ec2.create_dhcp_options(
DhcpConfigurations=[
{"Key": "domain-name", "Values": [SAMPLE_DOMAIN_NAME]},
{"Key": "domain-name-servers", "Values": SAMPLE_NAME_SERVERS},
]
)
vpc = ec2.create_vpc(CidrBlock="10.0.0.0/16")
client.associate_dhcp_options(DhcpOptionsId=dhcp_options.id, VpcId=vpc.id)
vpc.reload()
dhcp_options.id.should.equal(vpc.dhcp_options_id)
@mock_ec2
def test_associate_vpc_ipv4_cidr_block():
ec2 = boto3.resource("ec2", region_name="us-west-1")

View File

@ -5,10 +5,11 @@ import boto3
import pytest
import sure # noqa
from boto.exception import EC2ResponseError
from botocore.client import ClientError
from botocore.exceptions import ClientError
from moto import mock_ec2, mock_ec2_deprecated
# Has boto3 equivalent
@mock_ec2_deprecated
def test_create_vpn_connections():
conn = boto.connect_vpc("the_key", "the_secret")
@ -20,6 +21,17 @@ def test_create_vpn_connections():
vpn_connection.type.should.equal("ipsec.1")
@mock_ec2
def test_create_vpn_connections_boto3():
client = boto3.client("ec2", region_name="us-east-1")
vpn_connection = client.create_vpn_connection(
Type="ipsec.1", VpnGatewayId="vgw-0123abcd", CustomerGatewayId="cgw-0123abcd"
)["VpnConnection"]
vpn_connection["VpnConnectionId"].should.match(r"vpn-\w+")
vpn_connection["Type"].should.equal("ipsec.1")
# Has boto3 equivalent
@mock_ec2_deprecated
def test_delete_vpn_connections():
conn = boto.connect_vpc("the_key", "the_secret")
@ -33,6 +45,24 @@ def test_delete_vpn_connections():
list_of_vpn_connections[0].state.should.equal("deleted")
@mock_ec2
def test_delete_vpn_connections_boto3():
client = boto3.client("ec2", region_name="us-east-1")
vpn_connection = client.create_vpn_connection(
Type="ipsec.1", VpnGatewayId="vgw-0123abcd", CustomerGatewayId="cgw-0123abcd"
)["VpnConnection"]
cnx = client.describe_vpn_connections()["VpnConnections"]
cnx.should.have.length_of(1)
client.delete_vpn_connection(VpnConnectionId=vpn_connection["VpnConnectionId"])
cnx = client.describe_vpn_connections()["VpnConnections"]
cnx.should.have.length_of(1)
cnx[0].should.have.key("State").equal("deleted")
# Has boto3 equivalent
@mock_ec2_deprecated
def test_delete_vpn_connections_bad_id():
conn = boto.connect_vpc("the_key", "the_secret")
@ -40,6 +70,17 @@ def test_delete_vpn_connections_bad_id():
conn.delete_vpn_connection("vpn-0123abcd")
@mock_ec2
def test_delete_vpn_connections_bad_id_boto3():
client = boto3.client("ec2", region_name="us-east-1")
with pytest.raises(ClientError) as ex:
client.delete_vpn_connection(VpnConnectionId="vpn-0123abcd")
ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
ex.value.response["ResponseMetadata"].should.have.key("RequestId")
ex.value.response["Error"]["Code"].should.equal("InvalidVpnConnectionID.NotFound")
# Has boto3 equivalent
@mock_ec2_deprecated
def test_describe_vpn_connections():
conn = boto.connect_vpc("the_key", "the_secret")