This commit is contained in:
Steve Pulec 2017-02-23 21:37:43 -05:00
commit f37bad0e00
260 changed files with 6363 additions and 3766 deletions

View file

@ -1,6 +1,6 @@
from __future__ import unicode_literals
from .models import ec2_backends
from ..core.models import MockAWS, base_decorator, HttprettyMockAWS, deprecated_base_decorator
from ..core.models import base_decorator, deprecated_base_decorator
ec2_backend = ec2_backends['us-east-1']
mock_ec2 = base_decorator(ec2_backends)

View file

@ -7,12 +7,14 @@ class EC2ClientError(RESTError):
class DependencyViolationError(EC2ClientError):
def __init__(self, message):
super(DependencyViolationError, self).__init__(
"DependencyViolation", message)
class MissingParameterError(EC2ClientError):
def __init__(self, parameter):
super(MissingParameterError, self).__init__(
"MissingParameter",
@ -21,6 +23,7 @@ class MissingParameterError(EC2ClientError):
class InvalidDHCPOptionsIdError(EC2ClientError):
def __init__(self, dhcp_options_id):
super(InvalidDHCPOptionsIdError, self).__init__(
"InvalidDhcpOptionID.NotFound",
@ -29,6 +32,7 @@ class InvalidDHCPOptionsIdError(EC2ClientError):
class MalformedDHCPOptionsIdError(EC2ClientError):
def __init__(self, dhcp_options_id):
super(MalformedDHCPOptionsIdError, self).__init__(
"InvalidDhcpOptionsId.Malformed",
@ -37,6 +41,7 @@ class MalformedDHCPOptionsIdError(EC2ClientError):
class InvalidKeyPairNameError(EC2ClientError):
def __init__(self, key):
super(InvalidKeyPairNameError, self).__init__(
"InvalidKeyPair.NotFound",
@ -45,6 +50,7 @@ class InvalidKeyPairNameError(EC2ClientError):
class InvalidKeyPairDuplicateError(EC2ClientError):
def __init__(self, key):
super(InvalidKeyPairDuplicateError, self).__init__(
"InvalidKeyPair.Duplicate",
@ -53,6 +59,7 @@ class InvalidKeyPairDuplicateError(EC2ClientError):
class InvalidVPCIdError(EC2ClientError):
def __init__(self, vpc_id):
super(InvalidVPCIdError, self).__init__(
"InvalidVpcID.NotFound",
@ -61,6 +68,7 @@ class InvalidVPCIdError(EC2ClientError):
class InvalidSubnetIdError(EC2ClientError):
def __init__(self, subnet_id):
super(InvalidSubnetIdError, self).__init__(
"InvalidSubnetID.NotFound",
@ -69,6 +77,7 @@ class InvalidSubnetIdError(EC2ClientError):
class InvalidNetworkAclIdError(EC2ClientError):
def __init__(self, network_acl_id):
super(InvalidNetworkAclIdError, self).__init__(
"InvalidNetworkAclID.NotFound",
@ -77,6 +86,7 @@ class InvalidNetworkAclIdError(EC2ClientError):
class InvalidVpnGatewayIdError(EC2ClientError):
def __init__(self, network_acl_id):
super(InvalidVpnGatewayIdError, self).__init__(
"InvalidVpnGatewayID.NotFound",
@ -85,6 +95,7 @@ class InvalidVpnGatewayIdError(EC2ClientError):
class InvalidVpnConnectionIdError(EC2ClientError):
def __init__(self, network_acl_id):
super(InvalidVpnConnectionIdError, self).__init__(
"InvalidVpnConnectionID.NotFound",
@ -93,6 +104,7 @@ class InvalidVpnConnectionIdError(EC2ClientError):
class InvalidCustomerGatewayIdError(EC2ClientError):
def __init__(self, customer_gateway_id):
super(InvalidCustomerGatewayIdError, self).__init__(
"InvalidCustomerGatewayID.NotFound",
@ -101,6 +113,7 @@ class InvalidCustomerGatewayIdError(EC2ClientError):
class InvalidNetworkInterfaceIdError(EC2ClientError):
def __init__(self, eni_id):
super(InvalidNetworkInterfaceIdError, self).__init__(
"InvalidNetworkInterfaceID.NotFound",
@ -109,6 +122,7 @@ class InvalidNetworkInterfaceIdError(EC2ClientError):
class InvalidNetworkAttachmentIdError(EC2ClientError):
def __init__(self, attachment_id):
super(InvalidNetworkAttachmentIdError, self).__init__(
"InvalidAttachmentID.NotFound",
@ -117,6 +131,7 @@ class InvalidNetworkAttachmentIdError(EC2ClientError):
class InvalidSecurityGroupDuplicateError(EC2ClientError):
def __init__(self, name):
super(InvalidSecurityGroupDuplicateError, self).__init__(
"InvalidGroup.Duplicate",
@ -125,6 +140,7 @@ class InvalidSecurityGroupDuplicateError(EC2ClientError):
class InvalidSecurityGroupNotFoundError(EC2ClientError):
def __init__(self, name):
super(InvalidSecurityGroupNotFoundError, self).__init__(
"InvalidGroup.NotFound",
@ -133,6 +149,7 @@ class InvalidSecurityGroupNotFoundError(EC2ClientError):
class InvalidPermissionNotFoundError(EC2ClientError):
def __init__(self):
super(InvalidPermissionNotFoundError, self).__init__(
"InvalidPermission.NotFound",
@ -140,6 +157,7 @@ class InvalidPermissionNotFoundError(EC2ClientError):
class InvalidRouteTableIdError(EC2ClientError):
def __init__(self, route_table_id):
super(InvalidRouteTableIdError, self).__init__(
"InvalidRouteTableID.NotFound",
@ -148,6 +166,7 @@ class InvalidRouteTableIdError(EC2ClientError):
class InvalidRouteError(EC2ClientError):
def __init__(self, route_table_id, cidr):
super(InvalidRouteError, self).__init__(
"InvalidRoute.NotFound",
@ -156,6 +175,7 @@ class InvalidRouteError(EC2ClientError):
class InvalidInstanceIdError(EC2ClientError):
def __init__(self, instance_id):
super(InvalidInstanceIdError, self).__init__(
"InvalidInstanceID.NotFound",
@ -164,6 +184,7 @@ class InvalidInstanceIdError(EC2ClientError):
class InvalidAMIIdError(EC2ClientError):
def __init__(self, ami_id):
super(InvalidAMIIdError, self).__init__(
"InvalidAMIID.NotFound",
@ -172,6 +193,7 @@ class InvalidAMIIdError(EC2ClientError):
class InvalidAMIAttributeItemValueError(EC2ClientError):
def __init__(self, attribute, value):
super(InvalidAMIAttributeItemValueError, self).__init__(
"InvalidAMIAttributeItemValue",
@ -180,6 +202,7 @@ class InvalidAMIAttributeItemValueError(EC2ClientError):
class MalformedAMIIdError(EC2ClientError):
def __init__(self, ami_id):
super(MalformedAMIIdError, self).__init__(
"InvalidAMIID.Malformed",
@ -188,6 +211,7 @@ class MalformedAMIIdError(EC2ClientError):
class InvalidSnapshotIdError(EC2ClientError):
def __init__(self, snapshot_id):
super(InvalidSnapshotIdError, self).__init__(
"InvalidSnapshot.NotFound",
@ -195,6 +219,7 @@ class InvalidSnapshotIdError(EC2ClientError):
class InvalidVolumeIdError(EC2ClientError):
def __init__(self, volume_id):
super(InvalidVolumeIdError, self).__init__(
"InvalidVolume.NotFound",
@ -203,6 +228,7 @@ class InvalidVolumeIdError(EC2ClientError):
class InvalidVolumeAttachmentError(EC2ClientError):
def __init__(self, volume_id, instance_id):
super(InvalidVolumeAttachmentError, self).__init__(
"InvalidAttachment.NotFound",
@ -211,6 +237,7 @@ class InvalidVolumeAttachmentError(EC2ClientError):
class InvalidDomainError(EC2ClientError):
def __init__(self, domain):
super(InvalidDomainError, self).__init__(
"InvalidParameterValue",
@ -219,6 +246,7 @@ class InvalidDomainError(EC2ClientError):
class InvalidAddressError(EC2ClientError):
def __init__(self, ip):
super(InvalidAddressError, self).__init__(
"InvalidAddress.NotFound",
@ -227,6 +255,7 @@ class InvalidAddressError(EC2ClientError):
class InvalidAllocationIdError(EC2ClientError):
def __init__(self, allocation_id):
super(InvalidAllocationIdError, self).__init__(
"InvalidAllocationID.NotFound",
@ -235,6 +264,7 @@ class InvalidAllocationIdError(EC2ClientError):
class InvalidAssociationIdError(EC2ClientError):
def __init__(self, association_id):
super(InvalidAssociationIdError, self).__init__(
"InvalidAssociationID.NotFound",
@ -243,6 +273,7 @@ class InvalidAssociationIdError(EC2ClientError):
class InvalidVPCPeeringConnectionIdError(EC2ClientError):
def __init__(self, vpc_peering_connection_id):
super(InvalidVPCPeeringConnectionIdError, self).__init__(
"InvalidVpcPeeringConnectionId.NotFound",
@ -251,6 +282,7 @@ class InvalidVPCPeeringConnectionIdError(EC2ClientError):
class InvalidVPCPeeringConnectionStateTransitionError(EC2ClientError):
def __init__(self, vpc_peering_connection_id):
super(InvalidVPCPeeringConnectionStateTransitionError, self).__init__(
"InvalidStateTransition",
@ -259,6 +291,7 @@ class InvalidVPCPeeringConnectionStateTransitionError(EC2ClientError):
class InvalidParameterValueError(EC2ClientError):
def __init__(self, parameter_value):
super(InvalidParameterValueError, self).__init__(
"InvalidParameterValue",
@ -267,6 +300,7 @@ class InvalidParameterValueError(EC2ClientError):
class InvalidParameterValueErrorTagNull(EC2ClientError):
def __init__(self):
super(InvalidParameterValueErrorTagNull, self).__init__(
"InvalidParameterValue",
@ -274,6 +308,7 @@ class InvalidParameterValueErrorTagNull(EC2ClientError):
class InvalidInternetGatewayIdError(EC2ClientError):
def __init__(self, internet_gateway_id):
super(InvalidInternetGatewayIdError, self).__init__(
"InvalidInternetGatewayID.NotFound",
@ -282,6 +317,7 @@ class InvalidInternetGatewayIdError(EC2ClientError):
class GatewayNotAttachedError(EC2ClientError):
def __init__(self, internet_gateway_id, vpc_id):
super(GatewayNotAttachedError, self).__init__(
"Gateway.NotAttached",
@ -290,6 +326,7 @@ class GatewayNotAttachedError(EC2ClientError):
class ResourceAlreadyAssociatedError(EC2ClientError):
def __init__(self, resource_id):
super(ResourceAlreadyAssociatedError, self).__init__(
"Resource.AlreadyAssociated",
@ -298,6 +335,7 @@ class ResourceAlreadyAssociatedError(EC2ClientError):
class TagLimitExceeded(EC2ClientError):
def __init__(self):
super(TagLimitExceeded, self).__init__(
"TagLimitExceeded",
@ -305,6 +343,7 @@ class TagLimitExceeded(EC2ClientError):
class InvalidID(EC2ClientError):
def __init__(self, resource_id):
super(InvalidID, self).__init__(
"InvalidID",
@ -313,6 +352,7 @@ class InvalidID(EC2ClientError):
class InvalidCIDRSubnetError(EC2ClientError):
def __init__(self, cidr):
super(InvalidCIDRSubnetError, self).__init__(
"InvalidParameterValue",
@ -321,6 +361,7 @@ class InvalidCIDRSubnetError(EC2ClientError):
class RulesPerSecurityGroupLimitExceededError(EC2ClientError):
def __init__(self):
super(RulesPerSecurityGroupLimitExceededError, self).__init__(
"RulesPerSecurityGroupLimitExceeded",

File diff suppressed because it is too large Load diff

View file

@ -66,6 +66,7 @@ class EC2Response(
Windows,
NatGateways,
):
@property
def ec2_backend(self):
from moto.ec2.models import ec2_backends

View file

@ -3,5 +3,7 @@ from moto.core.responses import BaseResponse
class AmazonDevPay(BaseResponse):
def confirm_product_instance(self):
raise NotImplementedError('AmazonDevPay.confirm_product_instance is not yet implemented')
raise NotImplementedError(
'AmazonDevPay.confirm_product_instance is not yet implemented')

View file

@ -5,6 +5,7 @@ from moto.ec2.utils import instance_ids_from_querystring, image_ids_from_queryst
class AmisResponse(BaseResponse):
def create_image(self):
name = self.querystring.get('Name')[0]
if "Description" in self.querystring:
@ -14,17 +15,21 @@ class AmisResponse(BaseResponse):
instance_ids = instance_ids_from_querystring(self.querystring)
instance_id = instance_ids[0]
if self.is_not_dryrun('CreateImage'):
image = self.ec2_backend.create_image(instance_id, name, description)
image = self.ec2_backend.create_image(
instance_id, name, description)
template = self.response_template(CREATE_IMAGE_RESPONSE)
return template.render(image=image)
def copy_image(self):
source_image_id = self.querystring.get('SourceImageId')[0]
source_region = self.querystring.get('SourceRegion')[0]
name = self.querystring.get('Name')[0] if self.querystring.get('Name') else None
description = self.querystring.get('Description')[0] if self.querystring.get('Description') else None
name = self.querystring.get(
'Name')[0] if self.querystring.get('Name') else None
description = self.querystring.get(
'Description')[0] if self.querystring.get('Description') else None
if self.is_not_dryrun('CopyImage'):
image = self.ec2_backend.copy_image(source_image_id, source_region, name, description)
image = self.ec2_backend.copy_image(
source_image_id, source_region, name, description)
template = self.response_template(COPY_IMAGE_RESPONSE)
return template.render(image=image)
@ -38,7 +43,8 @@ class AmisResponse(BaseResponse):
def describe_images(self):
ami_ids = image_ids_from_querystring(self.querystring)
filters = filters_from_querystring(self.querystring)
images = self.ec2_backend.describe_images(ami_ids=ami_ids, filters=filters)
images = self.ec2_backend.describe_images(
ami_ids=ami_ids, filters=filters)
template = self.response_template(DESCRIBE_IMAGES_RESPONSE)
return template.render(images=images)
@ -56,18 +62,22 @@ class AmisResponse(BaseResponse):
user_ids = sequence_from_querystring('UserId', self.querystring)
if self.is_not_dryrun('ModifyImageAttribute'):
if (operation_type == 'add'):
self.ec2_backend.add_launch_permission(ami_id, user_ids=user_ids, group=group)
self.ec2_backend.add_launch_permission(
ami_id, user_ids=user_ids, group=group)
elif (operation_type == 'remove'):
self.ec2_backend.remove_launch_permission(ami_id, user_ids=user_ids, group=group)
self.ec2_backend.remove_launch_permission(
ami_id, user_ids=user_ids, group=group)
return MODIFY_IMAGE_ATTRIBUTE_RESPONSE
def register_image(self):
if self.is_not_dryrun('RegisterImage'):
raise NotImplementedError('AMIs.register_image is not yet implemented')
raise NotImplementedError(
'AMIs.register_image is not yet implemented')
def reset_image_attribute(self):
if self.is_not_dryrun('ResetImageAttribute'):
raise NotImplementedError('AMIs.reset_image_attribute is not yet implemented')
raise NotImplementedError(
'AMIs.reset_image_attribute is not yet implemented')
CREATE_IMAGE_RESPONSE = """<CreateImageResponse xmlns="http://ec2.amazonaws.com/doc/2013-10-15/">
@ -80,7 +90,8 @@ COPY_IMAGE_RESPONSE = """<CopyImageResponse xmlns="http://ec2.amazonaws.com/doc/
<imageId>{{ image.id }}</imageId>
</CopyImageResponse>"""
# TODO almost all of these params should actually be templated based on the ec2 image
# TODO almost all of these params should actually be templated based on
# the ec2 image
DESCRIBE_IMAGES_RESPONSE = """<DescribeImagesResponse xmlns="http://ec2.amazonaws.com/doc/2013-10-15/">
<requestId>59dbff89-35bd-4eac-99ed-be587EXAMPLE</requestId>
<imagesSet>

View file

@ -3,6 +3,7 @@ from moto.core.responses import BaseResponse
class AvailabilityZonesAndRegions(BaseResponse):
def describe_availability_zones(self):
zones = self.ec2_backend.describe_availability_zones()
template = self.response_template(DESCRIBE_ZONES_RESPONSE)
@ -13,6 +14,7 @@ class AvailabilityZonesAndRegions(BaseResponse):
template = self.response_template(DESCRIBE_REGIONS_RESPONSE)
return template.render(regions=regions)
DESCRIBE_REGIONS_RESPONSE = """<DescribeRegionsResponse xmlns="http://ec2.amazonaws.com/doc/2013-10-15/">
<requestId>59dbff89-35bd-4eac-99ed-be587EXAMPLE</requestId>
<regionInfo>

View file

@ -10,13 +10,15 @@ class CustomerGateways(BaseResponse):
type = self.querystring.get('Type', None)[0]
ip_address = self.querystring.get('IpAddress', None)[0]
bgp_asn = self.querystring.get('BgpAsn', None)[0]
customer_gateway = self.ec2_backend.create_customer_gateway(type, ip_address=ip_address, bgp_asn=bgp_asn)
customer_gateway = self.ec2_backend.create_customer_gateway(
type, ip_address=ip_address, bgp_asn=bgp_asn)
template = self.response_template(CREATE_CUSTOMER_GATEWAY_RESPONSE)
return template.render(customer_gateway=customer_gateway)
def delete_customer_gateway(self):
customer_gateway_id = self.querystring.get('CustomerGatewayId')[0]
delete_status = self.ec2_backend.delete_customer_gateway(customer_gateway_id)
delete_status = self.ec2_backend.delete_customer_gateway(
customer_gateway_id)
template = self.response_template(DELETE_CUSTOMER_GATEWAY_RESPONSE)
return template.render(customer_gateway=delete_status)

View file

@ -7,6 +7,7 @@ from moto.ec2.utils import (
class DHCPOptions(BaseResponse):
def associate_dhcp_options(self):
dhcp_opt_id = self.querystring.get("DhcpOptionsId", [None])[0]
vpc_id = self.querystring.get("VpcId", [None])[0]
@ -48,9 +49,11 @@ class DHCPOptions(BaseResponse):
return template.render(delete_status=delete_status)
def describe_dhcp_options(self):
dhcp_opt_ids = sequence_from_querystring("DhcpOptionsId", self.querystring)
dhcp_opt_ids = sequence_from_querystring(
"DhcpOptionsId", self.querystring)
filters = filters_from_querystring(self.querystring)
dhcp_opts = self.ec2_backend.get_all_dhcp_options(dhcp_opt_ids, filters)
dhcp_opts = self.ec2_backend.get_all_dhcp_options(
dhcp_opt_ids, filters)
template = self.response_template(DESCRIBE_DHCP_OPTIONS_RESPONSE)
return template.render(dhcp_options=dhcp_opts)

View file

@ -10,13 +10,15 @@ class ElasticBlockStore(BaseResponse):
instance_id = self.querystring.get('InstanceId')[0]
device_path = self.querystring.get('Device')[0]
if self.is_not_dryrun('AttachVolume'):
attachment = self.ec2_backend.attach_volume(volume_id, instance_id, device_path)
attachment = self.ec2_backend.attach_volume(
volume_id, instance_id, device_path)
template = self.response_template(ATTACHED_VOLUME_RESPONSE)
return template.render(attachment=attachment)
def copy_snapshot(self):
if self.is_not_dryrun('CopySnapshot'):
raise NotImplementedError('ElasticBlockStore.copy_snapshot is not yet implemented')
raise NotImplementedError(
'ElasticBlockStore.copy_snapshot is not yet implemented')
def create_snapshot(self):
description = self.querystring.get('Description', [None])[0]
@ -32,7 +34,8 @@ class ElasticBlockStore(BaseResponse):
snapshot_id = self.querystring.get('SnapshotId', [None])[0]
encrypted = self.querystring.get('Encrypted', ['false'])[0]
if self.is_not_dryrun('CreateVolume'):
volume = self.ec2_backend.create_volume(size, zone, snapshot_id, encrypted)
volume = self.ec2_backend.create_volume(
size, zone, snapshot_id, encrypted)
template = self.response_template(CREATE_VOLUME_RESPONSE)
return template.render(volume=volume)
@ -50,51 +53,64 @@ class ElasticBlockStore(BaseResponse):
def describe_snapshots(self):
filters = filters_from_querystring(self.querystring)
# querystring for multiple snapshotids results in SnapshotId.1, SnapshotId.2 etc
snapshot_ids = ','.join([','.join(s[1]) for s in self.querystring.items() if 'SnapshotId' in s[0]])
# querystring for multiple snapshotids results in SnapshotId.1,
# SnapshotId.2 etc
snapshot_ids = ','.join(
[','.join(s[1]) for s in self.querystring.items() if 'SnapshotId' in s[0]])
snapshots = self.ec2_backend.describe_snapshots(filters=filters)
# Describe snapshots to handle filter on snapshot_ids
snapshots = [s for s in snapshots if s.id in snapshot_ids] if snapshot_ids else snapshots
snapshots = [
s for s in snapshots if s.id in snapshot_ids] if snapshot_ids else snapshots
template = self.response_template(DESCRIBE_SNAPSHOTS_RESPONSE)
return template.render(snapshots=snapshots)
def describe_volumes(self):
filters = filters_from_querystring(self.querystring)
# querystring for multiple volumeids results in VolumeId.1, VolumeId.2 etc
volume_ids = ','.join([','.join(v[1]) for v in self.querystring.items() if 'VolumeId' in v[0]])
# querystring for multiple volumeids results in VolumeId.1, VolumeId.2
# etc
volume_ids = ','.join(
[','.join(v[1]) for v in self.querystring.items() if 'VolumeId' in v[0]])
volumes = self.ec2_backend.describe_volumes(filters=filters)
# Describe volumes to handle filter on volume_ids
volumes = [v for v in volumes if v.id in volume_ids] if volume_ids else volumes
volumes = [
v for v in volumes if v.id in volume_ids] if volume_ids else volumes
template = self.response_template(DESCRIBE_VOLUMES_RESPONSE)
return template.render(volumes=volumes)
def describe_volume_attribute(self):
raise NotImplementedError('ElasticBlockStore.describe_volume_attribute is not yet implemented')
raise NotImplementedError(
'ElasticBlockStore.describe_volume_attribute is not yet implemented')
def describe_volume_status(self):
raise NotImplementedError('ElasticBlockStore.describe_volume_status is not yet implemented')
raise NotImplementedError(
'ElasticBlockStore.describe_volume_status is not yet implemented')
def detach_volume(self):
volume_id = self.querystring.get('VolumeId')[0]
instance_id = self.querystring.get('InstanceId')[0]
device_path = self.querystring.get('Device')[0]
if self.is_not_dryrun('DetachVolume'):
attachment = self.ec2_backend.detach_volume(volume_id, instance_id, device_path)
attachment = self.ec2_backend.detach_volume(
volume_id, instance_id, device_path)
template = self.response_template(DETATCH_VOLUME_RESPONSE)
return template.render(attachment=attachment)
def enable_volume_io(self):
if self.is_not_dryrun('EnableVolumeIO'):
raise NotImplementedError('ElasticBlockStore.enable_volume_io is not yet implemented')
raise NotImplementedError(
'ElasticBlockStore.enable_volume_io is not yet implemented')
def import_volume(self):
if self.is_not_dryrun('ImportVolume'):
raise NotImplementedError('ElasticBlockStore.import_volume is not yet implemented')
raise NotImplementedError(
'ElasticBlockStore.import_volume is not yet implemented')
def describe_snapshot_attribute(self):
snapshot_id = self.querystring.get('SnapshotId')[0]
groups = self.ec2_backend.get_create_volume_permission_groups(snapshot_id)
template = self.response_template(DESCRIBE_SNAPSHOT_ATTRIBUTES_RESPONSE)
groups = self.ec2_backend.get_create_volume_permission_groups(
snapshot_id)
template = self.response_template(
DESCRIBE_SNAPSHOT_ATTRIBUTES_RESPONSE)
return template.render(snapshot_id=snapshot_id, groups=groups)
def modify_snapshot_attribute(self):
@ -104,18 +120,22 @@ class ElasticBlockStore(BaseResponse):
user_id = self.querystring.get('UserId.1', [None])[0]
if self.is_not_dryrun('ModifySnapshotAttribute'):
if (operation_type == 'add'):
self.ec2_backend.add_create_volume_permission(snapshot_id, user_id=user_id, group=group)
self.ec2_backend.add_create_volume_permission(
snapshot_id, user_id=user_id, group=group)
elif (operation_type == 'remove'):
self.ec2_backend.remove_create_volume_permission(snapshot_id, user_id=user_id, group=group)
self.ec2_backend.remove_create_volume_permission(
snapshot_id, user_id=user_id, group=group)
return MODIFY_SNAPSHOT_ATTRIBUTE_RESPONSE
def modify_volume_attribute(self):
if self.is_not_dryrun('ModifyVolumeAttribute'):
raise NotImplementedError('ElasticBlockStore.modify_volume_attribute is not yet implemented')
raise NotImplementedError(
'ElasticBlockStore.modify_volume_attribute is not yet implemented')
def reset_snapshot_attribute(self):
if self.is_not_dryrun('ResetSnapshotAttribute'):
raise NotImplementedError('ElasticBlockStore.reset_snapshot_attribute is not yet implemented')
raise NotImplementedError(
'ElasticBlockStore.reset_snapshot_attribute is not yet implemented')
CREATE_VOLUME_RESPONSE = """<CreateVolumeResponse xmlns="http://ec2.amazonaws.com/doc/2013-10-15/">
@ -272,4 +292,4 @@ MODIFY_SNAPSHOT_ATTRIBUTE_RESPONSE = """
<requestId>666d2944-9276-4d6a-be12-1f4ada972fd8</requestId>
<return>true</return>
</ModifySnapshotAttributeResponse>
"""
"""

View file

@ -4,6 +4,7 @@ from moto.ec2.utils import sequence_from_querystring
class ElasticIPAddresses(BaseResponse):
def allocate_address(self):
if "Domain" in self.querystring:
domain = self.querystring.get('Domain')[0]
@ -18,11 +19,14 @@ class ElasticIPAddresses(BaseResponse):
instance = eni = None
if "InstanceId" in self.querystring:
instance = self.ec2_backend.get_instance(self.querystring['InstanceId'][0])
instance = self.ec2_backend.get_instance(
self.querystring['InstanceId'][0])
elif "NetworkInterfaceId" in self.querystring:
eni = self.ec2_backend.get_network_interface(self.querystring['NetworkInterfaceId'][0])
eni = self.ec2_backend.get_network_interface(
self.querystring['NetworkInterfaceId'][0])
else:
self.ec2_backend.raise_error("MissingParameter", "Invalid request, expect InstanceId/NetworkId parameter.")
self.ec2_backend.raise_error(
"MissingParameter", "Invalid request, expect InstanceId/NetworkId parameter.")
reassociate = False
if "AllowReassociation" in self.querystring:
@ -31,13 +35,17 @@ class ElasticIPAddresses(BaseResponse):
if self.is_not_dryrun('AssociateAddress'):
if instance or eni:
if "PublicIp" in self.querystring:
eip = self.ec2_backend.associate_address(instance=instance, eni=eni, address=self.querystring['PublicIp'][0], reassociate=reassociate)
eip = self.ec2_backend.associate_address(instance=instance, eni=eni, address=self.querystring[
'PublicIp'][0], reassociate=reassociate)
elif "AllocationId" in self.querystring:
eip = self.ec2_backend.associate_address(instance=instance, eni=eni, allocation_id=self.querystring['AllocationId'][0], reassociate=reassociate)
eip = self.ec2_backend.associate_address(instance=instance, eni=eni, allocation_id=self.querystring[
'AllocationId'][0], reassociate=reassociate)
else:
self.ec2_backend.raise_error("MissingParameter", "Invalid request, expect PublicIp/AllocationId parameter.")
self.ec2_backend.raise_error(
"MissingParameter", "Invalid request, expect PublicIp/AllocationId parameter.")
else:
self.ec2_backend.raise_error("MissingParameter", "Invalid request, expect either instance or ENI.")
self.ec2_backend.raise_error(
"MissingParameter", "Invalid request, expect either instance or ENI.")
template = self.response_template(ASSOCIATE_ADDRESS_RESPONSE)
return template.render(address=eip)
@ -46,17 +54,23 @@ class ElasticIPAddresses(BaseResponse):
template = self.response_template(DESCRIBE_ADDRESS_RESPONSE)
if "Filter.1.Name" in self.querystring:
filter_by = sequence_from_querystring("Filter.1.Name", self.querystring)[0]
filter_value = sequence_from_querystring("Filter.1.Value", self.querystring)
filter_by = sequence_from_querystring(
"Filter.1.Name", self.querystring)[0]
filter_value = sequence_from_querystring(
"Filter.1.Value", self.querystring)
if filter_by == 'instance-id':
addresses = filter(lambda x: x.instance.id == filter_value[0], self.ec2_backend.describe_addresses())
addresses = filter(lambda x: x.instance.id == filter_value[
0], self.ec2_backend.describe_addresses())
else:
raise NotImplementedError("Filtering not supported in describe_address.")
raise NotImplementedError(
"Filtering not supported in describe_address.")
elif "PublicIp.1" in self.querystring:
public_ips = sequence_from_querystring("PublicIp", self.querystring)
public_ips = sequence_from_querystring(
"PublicIp", self.querystring)
addresses = self.ec2_backend.address_by_ip(public_ips)
elif "AllocationId.1" in self.querystring:
allocation_ids = sequence_from_querystring("AllocationId", self.querystring)
allocation_ids = sequence_from_querystring(
"AllocationId", self.querystring)
addresses = self.ec2_backend.address_by_allocation(allocation_ids)
else:
addresses = self.ec2_backend.describe_addresses()
@ -65,22 +79,28 @@ class ElasticIPAddresses(BaseResponse):
def disassociate_address(self):
if self.is_not_dryrun('DisAssociateAddress'):
if "PublicIp" in self.querystring:
self.ec2_backend.disassociate_address(address=self.querystring['PublicIp'][0])
self.ec2_backend.disassociate_address(
address=self.querystring['PublicIp'][0])
elif "AssociationId" in self.querystring:
self.ec2_backend.disassociate_address(association_id=self.querystring['AssociationId'][0])
self.ec2_backend.disassociate_address(
association_id=self.querystring['AssociationId'][0])
else:
self.ec2_backend.raise_error("MissingParameter", "Invalid request, expect PublicIp/AssociationId parameter.")
self.ec2_backend.raise_error(
"MissingParameter", "Invalid request, expect PublicIp/AssociationId parameter.")
return self.response_template(DISASSOCIATE_ADDRESS_RESPONSE).render()
def release_address(self):
if self.is_not_dryrun('ReleaseAddress'):
if "PublicIp" in self.querystring:
self.ec2_backend.release_address(address=self.querystring['PublicIp'][0])
self.ec2_backend.release_address(
address=self.querystring['PublicIp'][0])
elif "AllocationId" in self.querystring:
self.ec2_backend.release_address(allocation_id=self.querystring['AllocationId'][0])
self.ec2_backend.release_address(
allocation_id=self.querystring['AllocationId'][0])
else:
self.ec2_backend.raise_error("MissingParameter", "Invalid request, expect PublicIp/AllocationId parameter.")
self.ec2_backend.raise_error(
"MissingParameter", "Invalid request, expect PublicIp/AllocationId parameter.")
return self.response_template(RELEASE_ADDRESS_RESPONSE).render()

View file

@ -4,28 +4,35 @@ from moto.ec2.utils import sequence_from_querystring, filters_from_querystring
class ElasticNetworkInterfaces(BaseResponse):
def create_network_interface(self):
subnet_id = self.querystring.get('SubnetId')[0]
private_ip_address = self.querystring.get('PrivateIpAddress', [None])[0]
private_ip_address = self.querystring.get(
'PrivateIpAddress', [None])[0]
groups = sequence_from_querystring('SecurityGroupId', self.querystring)
subnet = self.ec2_backend.get_subnet(subnet_id)
if self.is_not_dryrun('CreateNetworkInterface'):
eni = self.ec2_backend.create_network_interface(subnet, private_ip_address, groups)
template = self.response_template(CREATE_NETWORK_INTERFACE_RESPONSE)
eni = self.ec2_backend.create_network_interface(
subnet, private_ip_address, groups)
template = self.response_template(
CREATE_NETWORK_INTERFACE_RESPONSE)
return template.render(eni=eni)
def delete_network_interface(self):
eni_id = self.querystring.get('NetworkInterfaceId')[0]
if self.is_not_dryrun('DeleteNetworkInterface'):
self.ec2_backend.delete_network_interface(eni_id)
template = self.response_template(DELETE_NETWORK_INTERFACE_RESPONSE)
template = self.response_template(
DELETE_NETWORK_INTERFACE_RESPONSE)
return template.render()
def describe_network_interface_attribute(self):
raise NotImplementedError('ElasticNetworkInterfaces(AmazonVPC).describe_network_interface_attribute is not yet implemented')
raise NotImplementedError(
'ElasticNetworkInterfaces(AmazonVPC).describe_network_interface_attribute is not yet implemented')
def describe_network_interfaces(self):
eni_ids = sequence_from_querystring('NetworkInterfaceId', self.querystring)
eni_ids = sequence_from_querystring(
'NetworkInterfaceId', self.querystring)
filters = filters_from_querystring(self.querystring)
enis = self.ec2_backend.get_all_network_interfaces(eni_ids, filters)
template = self.response_template(DESCRIBE_NETWORK_INTERFACES_RESPONSE)
@ -36,15 +43,18 @@ class ElasticNetworkInterfaces(BaseResponse):
instance_id = self.querystring.get('InstanceId')[0]
device_index = self.querystring.get('DeviceIndex')[0]
if self.is_not_dryrun('AttachNetworkInterface'):
attachment_id = self.ec2_backend.attach_network_interface(eni_id, instance_id, device_index)
template = self.response_template(ATTACH_NETWORK_INTERFACE_RESPONSE)
attachment_id = self.ec2_backend.attach_network_interface(
eni_id, instance_id, device_index)
template = self.response_template(
ATTACH_NETWORK_INTERFACE_RESPONSE)
return template.render(attachment_id=attachment_id)
def detach_network_interface(self):
attachment_id = self.querystring.get('AttachmentId')[0]
if self.is_not_dryrun('DetachNetworkInterface'):
self.ec2_backend.detach_network_interface(attachment_id)
template = self.response_template(DETACH_NETWORK_INTERFACE_RESPONSE)
template = self.response_template(
DETACH_NETWORK_INTERFACE_RESPONSE)
return template.render()
def modify_network_interface_attribute(self):
@ -52,12 +62,15 @@ class ElasticNetworkInterfaces(BaseResponse):
eni_id = self.querystring.get('NetworkInterfaceId')[0]
group_id = self.querystring.get('SecurityGroupId.1')[0]
if self.is_not_dryrun('ModifyNetworkInterface'):
self.ec2_backend.modify_network_interface_attribute(eni_id, group_id)
self.ec2_backend.modify_network_interface_attribute(
eni_id, group_id)
return MODIFY_NETWORK_INTERFACE_ATTRIBUTE_RESPONSE
def reset_network_interface_attribute(self):
if self.is_not_dryrun('ResetNetworkInterface'):
raise NotImplementedError('ElasticNetworkInterfaces(AmazonVPC).reset_network_interface_attribute is not yet implemented')
raise NotImplementedError(
'ElasticNetworkInterfaces(AmazonVPC).reset_network_interface_attribute is not yet implemented')
CREATE_NETWORK_INTERFACE_RESPONSE = """
<CreateNetworkInterfaceResponse xmlns="http://ec2.amazonaws.com/doc/2013-10-15/">

View file

@ -4,6 +4,7 @@ from moto.ec2.utils import instance_ids_from_querystring
class General(BaseResponse):
def get_console_output(self):
self.instance_ids = instance_ids_from_querystring(self.querystring)
instance_id = self.instance_ids[0]

View file

@ -5,14 +5,18 @@ from moto.core.utils import camelcase_to_underscores
from moto.ec2.utils import instance_ids_from_querystring, filters_from_querystring, \
dict_from_querystring, optional_from_querystring
class InstanceResponse(BaseResponse):
def describe_instances(self):
filter_dict = filters_from_querystring(self.querystring)
instance_ids = instance_ids_from_querystring(self.querystring)
if instance_ids:
reservations = self.ec2_backend.get_reservations_by_instance_ids(instance_ids, filters=filter_dict)
reservations = self.ec2_backend.get_reservations_by_instance_ids(
instance_ids, filters=filter_dict)
else:
reservations = self.ec2_backend.all_reservations(make_copy=True, filters=filter_dict)
reservations = self.ec2_backend.all_reservations(
make_copy=True, filters=filter_dict)
template = self.response_template(EC2_DESCRIBE_INSTANCES)
return template.render(reservations=reservations)
@ -25,10 +29,12 @@ class InstanceResponse(BaseResponse):
security_group_ids = self._get_multi_param('SecurityGroupId')
nics = dict_from_querystring("NetworkInterface", self.querystring)
instance_type = self.querystring.get("InstanceType", ["m1.small"])[0]
placement = self.querystring.get("Placement.AvailabilityZone", [None])[0]
placement = self.querystring.get(
"Placement.AvailabilityZone", [None])[0]
subnet_id = self.querystring.get("SubnetId", [None])[0]
private_ip = self.querystring.get("PrivateIpAddress", [None])[0]
associate_public_ip = self.querystring.get("AssociatePublicIpAddress", [None])[0]
associate_public_ip = self.querystring.get(
"AssociatePublicIpAddress", [None])[0]
key_name = self.querystring.get("KeyName", [None])[0]
if self.is_not_dryrun('RunInstance'):
@ -72,10 +78,11 @@ class InstanceResponse(BaseResponse):
def describe_instance_status(self):
instance_ids = instance_ids_from_querystring(self.querystring)
include_all_instances = optional_from_querystring('IncludeAllInstances',
self.querystring) == 'true'
self.querystring) == 'true'
if instance_ids:
instances = self.ec2_backend.get_multi_instances_by_id(instance_ids)
instances = self.ec2_backend.get_multi_instances_by_id(
instance_ids)
elif include_all_instances:
instances = self.ec2_backend.all_instances()
else:
@ -85,7 +92,8 @@ class InstanceResponse(BaseResponse):
return template.render(instances=instances)
def describe_instance_types(self):
instance_types = [InstanceType(name='t1.micro', cores=1, memory=644874240, disk=0)]
instance_types = [InstanceType(
name='t1.micro', cores=1, memory=644874240, disk=0)]
template = self.response_template(EC2_DESCRIBE_INSTANCE_TYPES)
return template.render(instance_types=instance_types)
@ -96,10 +104,12 @@ class InstanceResponse(BaseResponse):
key = camelcase_to_underscores(attribute)
instance_ids = instance_ids_from_querystring(self.querystring)
instance_id = instance_ids[0]
instance, value = self.ec2_backend.describe_instance_attribute(instance_id, key)
instance, value = self.ec2_backend.describe_instance_attribute(
instance_id, key)
if key == "group_set":
template = self.response_template(EC2_DESCRIBE_INSTANCE_GROUPSET_ATTRIBUTE)
template = self.response_template(
EC2_DESCRIBE_INSTANCE_GROUPSET_ATTRIBUTE)
else:
template = self.response_template(EC2_DESCRIBE_INSTANCE_ATTRIBUTE)
@ -152,7 +162,8 @@ class InstanceResponse(BaseResponse):
instance = self.ec2_backend.get_instance(instance_id)
if self.is_not_dryrun('ModifyInstanceAttribute'):
block_device_type = instance.block_device_mapping[device_name_value]
block_device_type = instance.block_device_mapping[
device_name_value]
block_device_type.delete_on_termination = del_on_term_value
# +1 for the next device
@ -171,24 +182,27 @@ class InstanceResponse(BaseResponse):
if not attribute_key:
return
if self.is_not_dryrun('Modify'+attribute_key.split(".")[0]):
if self.is_not_dryrun('Modify' + attribute_key.split(".")[0]):
value = self.querystring.get(attribute_key)[0]
normalized_attribute = camelcase_to_underscores(attribute_key.split(".")[0])
normalized_attribute = camelcase_to_underscores(
attribute_key.split(".")[0])
instance_ids = instance_ids_from_querystring(self.querystring)
instance_id = instance_ids[0]
self.ec2_backend.modify_instance_attribute(instance_id, normalized_attribute, value)
self.ec2_backend.modify_instance_attribute(
instance_id, normalized_attribute, value)
return EC2_MODIFY_INSTANCE_ATTRIBUTE
def _security_grp_instance_attribute_handler(self):
new_security_grp_list = []
for key, value in self.querystring.items():
if 'GroupId.' in key:
if 'GroupId.' in key:
new_security_grp_list.append(self.querystring.get(key)[0])
instance_ids = instance_ids_from_querystring(self.querystring)
instance_id = instance_ids[0]
if self.is_not_dryrun('ModifyInstanceSecurityGroups'):
self.ec2_backend.modify_instance_security_groups(instance_id, new_security_grp_list)
self.ec2_backend.modify_instance_security_groups(
instance_id, new_security_grp_list)
return EC2_MODIFY_INSTANCE_ATTRIBUTE
@ -630,4 +644,4 @@ EC2_DESCRIBE_INSTANCE_TYPES = """<?xml version="1.0" encoding="UTF-8"?>
</item>
{% endfor %}
</instanceTypeSet>
</DescribeInstanceTypesResponse>"""
</DescribeInstanceTypesResponse>"""

View file

@ -7,6 +7,7 @@ from moto.ec2.utils import (
class InternetGateways(BaseResponse):
def attach_internet_gateway(self):
igw_id = self.querystring.get("InternetGatewayId", [None])[0]
vpc_id = self.querystring.get("VpcId", [None])[0]
@ -33,9 +34,11 @@ class InternetGateways(BaseResponse):
if "InternetGatewayId.1" in self.querystring:
igw_ids = sequence_from_querystring(
"InternetGatewayId", self.querystring)
igws = self.ec2_backend.describe_internet_gateways(igw_ids, filters=filter_dict)
igws = self.ec2_backend.describe_internet_gateways(
igw_ids, filters=filter_dict)
else:
igws = self.ec2_backend.describe_internet_gateways(filters=filter_dict)
igws = self.ec2_backend.describe_internet_gateways(
filters=filter_dict)
template = self.response_template(DESCRIBE_INTERNET_GATEWAYS_RESPONSE)
return template.render(internet_gateways=igws)

View file

@ -4,10 +4,13 @@ from moto.core.responses import BaseResponse
class IPAddresses(BaseResponse):
def assign_private_ip_addresses(self):
if self.is_not_dryrun('AssignPrivateIPAddress'):
raise NotImplementedError('IPAddresses.assign_private_ip_addresses is not yet implemented')
raise NotImplementedError(
'IPAddresses.assign_private_ip_addresses is not yet implemented')
def unassign_private_ip_addresses(self):
if self.is_not_dryrun('UnAssignPrivateIPAddress'):
raise NotImplementedError('IPAddresses.unassign_private_ip_addresses is not yet implemented')
raise NotImplementedError(
'IPAddresses.unassign_private_ip_addresses is not yet implemented')

View file

@ -16,14 +16,16 @@ class KeyPairs(BaseResponse):
def delete_key_pair(self):
name = self.querystring.get('KeyName')[0]
if self.is_not_dryrun('DeleteKeyPair'):
success = six.text_type(self.ec2_backend.delete_key_pair(name)).lower()
success = six.text_type(
self.ec2_backend.delete_key_pair(name)).lower()
return self.response_template(DELETE_KEY_PAIR_RESPONSE).render(success=success)
def describe_key_pairs(self):
names = keypair_names_from_querystring(self.querystring)
filters = filters_from_querystring(self.querystring)
if len(filters) > 0:
raise NotImplementedError('Using filters in KeyPairs.describe_key_pairs is not yet implemented')
raise NotImplementedError(
'Using filters in KeyPairs.describe_key_pairs is not yet implemented')
keypairs = self.ec2_backend.describe_key_pairs(names)
template = self.response_template(DESCRIBE_KEY_PAIRS_RESPONSE)

View file

@ -3,10 +3,13 @@ from moto.core.responses import BaseResponse
class Monitoring(BaseResponse):
def monitor_instances(self):
if self.is_not_dryrun('MonitorInstances'):
raise NotImplementedError('Monitoring.monitor_instances is not yet implemented')
raise NotImplementedError(
'Monitoring.monitor_instances is not yet implemented')
def unmonitor_instances(self):
if self.is_not_dryrun('UnMonitorInstances'):
raise NotImplementedError('Monitoring.unmonitor_instances is not yet implemented')
raise NotImplementedError(
'Monitoring.unmonitor_instances is not yet implemented')

View file

@ -8,7 +8,8 @@ class NatGateways(BaseResponse):
def create_nat_gateway(self):
subnet_id = self._get_param('SubnetId')
allocation_id = self._get_param('AllocationId')
nat_gateway = self.ec2_backend.create_nat_gateway(subnet_id=subnet_id, allocation_id=allocation_id)
nat_gateway = self.ec2_backend.create_nat_gateway(
subnet_id=subnet_id, allocation_id=allocation_id)
template = self.response_template(CREATE_NAT_GATEWAY)
return template.render(nat_gateway=nat_gateway)

View file

@ -45,7 +45,8 @@ class NetworkACLs(BaseResponse):
def describe_network_acls(self):
network_acl_ids = network_acl_ids_from_querystring(self.querystring)
filters = filters_from_querystring(self.querystring)
network_acls = self.ec2_backend.get_all_network_acls(network_acl_ids, filters)
network_acls = self.ec2_backend.get_all_network_acls(
network_acl_ids, filters)
template = self.response_template(DESCRIBE_NETWORK_ACL_RESPONSE)
return template.render(network_acls=network_acls)

View file

@ -3,13 +3,17 @@ from moto.core.responses import BaseResponse
class PlacementGroups(BaseResponse):
def create_placement_group(self):
if self.is_not_dryrun('CreatePlacementGroup'):
raise NotImplementedError('PlacementGroups.create_placement_group is not yet implemented')
raise NotImplementedError(
'PlacementGroups.create_placement_group is not yet implemented')
def delete_placement_group(self):
if self.is_not_dryrun('DeletePlacementGroup'):
raise NotImplementedError('PlacementGroups.delete_placement_group is not yet implemented')
raise NotImplementedError(
'PlacementGroups.delete_placement_group is not yet implemented')
def describe_placement_groups(self):
raise NotImplementedError('PlacementGroups.describe_placement_groups is not yet implemented')
raise NotImplementedError(
'PlacementGroups.describe_placement_groups is not yet implemented')

View file

@ -3,23 +3,30 @@ from moto.core.responses import BaseResponse
class ReservedInstances(BaseResponse):
def cancel_reserved_instances_listing(self):
if self.is_not_dryrun('CancelReservedInstances'):
raise NotImplementedError('ReservedInstances.cancel_reserved_instances_listing is not yet implemented')
raise NotImplementedError(
'ReservedInstances.cancel_reserved_instances_listing is not yet implemented')
def create_reserved_instances_listing(self):
if self.is_not_dryrun('CreateReservedInstances'):
raise NotImplementedError('ReservedInstances.create_reserved_instances_listing is not yet implemented')
raise NotImplementedError(
'ReservedInstances.create_reserved_instances_listing is not yet implemented')
def describe_reserved_instances(self):
raise NotImplementedError('ReservedInstances.describe_reserved_instances is not yet implemented')
raise NotImplementedError(
'ReservedInstances.describe_reserved_instances is not yet implemented')
def describe_reserved_instances_listings(self):
raise NotImplementedError('ReservedInstances.describe_reserved_instances_listings is not yet implemented')
raise NotImplementedError(
'ReservedInstances.describe_reserved_instances_listings is not yet implemented')
def describe_reserved_instances_offerings(self):
raise NotImplementedError('ReservedInstances.describe_reserved_instances_offerings is not yet implemented')
raise NotImplementedError(
'ReservedInstances.describe_reserved_instances_offerings is not yet implemented')
def purchase_reserved_instances_offering(self):
if self.is_not_dryrun('PurchaseReservedInstances'):
raise NotImplementedError('ReservedInstances.purchase_reserved_instances_offering is not yet implemented')
raise NotImplementedError(
'ReservedInstances.purchase_reserved_instances_offering is not yet implemented')

View file

@ -8,24 +8,28 @@ class RouteTables(BaseResponse):
def associate_route_table(self):
route_table_id = self.querystring.get('RouteTableId')[0]
subnet_id = self.querystring.get('SubnetId')[0]
association_id = self.ec2_backend.associate_route_table(route_table_id, subnet_id)
association_id = self.ec2_backend.associate_route_table(
route_table_id, subnet_id)
template = self.response_template(ASSOCIATE_ROUTE_TABLE_RESPONSE)
return template.render(association_id=association_id)
def create_route(self):
route_table_id = self.querystring.get('RouteTableId')[0]
destination_cidr_block = self.querystring.get('DestinationCidrBlock')[0]
destination_cidr_block = self.querystring.get(
'DestinationCidrBlock')[0]
gateway_id = optional_from_querystring('GatewayId', self.querystring)
instance_id = optional_from_querystring('InstanceId', self.querystring)
interface_id = optional_from_querystring('NetworkInterfaceId', self.querystring)
pcx_id = optional_from_querystring('VpcPeeringConnectionId', self.querystring)
interface_id = optional_from_querystring(
'NetworkInterfaceId', self.querystring)
pcx_id = optional_from_querystring(
'VpcPeeringConnectionId', self.querystring)
self.ec2_backend.create_route(route_table_id, destination_cidr_block,
gateway_id=gateway_id,
instance_id=instance_id,
interface_id=interface_id,
vpc_peering_connection_id=pcx_id)
gateway_id=gateway_id,
instance_id=instance_id,
interface_id=interface_id,
vpc_peering_connection_id=pcx_id)
template = self.response_template(CREATE_ROUTE_RESPONSE)
return template.render()
@ -38,7 +42,8 @@ class RouteTables(BaseResponse):
def delete_route(self):
route_table_id = self.querystring.get('RouteTableId')[0]
destination_cidr_block = self.querystring.get('DestinationCidrBlock')[0]
destination_cidr_block = self.querystring.get(
'DestinationCidrBlock')[0]
self.ec2_backend.delete_route(route_table_id, destination_cidr_block)
template = self.response_template(DELETE_ROUTE_RESPONSE)
return template.render()
@ -52,7 +57,8 @@ class RouteTables(BaseResponse):
def describe_route_tables(self):
route_table_ids = route_table_ids_from_querystring(self.querystring)
filters = filters_from_querystring(self.querystring)
route_tables = self.ec2_backend.get_all_route_tables(route_table_ids, filters)
route_tables = self.ec2_backend.get_all_route_tables(
route_table_ids, filters)
template = self.response_template(DESCRIBE_ROUTE_TABLES_RESPONSE)
return template.render(route_tables=route_tables)
@ -64,18 +70,21 @@ class RouteTables(BaseResponse):
def replace_route(self):
route_table_id = self.querystring.get('RouteTableId')[0]
destination_cidr_block = self.querystring.get('DestinationCidrBlock')[0]
destination_cidr_block = self.querystring.get(
'DestinationCidrBlock')[0]
gateway_id = optional_from_querystring('GatewayId', self.querystring)
instance_id = optional_from_querystring('InstanceId', self.querystring)
interface_id = optional_from_querystring('NetworkInterfaceId', self.querystring)
pcx_id = optional_from_querystring('VpcPeeringConnectionId', self.querystring)
interface_id = optional_from_querystring(
'NetworkInterfaceId', self.querystring)
pcx_id = optional_from_querystring(
'VpcPeeringConnectionId', self.querystring)
self.ec2_backend.replace_route(route_table_id, destination_cidr_block,
gateway_id=gateway_id,
instance_id=instance_id,
interface_id=interface_id,
vpc_peering_connection_id=pcx_id)
gateway_id=gateway_id,
instance_id=instance_id,
interface_id=interface_id,
vpc_peering_connection_id=pcx_id)
template = self.response_template(REPLACE_ROUTE_RESPONSE)
return template.render()
@ -83,8 +92,10 @@ class RouteTables(BaseResponse):
def replace_route_table_association(self):
route_table_id = self.querystring.get('RouteTableId')[0]
association_id = self.querystring.get('AssociationId')[0]
new_association_id = self.ec2_backend.replace_route_table_association(association_id, route_table_id)
template = self.response_template(REPLACE_ROUTE_TABLE_ASSOCIATION_RESPONSE)
new_association_id = self.ec2_backend.replace_route_table_association(
association_id, route_table_id)
template = self.response_template(
REPLACE_ROUTE_TABLE_ASSOCIATION_RESPONSE)
return template.render(association_id=new_association_id)

View file

@ -1,7 +1,5 @@
from __future__ import unicode_literals
import collections
from moto.core.responses import BaseResponse
from moto.ec2.utils import filters_from_querystring
@ -55,10 +53,11 @@ def process_rules_from_querystring(querystring):
source_groups.append(group_dict['GroupName'][0])
yield (group_name_or_id, ip_protocol, from_port, to_port, ip_ranges,
source_groups, source_group_ids)
source_groups, source_group_ids)
class SecurityGroups(BaseResponse):
def authorize_security_group_egress(self):
if self.is_not_dryrun('GrantSecurityGroupEgress'):
for args in process_rules_from_querystring(self.querystring):
@ -77,12 +76,15 @@ class SecurityGroups(BaseResponse):
vpc_id = self.querystring.get("VpcId", [None])[0]
if self.is_not_dryrun('CreateSecurityGroup'):
group = self.ec2_backend.create_security_group(name, description, vpc_id=vpc_id)
group = self.ec2_backend.create_security_group(
name, description, vpc_id=vpc_id)
template = self.response_template(CREATE_SECURITY_GROUP_RESPONSE)
return template.render(group=group)
def delete_security_group(self):
# TODO this should raise an error if there are instances in the group. See http://docs.aws.amazon.com/AWSEC2/latest/APIReference/ApiReference-query-DeleteSecurityGroup.html
# TODO this should raise an error if there are instances in the group.
# See
# http://docs.aws.amazon.com/AWSEC2/latest/APIReference/ApiReference-query-DeleteSecurityGroup.html
name = self.querystring.get('GroupName')
sg_id = self.querystring.get('GroupId')

View file

@ -7,21 +7,25 @@ class SpotFleets(BaseResponse):
def cancel_spot_fleet_requests(self):
spot_fleet_request_ids = self._get_multi_param("SpotFleetRequestId.")
terminate_instances = self._get_param("TerminateInstances")
spot_fleets = self.ec2_backend.cancel_spot_fleet_requests(spot_fleet_request_ids, terminate_instances)
spot_fleets = self.ec2_backend.cancel_spot_fleet_requests(
spot_fleet_request_ids, terminate_instances)
template = self.response_template(CANCEL_SPOT_FLEETS_TEMPLATE)
return template.render(spot_fleets=spot_fleets)
def describe_spot_fleet_instances(self):
spot_fleet_request_id = self._get_param("SpotFleetRequestId")
spot_requests = self.ec2_backend.describe_spot_fleet_instances(spot_fleet_request_id)
template = self.response_template(DESCRIBE_SPOT_FLEET_INSTANCES_TEMPLATE)
spot_requests = self.ec2_backend.describe_spot_fleet_instances(
spot_fleet_request_id)
template = self.response_template(
DESCRIBE_SPOT_FLEET_INSTANCES_TEMPLATE)
return template.render(spot_request_id=spot_fleet_request_id, spot_requests=spot_requests)
def describe_spot_fleet_requests(self):
spot_fleet_request_ids = self._get_multi_param("SpotFleetRequestId.")
requests = self.ec2_backend.describe_spot_fleet_requests(spot_fleet_request_ids)
requests = self.ec2_backend.describe_spot_fleet_requests(
spot_fleet_request_ids)
template = self.response_template(DESCRIBE_SPOT_FLEET_TEMPLATE)
return template.render(requests=requests)
@ -32,7 +36,8 @@ class SpotFleets(BaseResponse):
iam_fleet_role = spot_config['iam_fleet_role']
allocation_strategy = spot_config['allocation_strategy']
launch_specs = self._get_list_prefix("SpotFleetRequestConfig.LaunchSpecifications")
launch_specs = self._get_list_prefix(
"SpotFleetRequestConfig.LaunchSpecifications")
request = self.ec2_backend.request_spot_fleet(
spot_price=spot_price,
@ -45,6 +50,7 @@ class SpotFleets(BaseResponse):
template = self.response_template(REQUEST_SPOT_FLEET_TEMPLATE)
return template.render(request=request)
REQUEST_SPOT_FLEET_TEMPLATE = """<RequestSpotFleetResponse xmlns="http://ec2.amazonaws.com/doc/2016-09-15/">
<requestId>60262cc5-2bd4-4c8d-98ed-example</requestId>
<spotFleetRequestId>{{ request.id }}</spotFleetRequestId>

View file

@ -8,29 +8,35 @@ class SpotInstances(BaseResponse):
def cancel_spot_instance_requests(self):
request_ids = self._get_multi_param('SpotInstanceRequestId')
if self.is_not_dryrun('CancelSpotInstance'):
requests = self.ec2_backend.cancel_spot_instance_requests(request_ids)
requests = self.ec2_backend.cancel_spot_instance_requests(
request_ids)
template = self.response_template(CANCEL_SPOT_INSTANCES_TEMPLATE)
return template.render(requests=requests)
def create_spot_datafeed_subscription(self):
if self.is_not_dryrun('CreateSpotDatafeedSubscription'):
raise NotImplementedError('SpotInstances.create_spot_datafeed_subscription is not yet implemented')
raise NotImplementedError(
'SpotInstances.create_spot_datafeed_subscription is not yet implemented')
def delete_spot_datafeed_subscription(self):
if self.is_not_dryrun('DeleteSpotDatafeedSubscription'):
raise NotImplementedError('SpotInstances.delete_spot_datafeed_subscription is not yet implemented')
raise NotImplementedError(
'SpotInstances.delete_spot_datafeed_subscription is not yet implemented')
def describe_spot_datafeed_subscription(self):
raise NotImplementedError('SpotInstances.describe_spot_datafeed_subscription is not yet implemented')
raise NotImplementedError(
'SpotInstances.describe_spot_datafeed_subscription is not yet implemented')
def describe_spot_instance_requests(self):
filters = filters_from_querystring(self.querystring)
requests = self.ec2_backend.describe_spot_instance_requests(filters=filters)
requests = self.ec2_backend.describe_spot_instance_requests(
filters=filters)
template = self.response_template(DESCRIBE_SPOT_INSTANCES_TEMPLATE)
return template.render(requests=requests)
def describe_spot_price_history(self):
raise NotImplementedError('SpotInstances.describe_spot_price_history is not yet implemented')
raise NotImplementedError(
'SpotInstances.describe_spot_price_history is not yet implemented')
def request_spot_instances(self):
price = self._get_param('SpotPrice')
@ -42,13 +48,17 @@ class SpotInstances(BaseResponse):
launch_group = self._get_param('LaunchGroup')
availability_zone_group = self._get_param('AvailabilityZoneGroup')
key_name = self._get_param('LaunchSpecification.KeyName')
security_groups = self._get_multi_param('LaunchSpecification.SecurityGroup')
security_groups = self._get_multi_param(
'LaunchSpecification.SecurityGroup')
user_data = self._get_param('LaunchSpecification.UserData')
instance_type = self._get_param('LaunchSpecification.InstanceType', 'm1.small')
placement = self._get_param('LaunchSpecification.Placement.AvailabilityZone')
instance_type = self._get_param(
'LaunchSpecification.InstanceType', 'm1.small')
placement = self._get_param(
'LaunchSpecification.Placement.AvailabilityZone')
kernel_id = self._get_param('LaunchSpecification.KernelId')
ramdisk_id = self._get_param('LaunchSpecification.RamdiskId')
monitoring_enabled = self._get_param('LaunchSpecification.Monitoring.Enabled')
monitoring_enabled = self._get_param(
'LaunchSpecification.Monitoring.Enabled')
subnet_id = self._get_param('LaunchSpecification.SubnetId')
if self.is_not_dryrun('RequestSpotInstance'):

View file

@ -5,13 +5,15 @@ from moto.ec2.utils import filters_from_querystring
class Subnets(BaseResponse):
def create_subnet(self):
vpc_id = self.querystring.get('VpcId')[0]
cidr_block = self.querystring.get('CidrBlock')[0]
if 'AvailabilityZone' in self.querystring:
availability_zone = self.querystring['AvailabilityZone'][0]
else:
zone = random.choice(self.ec2_backend.describe_availability_zones())
zone = random.choice(
self.ec2_backend.describe_availability_zones())
availability_zone = zone.name
subnet = self.ec2_backend.create_subnet(
vpc_id,

View file

@ -8,7 +8,8 @@ from moto.ec2.utils import sequence_from_querystring, tags_from_query_string, fi
class TagResponse(BaseResponse):
def create_tags(self):
resource_ids = sequence_from_querystring('ResourceId', self.querystring)
resource_ids = sequence_from_querystring(
'ResourceId', self.querystring)
validate_resource_ids(resource_ids)
self.ec2_backend.do_resources_exist(resource_ids)
tags = tags_from_query_string(self.querystring)
@ -17,7 +18,8 @@ class TagResponse(BaseResponse):
return CREATE_RESPONSE
def delete_tags(self):
resource_ids = sequence_from_querystring('ResourceId', self.querystring)
resource_ids = sequence_from_querystring(
'ResourceId', self.querystring)
validate_resource_ids(resource_ids)
tags = tags_from_query_string(self.querystring)
if self.is_not_dryrun('DeleteTags'):

View file

@ -4,6 +4,7 @@ from moto.ec2.utils import filters_from_querystring
class VirtualPrivateGateways(BaseResponse):
def attach_vpn_gateway(self):
vpn_gateway_id = self.querystring.get('VpnGatewayId')[0]
vpc_id = self.querystring.get('VpcId')[0]
@ -42,6 +43,7 @@ class VirtualPrivateGateways(BaseResponse):
template = self.response_template(DETACH_VPN_GATEWAY_RESPONSE)
return template.render(attachment=attachment)
CREATE_VPN_GATEWAY_RESPONSE = """
<CreateVpnGatewayResponse xmlns="http://ec2.amazonaws.com/doc/2013-10-15/">
<requestId>7a62c49f-347e-4fc4-9331-6e8eEXAMPLE</requestId>

View file

@ -3,11 +3,15 @@ from moto.core.responses import BaseResponse
class VMExport(BaseResponse):
def cancel_export_task(self):
raise NotImplementedError('VMExport.cancel_export_task is not yet implemented')
raise NotImplementedError(
'VMExport.cancel_export_task is not yet implemented')
def create_instance_export_task(self):
raise NotImplementedError('VMExport.create_instance_export_task is not yet implemented')
raise NotImplementedError(
'VMExport.create_instance_export_task is not yet implemented')
def describe_export_tasks(self):
raise NotImplementedError('VMExport.describe_export_tasks is not yet implemented')
raise NotImplementedError(
'VMExport.describe_export_tasks is not yet implemented')

View file

@ -3,14 +3,19 @@ from moto.core.responses import BaseResponse
class VMImport(BaseResponse):
def cancel_conversion_task(self):
raise NotImplementedError('VMImport.cancel_conversion_task is not yet implemented')
raise NotImplementedError(
'VMImport.cancel_conversion_task is not yet implemented')
def describe_conversion_tasks(self):
raise NotImplementedError('VMImport.describe_conversion_tasks is not yet implemented')
raise NotImplementedError(
'VMImport.describe_conversion_tasks is not yet implemented')
def import_instance(self):
raise NotImplementedError('VMImport.import_instance is not yet implemented')
raise NotImplementedError(
'VMImport.import_instance is not yet implemented')
def import_volume(self):
raise NotImplementedError('VMImport.import_volume is not yet implemented')
raise NotImplementedError(
'VMImport.import_volume is not yet implemented')

View file

@ -3,34 +3,41 @@ from moto.core.responses import BaseResponse
class VPCPeeringConnections(BaseResponse):
def create_vpc_peering_connection(self):
vpc = self.ec2_backend.get_vpc(self.querystring.get('VpcId')[0])
peer_vpc = self.ec2_backend.get_vpc(self.querystring.get('PeerVpcId')[0])
peer_vpc = self.ec2_backend.get_vpc(
self.querystring.get('PeerVpcId')[0])
vpc_pcx = self.ec2_backend.create_vpc_peering_connection(vpc, peer_vpc)
template = self.response_template(CREATE_VPC_PEERING_CONNECTION_RESPONSE)
template = self.response_template(
CREATE_VPC_PEERING_CONNECTION_RESPONSE)
return template.render(vpc_pcx=vpc_pcx)
def delete_vpc_peering_connection(self):
vpc_pcx_id = self.querystring.get('VpcPeeringConnectionId')[0]
vpc_pcx = self.ec2_backend.delete_vpc_peering_connection(vpc_pcx_id)
template = self.response_template(DELETE_VPC_PEERING_CONNECTION_RESPONSE)
template = self.response_template(
DELETE_VPC_PEERING_CONNECTION_RESPONSE)
return template.render(vpc_pcx=vpc_pcx)
def describe_vpc_peering_connections(self):
vpc_pcxs = self.ec2_backend.get_all_vpc_peering_connections()
template = self.response_template(DESCRIBE_VPC_PEERING_CONNECTIONS_RESPONSE)
template = self.response_template(
DESCRIBE_VPC_PEERING_CONNECTIONS_RESPONSE)
return template.render(vpc_pcxs=vpc_pcxs)
def accept_vpc_peering_connection(self):
vpc_pcx_id = self.querystring.get('VpcPeeringConnectionId')[0]
vpc_pcx = self.ec2_backend.accept_vpc_peering_connection(vpc_pcx_id)
template = self.response_template(ACCEPT_VPC_PEERING_CONNECTION_RESPONSE)
template = self.response_template(
ACCEPT_VPC_PEERING_CONNECTION_RESPONSE)
return template.render(vpc_pcx=vpc_pcx)
def reject_vpc_peering_connection(self):
vpc_pcx_id = self.querystring.get('VpcPeeringConnectionId')[0]
self.ec2_backend.reject_vpc_peering_connection(vpc_pcx_id)
template = self.response_template(REJECT_VPC_PEERING_CONNECTION_RESPONSE)
template = self.response_template(
REJECT_VPC_PEERING_CONNECTION_RESPONSE)
return template.render()

View file

@ -5,9 +5,11 @@ from moto.ec2.utils import filters_from_querystring, vpc_ids_from_querystring
class VPCs(BaseResponse):
def create_vpc(self):
cidr_block = self.querystring.get('CidrBlock')[0]
instance_tenancy = self.querystring.get('InstanceTenancy', ['default'])[0]
instance_tenancy = self.querystring.get(
'InstanceTenancy', ['default'])[0]
vpc = self.ec2_backend.create_vpc(cidr_block, instance_tenancy)
template = self.response_template(CREATE_VPC_RESPONSE)
return template.render(vpc=vpc)
@ -40,7 +42,8 @@ class VPCs(BaseResponse):
if self.querystring.get('%s.Value' % attribute):
attr_name = camelcase_to_underscores(attribute)
attr_value = self.querystring.get('%s.Value' % attribute)[0]
self.ec2_backend.modify_vpc_attribute(vpc_id, attr_name, attr_value)
self.ec2_backend.modify_vpc_attribute(
vpc_id, attr_name, attr_value)
return MODIFY_VPC_ATTRIBUTE_RESPONSE

View file

@ -4,23 +4,27 @@ from moto.ec2.utils import filters_from_querystring, sequence_from_querystring
class VPNConnections(BaseResponse):
def create_vpn_connection(self):
type = self.querystring.get("Type", [None])[0]
cgw_id = self.querystring.get("CustomerGatewayId", [None])[0]
vgw_id = self.querystring.get("VPNGatewayId", [None])[0]
static_routes = self.querystring.get("StaticRoutesOnly", [None])[0]
vpn_connection = self.ec2_backend.create_vpn_connection(type, cgw_id, vgw_id, static_routes_only=static_routes)
vpn_connection = self.ec2_backend.create_vpn_connection(
type, cgw_id, vgw_id, static_routes_only=static_routes)
template = self.response_template(CREATE_VPN_CONNECTION_RESPONSE)
return template.render(vpn_connection=vpn_connection)
def delete_vpn_connection(self):
vpn_connection_id = self.querystring.get('VpnConnectionId')[0]
vpn_connection = self.ec2_backend.delete_vpn_connection(vpn_connection_id)
vpn_connection = self.ec2_backend.delete_vpn_connection(
vpn_connection_id)
template = self.response_template(DELETE_VPN_CONNECTION_RESPONSE)
return template.render(vpn_connection=vpn_connection)
def describe_vpn_connections(self):
vpn_connection_ids = sequence_from_querystring('VpnConnectionId', self.querystring)
vpn_connection_ids = sequence_from_querystring(
'VpnConnectionId', self.querystring)
filters = filters_from_querystring(self.querystring)
vpn_connections = self.ec2_backend.get_all_vpn_connections(
vpn_connection_ids=vpn_connection_ids, filters=filters)

View file

@ -3,14 +3,19 @@ from moto.core.responses import BaseResponse
class Windows(BaseResponse):
def bundle_instance(self):
raise NotImplementedError('Windows.bundle_instance is not yet implemented')
raise NotImplementedError(
'Windows.bundle_instance is not yet implemented')
def cancel_bundle_task(self):
raise NotImplementedError('Windows.cancel_bundle_task is not yet implemented')
raise NotImplementedError(
'Windows.cancel_bundle_task is not yet implemented')
def describe_bundle_tasks(self):
raise NotImplementedError('Windows.describe_bundle_tasks is not yet implemented')
raise NotImplementedError(
'Windows.describe_bundle_tasks is not yet implemented')
def get_password_data(self):
raise NotImplementedError('Windows.get_password_data is not yet implemented')
raise NotImplementedError(
'Windows.get_password_data is not yet implemented')

View file

@ -32,13 +32,15 @@ EC2_RESOURCE_TO_PREFIX = {
'vpn-gateway': 'vgw'}
EC2_PREFIX_TO_RESOURCE = dict((v, k) for (k, v) in EC2_RESOURCE_TO_PREFIX.items())
EC2_PREFIX_TO_RESOURCE = dict((v, k)
for (k, v) in EC2_RESOURCE_TO_PREFIX.items())
def random_id(prefix='', size=8):
chars = list(range(10)) + ['a', 'b', 'c', 'd', 'e', 'f']
resource_id = ''.join(six.text_type(random.choice(chars)) for x in range(size))
resource_id = ''.join(six.text_type(random.choice(chars))
for x in range(size))
return '{0}-{1}'.format(prefix, resource_id)
@ -228,7 +230,8 @@ def tags_from_query_string(querystring_dict):
tag_key = querystring_dict.get("Tag.{0}.Key".format(tag_index))[0]
tag_value_key = "Tag.{0}.Value".format(tag_index)
if tag_value_key in querystring_dict:
response_values[tag_key] = querystring_dict.get(tag_value_key)[0]
response_values[tag_key] = querystring_dict.get(tag_value_key)[
0]
else:
response_values[tag_key] = None
return response_values
@ -262,7 +265,8 @@ def dhcp_configuration_from_querystring(querystring, option=u'DhcpConfiguration'
key_index = key.split(".")[1]
value_index = 1
while True:
value_key = u'{0}.{1}.Value.{2}'.format(option, key_index, value_index)
value_key = u'{0}.{1}.Value.{2}'.format(
option, key_index, value_index)
if value_key in querystring:
values.extend(querystring[value_key])
else:
@ -337,16 +341,20 @@ def get_obj_tag(obj, filter_name):
tags = dict((tag['key'], tag['value']) for tag in obj.get_tags())
return tags.get(tag_name)
def get_obj_tag_names(obj):
tags = set((tag['key'] for tag in obj.get_tags()))
return tags
def get_obj_tag_values(obj):
tags = set((tag['value'] for tag in obj.get_tags()))
return tags
def tag_filter_matches(obj, filter_name, filter_values):
regex_filters = [re.compile(simple_aws_filter_to_re(f)) for f in filter_values]
regex_filters = [re.compile(simple_aws_filter_to_re(f))
for f in filter_values]
if filter_name == 'tag-key':
tag_values = get_obj_tag_names(obj)
elif filter_name == 'tag-value':
@ -400,7 +408,7 @@ def instance_value_in_filter_values(instance_value, filter_values):
if not set(filter_values).intersection(set(instance_value)):
return False
elif instance_value not in filter_values:
return False
return False
return True
@ -464,7 +472,8 @@ def is_filter_matching(obj, filter, filter_value):
def generic_filter(filters, objects):
if filters:
for (_filter, _filter_value) in filters.items():
objects = [obj for obj in objects if is_filter_matching(obj, _filter, _filter_value)]
objects = [obj for obj in objects if is_filter_matching(
obj, _filter, _filter_value)]
return objects
@ -480,8 +489,10 @@ def simple_aws_filter_to_re(filter_string):
def random_key_pair():
def random_hex():
return chr(random.choice(list(range(48, 58)) + list(range(97, 102))))
def random_fingerprint():
return ':'.join([random_hex()+random_hex() for i in range(20)])
return ':'.join([random_hex() + random_hex() for i in range(20)])
def random_material():
return ''.join([
chr(random.choice(list(range(65, 91)) + list(range(48, 58)) +
@ -489,7 +500,7 @@ def random_key_pair():
for i in range(1000)
])
material = "---- BEGIN RSA PRIVATE KEY ----" + random_material() + \
"-----END RSA PRIVATE KEY-----"
"-----END RSA PRIVATE KEY-----"
return {
'fingerprint': random_fingerprint(),
'material': material
@ -500,9 +511,11 @@ def get_prefix(resource_id):
resource_id_prefix, separator, after = resource_id.partition('-')
if resource_id_prefix == EC2_RESOURCE_TO_PREFIX['network-interface']:
if after.startswith('attach'):
resource_id_prefix = EC2_RESOURCE_TO_PREFIX['network-interface-attachment']
resource_id_prefix = EC2_RESOURCE_TO_PREFIX[
'network-interface-attachment']
if resource_id_prefix not in EC2_RESOURCE_TO_PREFIX.values():
uuid4hex = re.compile('[0-9a-f]{12}4[0-9a-f]{3}[89ab][0-9a-f]{15}\Z', re.I)
uuid4hex = re.compile(
'[0-9a-f]{12}4[0-9a-f]{3}[89ab][0-9a-f]{15}\Z', re.I)
if uuid4hex.match(resource_id) is not None:
resource_id_prefix = EC2_RESOURCE_TO_PREFIX['reserved-instance']
else:
@ -539,20 +552,20 @@ def generate_instance_identity_document(instance):
"""
document = {
'devPayProductCodes': None,
'availabilityZone': instance.placement['AvailabilityZone'],
'privateIp': instance.private_ip_address,
'version': '2010-8-31',
'region': instance.placement['AvailabilityZone'][:-1],
'instanceId': instance.id,
'billingProducts': None,
'instanceType': instance.instance_type,
'accountId': '012345678910',
'pendingTime': '2015-11-19T16:32:11Z',
'imageId': instance.image_id,
'kernelId': instance.kernel_id,
'ramdiskId': instance.ramdisk_id,
'architecture': instance.architecture,
}
'devPayProductCodes': None,
'availabilityZone': instance.placement['AvailabilityZone'],
'privateIp': instance.private_ip_address,
'version': '2010-8-31',
'region': instance.placement['AvailabilityZone'][:-1],
'instanceId': instance.id,
'billingProducts': None,
'instanceType': instance.instance_type,
'accountId': '012345678910',
'pendingTime': '2015-11-19T16:32:11Z',
'imageId': instance.image_id,
'kernelId': instance.kernel_id,
'ramdiskId': instance.ramdisk_id,
'architecture': instance.architecture,
}
return document