lib/ansible/modules/cloud/alicloud/ali_image.py [135:368]:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    image_id: '{{ image_id }}'
    state: 'absent'
'''

RETURN = '''
image:
    description: Details about the image that was created.
    returned: except on delete
    type: dict
    sample: {
        "disk_device_mappings": {
            "disk_device_mapping": [
                {
                    "device": "/dev/xvda",
                    "format": "",
                    "import_ossbucket": "",
                    "import_ossobject": "",
                    "size": "40",
                    "snapshot_id": "s-2zeddnvf7uhw3xw3its6",
                    "type": "system"
                }
            ]
        },
        "id": "m-2zee2i7regbnhhawrwc2",
        "image_name": "image_test",
        "launch_time": "2017-10-17T09:33:02Z",
        "platform": "CentOS",
        "region_id": "cn-beijing",
        "size": 40,
        "status": "Available"
    }
image_id:
    description: return the created image id
    returned: except on absent
    type: str
    sample: "m-2ze43t8c5urc4mvkx3fp"
'''
import time
from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.alicloud_ecs import ecs_argument_spec, ecs_connect

HAS_FOOTMARK = False

try:
    from footmark.exception import ECSResponseError
    HAS_FOOTMARK = True
except ImportError:
    HAS_FOOTMARK = False


def get_image_detail(image):
    """
    Method call to get image details
    :param image:  Image object to Describe
    :return: return id, status and object of disk
    """
    if image:
        return {'id': image.image_id,
                'image_name': image.image_name,
                'size': image.size,
                'region_id': image.region,
                'disk_device_mappings': image.disk_device_mappings,
                'status': image.status,
                'platform': image.platform,
                'launch_time': image.creation_time
                }


def create_image(module, ecs, snapshot_id, image_name, image_version, description, instance_id,
                 disk_mapping, client_token, wait, wait_timeout):
    """
    Create a user-defined image with snapshots.
    :param module: Ansible module object
    :param ecs: authenticated ecs connection object
    :param snapshot_id: A user-defined image is created from the specified snapshot.
    :param image_name: image name which is to be created
    :param image_version: version of image
    :param description: description of the image
    :param instance_id: the specified instance_id
    :param disk_mapping: list relating device and disk
    :param client_token: Used to ensure the idempotence of the request
    :param wait: Used to indicate wait for instance to be running before running
    :param wait_timeout: Used to indicate how long to wait, default 300
    :return: id of image
    """
    changed = False
    if image_name:
        if len(image_name) < 2 or len(image_name) > 128:
            module.fail_json(msg='image_name must be 2 - 128 characters long')

        if image_name.startswith('http://') or image_name.startswith('https://'):
            module.fail_json(msg='image_name can not start with http:// or https://')
    if image_version:
        if image_version.isdigit():
            if int(image_version) < 1 or int(image_version) > 40:
                module.fail_json(msg='The permitted range of image_version is between 1 - 40')
        else:
            module.fail_json(msg='The permitted range of image_version is between 1 - 40, entered value is {0}'
                             .format(image_version))

    if disk_mapping:
        for mapping in disk_mapping:
            if mapping:
                if 'snapshot_id' not in mapping:
                    module.fail_json(msg='The snapshot_id of system disk is needed for disk mapping.')

                if not('disk_size' in mapping or 'snapshot_id' in mapping):
                    module.fail_json(msg='The disk_size and snapshot_id parameters '
                                         'are valid for disk mapping.')

                if 'disk_size' in mapping:
                    map_disk = mapping['disk_size']
                    if map_disk:
                        if str(map_disk).isdigit():
                            if int(map_disk) < 5 or int(map_disk) > 2000:
                                module.fail_json(msg='The permitted range of disk-size is 5 GB - 2000 GB ')
                        else:
                            module.fail_json(msg='The disk_size must be an integer value, entered value is {0}'.format(
                                map_disk))

    if not snapshot_id and not instance_id and not disk_mapping:
        module.fail_json(msg='Either of SnapshotId or InstanceId or disk_mapping, must be present for '
                             'create image operation to get performed')

    if (snapshot_id and instance_id) or (snapshot_id and disk_mapping) or (instance_id and disk_mapping):
        module.fail_json(msg='Only 1 of SnapshotId or InstanceId or disk_mapping, must be present for '
                             'create image operation to get performed')

    # call to create_image method in footmark
    try:
        changed, image_id, results, request_id = ecs.create_image(snapshot_id=snapshot_id, image_name=image_name,
                                                                  image_version=image_version, description=description,
                                                                  instance_id=instance_id, disk_mapping=disk_mapping,
                                                                  client_token=client_token, wait=wait,
                                                                  wait_timeout=wait_timeout)

        if 'error code' in str(results).lower():
            module.fail_json(changed=changed, msg=results)

    except ECSResponseError as e:
        module.fail_json(msg='Unable to create image, error: {0}'.format(e))
    return changed, image_id, results, request_id


def main():
    argument_spec = ecs_argument_spec()
    argument_spec.update(dict(
        image_id=dict(type='str'),
        snapshot_id=dict(type='str', aliases=['snapshot']),
        description=dict(type='str'),
        image_name=dict(type='str', aliases=['name']),
        image_version=dict(type='str', aliases=['version']),
        disk_mapping=dict(type='list', elements='dict'),
        instance_id=dict(aliases=['instance']),
        state=dict(default='present', choices=['present', 'absent'], type='str'),
        wait=dict(default=False, type='bool'),
        wait_timeout=dict(type='int', default=300)
    ))
    module = AnsibleModule(argument_spec=argument_spec)

    if HAS_FOOTMARK is False:
        module.fail_json(msg='footmark required for the module alicloud_security_group.')

    ecs = ecs_connect(module)
    state = module.params['state']
    image_id = module.params['image_id']
    image_name = module.params['image_name']

    changed = False
    current_image = None

    try:
        if image_id:
            images = ecs.get_all_images(image_id=image_id)
            if images and len(images) == 1:
                current_image = images[0]
        elif image_name and state == 'absent':
            images = ecs.get_all_images(image_name=image_name)
            if images:
                if len(images) == 1:
                    current_image = images[0]
                else:
                    images_ids = []
                    for i in images:
                        images_ids.append(i.id)
                    module.fail_json(msg="There is too many images match name '{0}', "
                                         "please use image_id or a new image_name to specify a unique image."
                                         "Matched images ids are: {1}".format(image_name, images_ids))
        elif state == 'absent':
            images = ecs.get_all_images()
            if images and len(images) > 0:
                current_image = images[0]

    except ECSResponseError as e:
        module.fail_json(msg='Error in get_all_images: %s' % str(e))

    if state == 'absent':
        if not current_image:
            module.fail_json(msg="Please use valid image_id or image_name to specify one image for deleting.")

        try:
            changed_img = current_image.delete()
            module.exit_json(changed=changed_img, image_id=current_image.id, image=get_image_detail(current_image))
        except Exception as e:
            module.fail_json(msg='Deleting a image is failed, error: {0}'.format(e))
    if not current_image:
        snapshot_id = module.params['snapshot_id']
        image_version = module.params['image_version']
        description = module.params['description']
        disk_mapping = module.params['disk_mapping']
        instance_id = module.params['instance_id']
        wait = module.params['wait']
        wait_timeout = module.params['wait_timeout']


        try:
            # Calling create_image method
            client_token = "Ansible-Alicloud-%s-%s" % (hash(str(module.params)), str(time.time()))
            changed, image_id, results, request_id = create_image(module=module, ecs=ecs, snapshot_id=snapshot_id,
                                                                  image_name=image_name, image_version=image_version,
                                                                  description=description, instance_id=instance_id,
                                                                  disk_mapping=disk_mapping, client_token=client_token,
                                                                  wait=wait, wait_timeout=wait_timeout)
            images = ecs.get_all_images(image_id=image_id)
            if images:
                if len(images) == 1:
                    current_image = images[0]

            module.exit_json(changed=changed, image_id=image_id, image=get_image_detail(current_image) )
        except Exception as e:
            module.fail_json(msg='Creating a new image is failed, error: {0}'.format(e))


if __name__ == '__main__':
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -



plugins/modules/ali_image.py [118:351]:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    image_id: '{{ image_id }}'
    state: 'absent'
'''

