Added improvements and documented return structure (#2320)

reviewable/pr18780/r1
Constantin 9 years ago committed by Brian Coca
parent bfa0a94c27
commit b3bcd5a433

@ -72,12 +72,13 @@ options:
default: null
delete_snapshot:
description:
- Whether or not to delete an AMI while deregistering it.
- Whether or not to delete snapshots when deregistering AMI.
required: false
default: null
default: "no"
choices: [ "yes", "no" ]
tags:
description:
- a hash/dictionary of tags to add to the new image; '{"key":"value"}' and '{"key":"value","key":"value"}'
- a dictionary of tags to add to the new image; '{"key":"value"}' and '{"key":"value","key":"value"}'
required: false
default: null
version_added: "2.0"
@ -87,7 +88,9 @@ options:
required: false
default: null
version_added: "2.0"
author: "Evan Duffield (@scicoin-project) <eduffield@iacquire.com>"
author:
- "Evan Duffield (@scicoin-project) <eduffield@iacquire.com>"
- "Constantin Bugneac (@Constantin07) <constantin.bugneac@endava.com>"
extends_documentation_fragment:
- aws
- ec2
@ -150,22 +153,22 @@ EXAMPLES = '''
no_device: yes
register: instance
# Deregister/Delete AMI
# Deregister/Delete AMI (keep associated snapshots)
- ec2_ami:
aws_access_key: xxxxxxxxxxxxxxxxxxxxxxx
aws_secret_key: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
region: xxxxxx
image_id: "{{ instance.image_id }}"
delete_snapshot: True
delete_snapshot: False
state: absent
# Deregister AMI
# Deregister AMI (delete associated snapshots too)
- ec2_ami:
aws_access_key: xxxxxxxxxxxxxxxxxxxxxxx
aws_secret_key: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
region: xxxxxx
image_id: "{{ instance.image_id }}"
delete_snapshot: False
delete_snapshot: True
state: absent
# Update AMI Launch Permissions, making it public
@ -189,6 +192,102 @@ EXAMPLES = '''
user_ids: ['123456789012']
'''
RETURN = '''
architecture:
description: architecture of image
returned: when AMI is created or already exists
type: string
sample: "x86_64"
block_device_mapping:
description: block device mapping associated with image
returned: when AMI is created or already exists
type: a dictionary of block devices
sample: {
"/dev/sda1": {
"delete_on_termination": true,
"encrypted": false,
"size": 10,
"snapshot_id": "snap-1a03b80e7",
"volume_type": "standard"
}
creationDate:
description: creation date of image
returned: when AMI is created or already exists
type: string
sample: "2015-10-15T22:43:44.000Z"
description:
description: description of image
returned: when AMI is created or already exists
type: string
sample: "nat-server"
hypervisor:
description: type of hypervisor
returned: when AMI is created or already exists
type: string
sample: "xen"
is_public:
description: whether image is public
returned: when AMI is created or already exists
type: bool
sample: false
location:
description: location of image
returned: when AMI is created or already exists
type: string
sample: "315210894379/nat-server"
name:
description: ami name of image
returned: when AMI is created or already exists
type: string
sample: "nat-server"
owner_id:
description: owner of image
returned: when AMI is created or already exists
type: string
sample: "435210894375"
platform:
description: plaform of image
returned: when AMI is created or already exists
type: string
sample: null
root_device_name:
description: root device name of image
returned: when AMI is created or already exists
type: string
sample: "/dev/sda1"
root_device_type:
description: root device type of image
returned: when AMI is created or already exists
type: string
sample: "ebs"
state:
description: state of image
returned: when AMI is created or already exists
type: string
sample: "available"
tags:
description: a dictionary of tags assigned to image
returned: when AMI is created or already exists
type: dictionary of tags
sample: {
"Env": "devel",
"Name": "nat-server"
}
virtualization_type:
description: image virtualization type
returned: when AMI is created or already exists
type: string
sample: "hvm"
snapshots_deleted:
description: a list of snapshot ids deleted after deregistering image
returned: after AMI is deregistered, if 'delete_snapshot' is set to 'yes'
type: list
sample: [
"snap-fbcccb8f",
"snap-cfe7cdb4"
]
'''
import sys
import time
@ -201,6 +300,47 @@ except ImportError:
HAS_BOTO = False
def get_block_device_mapping(image):
"""
Retrieves block device mapping from AMI
"""
bdm_dict = dict()
if image is not None and hasattr(image, 'block_device_mapping'):
bdm = getattr(image,'block_device_mapping')
for device_name in bdm.keys():
bdm_dict[device_name] = {
'size': bdm[device_name].size,
'snapshot_id': bdm[device_name].snapshot_id,
'volume_type': bdm[device_name].volume_type,
'encrypted': bdm[device_name].encrypted,
'delete_on_termination': bdm[device_name].delete_on_termination
}
return bdm_dict
def get_ami_info(image):
return dict(
image_id=image.id,
state=image.state,
architecture=image.architecture,
block_device_mapping=get_block_device_mapping(image),
creationDate=image.creationDate,
description=image.description,
hypervisor=image.hypervisor,
is_public=image.is_public,
location=image.location,
ownerId=image.ownerId,
root_device_name=image.root_device_name,
root_device_type=image.root_device_type,
tags=image.tags,
virtualization_type = image.virtualization_type
)
def create_image(module, ec2):
"""
Creates new AMI
@ -275,7 +415,7 @@ def create_image(module, ec2):
except boto.exception.BotoServerError, e:
module.fail_json(msg="%s: %s" % (e.error_code, e.error_message), image_id=image_id)
module.exit_json(msg="AMI creation operation complete", image_id=image_id, state=img.state, changed=True)
module.exit_json(msg="AMI creation operation complete", changed=True, **get_ami_info(img))
def deregister_image(module, ec2):
@ -292,13 +432,23 @@ def deregister_image(module, ec2):
if img == None:
module.fail_json(msg = "Image %s does not exist" % image_id, changed=False)
# Get all associated snapshot ids before deregistering image otherwise this information becomes unavailable
snapshots = []
if hasattr(img, 'block_device_mapping'):
for key in img.block_device_mapping:
snapshots.append(img.block_device_mapping[key].snapshot_id)
# When trying to re-delete already deleted image it doesn't raise an exception
# It just returns an object without image attributes
if hasattr(img, 'id'):
try:
params = {'image_id': image_id,
'delete_snapshot': delete_snapshot}
res = ec2.deregister_image(**params)
except boto.exception.BotoServerError, e:
module.fail_json(msg = "%s: %s" % (e.error_code, e.error_message))
else:
module.exit_json(msg = "Image %s has already been deleted" % image_id, changed=False)
# wait here until the image is gone
img = ec2.get_image(image_id)
@ -308,8 +458,20 @@ def deregister_image(module, ec2):
time.sleep(3)
if wait and wait_timeout <= time.time():
# waiting took too long
module.fail_json(msg = "timed out waiting for image to be reregistered/deleted")
module.fail_json(msg = "timed out waiting for image to be deregistered/deleted")
# Boto library has hardcoded the deletion of the snapshot for the root volume mounted as '/dev/sda1' only
# Make it possible to delete all snapshots which belong to image, including root block device mapped as '/dev/xvda'
if delete_snapshot:
try:
for snapshot_id in snapshots:
ec2.delete_snapshot(snapshot_id)
except boto.exception.BotoServerError, e:
if e.error_code == 'InvalidSnapshot.NotFound':
# Don't error out if root volume snapshot was already deleted as part of deregister_image
pass
module.exit_json(msg="AMI deregister/delete operation complete", changed=True, snapshots_deleted=snapshots)
else:
module.exit_json(msg="AMI deregister/delete operation complete", changed=True)
@ -348,12 +510,12 @@ def main():
argument_spec.update(dict(
instance_id = dict(),
image_id = dict(),
delete_snapshot = dict(),
delete_snapshot = dict(default=False, type='bool'),
name = dict(),
wait = dict(type="bool", default=False),
wait = dict(type='bool', default=False),
wait_timeout = dict(default=900),
description = dict(default=""),
no_reboot = dict(default=False, type="bool"),
no_reboot = dict(default=False, type='bool'),
state = dict(default='present'),
device_mapping = dict(type='list'),
tags = dict(type='dict'),
@ -393,4 +555,5 @@ def main():
from ansible.module_utils.basic import *
from ansible.module_utils.ec2 import *
main()
if __name__ == '__main__':
main()

Loading…
Cancel
Save