from jinja2 import Template
from moto.core.responses import BaseResponse
from moto.ec2.models import ec2_backend
class ElasticBlockStore(BaseResponse):
def attach_volume(self):
volume_id = self.querystring.get('VolumeId')[0]
instance_id = self.querystring.get('InstanceId')[0]
device_path = self.querystring.get('Device')[0]
attachment = ec2_backend.attach_volume(volume_id, instance_id, device_path)
if not attachment:
return "", dict(status=404)
template = Template(ATTACHED_VOLUME_RESPONSE)
return template.render(attachment=attachment)
def copy_snapshot(self):
raise NotImplementedError('ElasticBlockStore.copy_snapshot is not yet implemented')
def create_snapshot(self):
description = None
if 'Description' in self.querystring:
description = self.querystring.get('Description')[0]
volume_id = self.querystring.get('VolumeId')[0]
snapshot = ec2_backend.create_snapshot(volume_id, description)
template = Template(CREATE_SNAPSHOT_RESPONSE)
return template.render(snapshot=snapshot)
def create_volume(self):
size = self.querystring.get('Size')[0]
zone = self.querystring.get('AvailabilityZone')[0]
volume = ec2_backend.create_volume(size, zone)
template = Template(CREATE_VOLUME_RESPONSE)
return template.render(volume=volume)
def delete_snapshot(self):
snapshot_id = self.querystring.get('SnapshotId')[0]
success = ec2_backend.delete_snapshot(snapshot_id)
if not success:
# Snapshot doesn't exist
return "Snapshot with id {0} does not exist".format(snapshot_id), dict(status=404)
return DELETE_SNAPSHOT_RESPONSE
def delete_volume(self):
volume_id = self.querystring.get('VolumeId')[0]
success = ec2_backend.delete_volume(volume_id)
if not success:
# Volume doesn't exist
return "Volume with id {0} does not exist".format(volume_id), dict(status=404)
return DELETE_VOLUME_RESPONSE
def describe_snapshot_attribute(self):
raise NotImplementedError('ElasticBlockStore.describe_snapshot_attribute is not yet implemented')
def describe_snapshots(self):
snapshots = ec2_backend.describe_snapshots()
template = Template(DESCRIBE_SNAPSHOTS_RESPONSE)
return template.render(snapshots=snapshots)
def describe_volumes(self):
volumes = ec2_backend.describe_volumes()
template = Template(DESCRIBE_VOLUMES_RESPONSE)
return template.render(volumes=volumes)
def describe_volume_attribute(self):
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')
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]
attachment = ec2_backend.detach_volume(volume_id, instance_id, device_path)
if not attachment:
# Volume wasn't attached
return "Volume {0} can not be detached from {1} because it is not attached".format(volume_id, instance_id), dict(status=404)
template = Template(DETATCH_VOLUME_RESPONSE)
return template.render(attachment=attachment)
def enable_volume_io(self):
raise NotImplementedError('ElasticBlockStore.enable_volume_io is not yet implemented')
def import_volume(self):
raise NotImplementedError('ElasticBlockStore.import_volume is not yet implemented')
def modify_snapshot_attribute(self):
raise NotImplementedError('ElasticBlockStore.modify_snapshot_attribute is not yet implemented')
def modify_volume_attribute(self):
raise NotImplementedError('ElasticBlockStore.modify_volume_attribute is not yet implemented')
def reset_snapshot_attribute(self):
raise NotImplementedError('ElasticBlockStore.reset_snapshot_attribute is not yet implemented')
CREATE_VOLUME_RESPONSE = """
59dbff89-35bd-4eac-99ed-be587EXAMPLE
{{ volume.id }}
{{ volume.size }}
{{ volume.zone.name }}
creating
YYYY-MM-DDTHH:MM:SS.000Z
standard
"""
DESCRIBE_VOLUMES_RESPONSE = """
59dbff89-35bd-4eac-99ed-be587EXAMPLE
{% for volume in volumes %}
-
{{ volume.id }}
{{ volume.size }}
{{ volume.zone.name }}
{{ volume.status }}
YYYY-MM-DDTHH:MM:SS.SSSZ
{% if volume.attachment %}
-
{{ volume.id }}
{{ volume.attachment.instance.id }}
{{ volume.attachment.device }}
attached
YYYY-MM-DDTHH:MM:SS.SSSZ
false
{% endif %}
standard
{% endfor %}
"""
DELETE_VOLUME_RESPONSE = """
59dbff89-35bd-4eac-99ed-be587EXAMPLE
true
"""
ATTACHED_VOLUME_RESPONSE = """
59dbff89-35bd-4eac-99ed-be587EXAMPLE
{{ attachment.volume.id }}
{{ attachment.instance.id }}
{{ attachment.device }}
attaching
YYYY-MM-DDTHH:MM:SS.000Z
"""
DETATCH_VOLUME_RESPONSE = """
59dbff89-35bd-4eac-99ed-be587EXAMPLE
{{ attachment.volume.id }}
{{ attachment.instance.id }}
{{ attachment.device }}
detaching
YYYY-MM-DDTHH:MM:SS.000Z
"""
CREATE_SNAPSHOT_RESPONSE = """
59dbff89-35bd-4eac-99ed-be587EXAMPLE
{{ snapshot.id }}
{{ snapshot.volume.id }}
pending
YYYY-MM-DDTHH:MM:SS.000Z
111122223333
{{ snapshot.volume.size }}
{{ snapshot.description }}
"""
DESCRIBE_SNAPSHOTS_RESPONSE = """
59dbff89-35bd-4eac-99ed-be587EXAMPLE
{% for snapshot in snapshots %}
-
{{ snapshot.id }}
{{ snapshot.volume.id }}
pending
YYYY-MM-DDTHH:MM:SS.SSSZ
111122223333
{{ snapshot.volume.size }}
{{ snapshot.description }}
{% endfor %}
"""
DELETE_SNAPSHOT_RESPONSE = """
59dbff89-35bd-4eac-99ed-be587EXAMPLE
true
"""