RETURN = '''
image:
    description: Details about the image that was created.
    returned: except on delete
    type: dict
    sample: {
        "disk_device_mappings": {
            "disk_device_mapping": [
                {
                    "device": "/dev/xvda",
                    "format": "",
                    "import_ossbucket": "",
                    "import_ossobject": "",
                    "size": "40",
                    "snapshot_id": "s-2zeddnvf7uhw3xw3its6",
                    "type": "system"
                }
            ]
        },
        "id": "m-2zee2i7regbnhhawrwc2",
        "image_name": "image_test",
        "launch_time": "2017-10-17T09:33:02Z",
        "platform": "CentOS",
        "region_id": "cn-beijing",
        "size": 40,
        "status": "Available"
    }
image_id:
    description: return the created image id
    returned: except on absent
    type: str
    sample: "m-2ze43t8c5urc4mvkx3fp"
'''
import time
from ansible.module_utils.basic import AnsibleModule
from ansible_collections.alibaba.alicloud.plugins.module_utils.alicloud_ecs import ecs_argument_spec, ecs_connect

HAS_FOOTMARK = False

try:
    from footmark.exception import ECSResponseError
    HAS_FOOTMARK = True
except ImportError:
    HAS_FOOTMARK = False


def get_image_detail(image):
    """
    Method call to get image details
    :param image:  Image object to Describe
    :return: return id, status and object of disk
    """
    if image:
        return {'id': image.image_id,
                'image_name': image.image_name,
                'size': image.size,
                'region_id': image.region,
                'disk_device_mappings': image.disk_device_mappings,
                'status': image.status,
                'platform': image.platform,
                'launch_time': image.creation_time
                }


def create_image(module, ecs, snapshot_id, image_name, image_version, description, instance_id,
                 disk_mapping, client_token, wait, wait_timeout):
    """
    Create a user-defined image with snapshots.
    :param module: Ansible module object
    :param ecs: authenticated ecs connection object
    :param snapshot_id: A user-defined image is created from the specified snapshot.
    :param image_name: image name which is to be created
    :param image_version: version of image
    :param description: description of the image
    :param instance_id: the specified instance_id
    :param disk_mapping: list relating device and disk
    :param client_token: Used to ensure the idempotence of the request
    :param wait: Used to indicate wait for instance to be running before running
    :param wait_timeout: Used to indicate how long to wait, default 300
    :return: id of image
    """
    changed = False
    if image_name:
        if len(image_name) < 2 or len(image_name) > 128:
            module.fail_json(msg='image_name must be 2 - 128 characters long')

        if image_name.startswith('http://') or image_name.startswith('https://'):
            module.fail_json(msg='image_name can not start with http:// or https://')
    if image_version:
        if image_version.isdigit():
            if int(image_version) < 1 or int(image_version) > 40:
                module.fail_json(msg='The permitted range of image_version is between 1 - 40')
        else:
            module.fail_json(msg='The permitted range of image_version is between 1 - 40, entered value is {0}'
                             .format(image_version))

    if disk_mapping:
        for mapping in disk_mapping:
            if mapping:
                if 'snapshot_id' not in mapping:
                    module.fail_json(msg='The snapshot_id of system disk is needed for disk mapping.')

                if not('disk_size' in mapping or 'snapshot_id' in mapping):
                    module.fail_json(msg='The disk_size and snapshot_id parameters '
                                         'are valid for disk mapping.')

                if 'disk_size' in mapping:
                    map_disk = mapping['disk_size']
                    if map_disk:
                        if str(map_disk).isdigit():
                            if int(map_disk) < 5 or int(map_disk) > 2000:
                                module.fail_json(msg='The permitted range of disk-size is 5 GB - 2000 GB ')
                        else:
                            module.fail_json(msg='The disk_size must be an integer value, entered value is {0}'.format(
                                map_disk))

    if not snapshot_id and not instance_id and not disk_mapping:
        module.fail_json(msg='Either of SnapshotId or InstanceId or disk_mapping, must be present for '
                             'create image operation to get performed')

    if (snapshot_id and instance_id) or (snapshot_id and disk_mapping) or (instance_id and disk_mapping):
        module.fail_json(msg='Only 1 of SnapshotId or InstanceId or disk_mapping, must be present for '
                             'create image operation to get performed')

    # call to create_image method in footmark
    try:
        changed, image_id, results, request_id = ecs.create_image(snapshot_id=snapshot_id, image_name=image_name,
                                                                  image_version=image_version, description=description,
                                                                  instance_id=instance_id, disk_mapping=disk_mapping,
                                                                  client_token=client_token, wait=wait,
                                                                  wait_timeout=wait_timeout)

        if 'error code' in str(results).lower():
            module.fail_json(changed=changed, msg=results)

    except ECSResponseError as e:
        module.fail_json(msg='Unable to create image, error: {0}'.format(e))
    return changed, image_id, results, request_id


def main():
    argument_spec = ecs_argument_spec()
    argument_spec.update(dict(
        image_id=dict(type='str'),
        snapshot_id=dict(type='str', aliases=['snapshot']),
        description=dict(type='str'),
        image_name=dict(type='str', aliases=['name']),
        image_version=dict(type='str', aliases=['version']),
        disk_mapping=dict(type='list', elements='dict'),
        instance_id=dict(aliases=['instance']),
        state=dict(default='present', choices=['present', 'absent'], type='str'),
        wait=dict(default=False, type='bool'),
        wait_timeout=dict(type='int', default=300)
    ))
    module = AnsibleModule(argument_spec=argument_spec)

    if HAS_FOOTMARK is False:
        module.fail_json(msg='footmark required for the module alicloud_security_group.')

    ecs = ecs_connect(module)
    state = module.params['state']
    image_id = module.params['image_id']
    image_name = module.params['image_name']

    changed = False
    current_image = None

    try:
        if image_id:
            images = ecs.get_all_images(image_id=image_id)
            if images and len(images) == 1:
                current_image = images[0]
        elif image_name and state == 'absent':
            images = ecs.get_all_images(image_name=image_name)
            if images:
                if len(images) == 1:
                    current_image = images[0]
                else:
                    images_ids = []
                    for i in images:
                        images_ids.append(i.id)
                    module.fail_json(msg="There is too many images match name '{0}', "
                                         "please use image_id or a new image_name to specify a unique image."
                                         "Matched images ids are: {1}".format(image_name, images_ids))
        elif state == 'absent':
            images = ecs.get_all_images()
            if images and len(images) > 0:
                current_image = images[0]

    except ECSResponseError as e:
        module.fail_json(msg='Error in get_all_images: %s' % str(e))

    if state == 'absent':
        if not current_image:
            module.fail_json(msg="Please use valid image_id or image_name to specify one image for deleting.")

        try:
            changed_img = current_image.delete()
            module.exit_json(changed=changed_img, image_id=current_image.id, image=get_image_detail(current_image))
        except Exception as e:
            module.fail_json(msg='Deleting a image is failed, error: {0}'.format(e))
    if not current_image:
        snapshot_id = module.params['snapshot_id']
        image_version = module.params['image_version']
        description = module.params['description']
        disk_mapping = module.params['disk_mapping']
        instance_id = module.params['instance_id']
        wait = module.params['wait']
        wait_timeout = module.params['wait_timeout']


        try:
            # Calling create_image method
            client_token = "Ansible-Alicloud-%s-%s" % (hash(str(module.params)), str(time.time()))
            changed, image_id, results, request_id = create_image(module=module, ecs=ecs, snapshot_id=snapshot_id,
                                                                  image_name=image_name, image_version=image_version,
                                                                  description=description, instance_id=instance_id,
                                                                  disk_mapping=disk_mapping, client_token=client_token,
                                                                  wait=wait, wait_timeout=wait_timeout)
            images = ecs.get_all_images(image_id=image_id)
            if images:
                if len(images) == 1:
                    current_image = images[0]

            module.exit_json(changed=changed, image_id=image_id, image=get_image_detail(current_image) )
        except Exception as e:
            module.fail_json(msg='Creating a new image is failed, error: {0}'.format(e))


if __name__ == '__main__':
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -



