From 80d4bd7ec7dee1ff2b588e833f9260ac2269058a Mon Sep 17 00:00:00 2001 From: Alina Buzachis Date: Fri, 1 Sep 2023 15:11:16 +0200 Subject: [PATCH] Add _info module Signed-off-by: Alina Buzachis --- plugins/module_utils/ec2.py | 19 +++ plugins/modules/ec2_import_image.py | 37 ++--- plugins/modules/ec2_import_image_info.py | 197 +++++++++++++++++++++++ 3 files changed, 225 insertions(+), 28 deletions(-) create mode 100644 plugins/modules/ec2_import_image_info.py diff --git a/plugins/module_utils/ec2.py b/plugins/module_utils/ec2.py index de9d91b56a1..9126934f1f0 100644 --- a/plugins/module_utils/ec2.py +++ b/plugins/module_utils/ec2.py @@ -304,3 +304,22 @@ def normalize_ec2_vpc_dhcp_config(option_config): config_data[option] = [val["Value"] for val in config_item["Values"]] return config_data + + +@AWSRetry.jittered_backoff(retries=10) +def helper_describe_import_image_tasks(client, module, **params): + try: + paginator = client.get_paginator("describe_import_image_tasks") + return paginator.paginate(**params).build_full_result()["ImportImageTasks"] + except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e: + module.fail_json_aws(e, msg="Failed to describe the import image") + + +def ensure_result(module, import_image_info): + result = {"import_image": {}} + + import_image_info["Tags"] = boto3_tag_list_to_ansible_dict(import_image_info["Tags"]) + result["import_image"] = camel_dict_to_snake_dict(import_image_info) + result["import_image"]["task_name"] = module.params["task_name"] + + return result diff --git a/plugins/modules/ec2_import_image.py b/plugins/modules/ec2_import_image.py index 3fa4e2de030..e0e1d66e9ce 100644 --- a/plugins/modules/ec2_import_image.py +++ b/plugins/modules/ec2_import_image.py @@ -211,13 +211,11 @@ encrypted: description: - Specifies whether the destination AMI of the imported image should be encrypted. - - The default KMS key for EBS is used unless you specify a non-default KMS key using I(kms_key_id). type: bool hypervisor: description: - The target hypervisor platform. default: str - choices: ["xen"] wait: description: - Wait for operation to complete before returning. @@ -240,7 +238,6 @@ description: - The operating system of the virtual machine. type: str - choices: ["Windows", "Linux"] role_name: description: - The name of the role to use when not using the default role, 'vmimport'. @@ -250,7 +247,6 @@ type: dict """ -import datetime try: import botocore @@ -258,19 +254,10 @@ pass # Handled by AnsibleAWSModule from ansible_collections.amazon.aws.plugins.module_utils.modules import AnsibleAWSModule -from ansible_collections.amazon.aws.plugins.module_utils.waiters import get_waiter from ansible_collections.amazon.aws.plugins.module_utils.retries import AWSRetry -from ansible.module_utils.common.dict_transformations import camel_dict_to_snake_dict from ansible_collections.amazon.aws.plugins.module_utils.tagging import boto3_tag_specifications -from ansible_collections.amazon.aws.plugins.module_utils.tagging import boto3_tag_list_to_ansible_dict - -@AWSRetry.jittered_backoff(retries=10) -def _describe_import_image_tasks(**params): - try: - paginator = client.get_paginator("describe_import_image_tasks") - return paginator.paginate(**params).build_full_result()["ImportImageTasks"] - except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e: - module.fail_json_aws(e, msg"Failed to describe the import image") +from ansible_collections.amazon.aws.plugins.module_utils.ec2 import helper_describe_import_image_tasks +from ansible_collections.amazon.aws.plugins.module_utils.ec2 import ensure_ec2_import_image_result def absent(): @@ -291,7 +278,7 @@ def absent(): if module.params.get("cancel_reason") params["CancelReason"] = module.params["cancel_reason"] - import_image_info = _describe_import_image_tasks(**filters) + import_image_info = helper_describe_import_image_tasks(client, module, **filters) if import_image_info: params["ImportTaskId"] = import_image_info["ImportTaskId"] @@ -301,14 +288,12 @@ def absent(): try: import_image_info = client.cancel_import_task(aws_retry=True, **params) - import_image_info["Tags"] = boto3_tag_list_to_ansible_dict(import_image_info["Tags"]) - result["import_image"] = camel_dict_to_snake_dict(import_image_info) except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e: module.fail_json_aws(e, msg"Failed to import the image") else: module.exit_json(changed=False, msg="The specified import task does not exist or it cannot be cancelled") - module.exit_json(changed=True, **result) + module.exit_json(changed=True, **ensure_ec2_import_image_result(module, result)) def present(): @@ -346,33 +331,29 @@ def present(): params["TagSpecifications"] = boto3_tag_specifications(tags, ["import-image-task"]) wait = module.params.get("wait") - result = {"import_image": {}} filters = { "Filters": [ {"Name": "name", "Values": [module.params["task_name"]]} - {"Name": "task-state", "Values": ["completed", "active"]} + {"Name": "task-state", "Values": ["completed", "active", "deleting"]} ] } - import_image_info = _describe_import_image_tasks(**filters) + import_image_info = helper_describe_import_image_tasks(client, module, **filters) if import_image_info: # Import tasks cannot be modified - module.exit_json(changed=False, msg="An import task with the specified name already exists", **camel_dict_to_snake_dict(import_image_info)) + module.exit_json(changed=False, msg="An import task with the specified name already exists", **ensure_ec2_import_image_result(module, result)) else: if module.check_mode: module.exit_json(changed=True, msg="Would have created the import task if not in check mode") try: client.import_image(aws_retry=True, **params) - import_image_info = _describe_import_image_tasks(**filters) - import_image_info["Tags"] = boto3_tag_list_to_ansible_dict(import_image_info["Tags"]) - result["import_image"] = camel_dict_to_snake_dict(import_image_info) - result["import_image"]["task_name"] = module.params["task_name"] + import_image_info = helper_describe_import_image_tasks(client, module, **filters) except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e: module.fail_json_aws(e, msg"Failed to import the image") - module.exit_json(changed=True, **result) + module.exit_json(changed=True, **ensure_ec2_import_image_result(module, result)) def main(): diff --git a/plugins/modules/ec2_import_image_info.py b/plugins/modules/ec2_import_image_info.py new file mode 100644 index 00000000000..d42c59bfd8e --- /dev/null +++ b/plugins/modules/ec2_import_image_info.py @@ -0,0 +1,197 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright: Ansible Project +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +DOCUMENTATION = r""" +--- +module: ec2_import_image_info +version_added: 6.5.0 +short_description: Gather information about import virtual machine tasks +description: + - Displays details about an import virtual machine tasks that are already created. +author: + - Alina Buzachis (@alinabuzachis) +options: + import_task_ids: + description: The IDs of the import image tasks. + type: list + elements: str + aliases: ["ids"] + filters: + description: + - A dict of filters to apply. Each dict item consists of a filter key and a filter value. + - See U(https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_DescribeImportImageTasks.html) for possible filters. + type: list + elements: dict + default: {} +extends_documentation_fragment: + - amazon.aws.common.modules + - amazon.aws.region.modules + - amazon.aws.boto3 +""" + +EXAMPLES = r""" +# Note: These examples do not set authentication details, see the AWS Guide for details. + +""" + +RETURN = r""" + task_name: + description: + - The name of the EC2 image import task. + type: str + architecture: + description: + - The architecture of the virtual machine. + type: str + image_id: + description: + - The ID of the Amazon Machine Image (AMI) created by the import task. + type: str + import_task_id: + description: + - The task ID of the import image task. + type: str + progress: + description: + - The progress of the task. + type: str + snapshot_details: + description: + - Describes the snapshot created from the imported disk. + type: dict + suboptions: + description: + description: + - A description for the snapshot. + type: str + device_name: + description: + - The block device mapping for the snapshot. + type: str + disk_image_size: + description: + - The size of the disk in the snapshot, in GiB. + type: float + format: + description: + - The format of the disk image from which the snapshot is created. + type: str + progress: + description: + - The percentage of progress for the task. + type: str + snapshot_id: + description: + - The snapshot ID of the disk being imported. + type: str + status: + description: + - A brief status of the snapshot creation. + type: str + status_message: + description: + - A detailed status message for the snapshot creation. + type: str + url: + description: + - The URL used to access the disk image. + type: str + user_bucket: + description: + - The Amazon S3 bucket for the disk image. + type: dict + status: + description: + - A brief status of the task. + type: str + status_message: + description: + - A detailed status message of the import task. + type: str + license_specifications: + description: + - The ARNs of the license configurations. + type: dict + usage_operation: + description: + - The usage operation value. + type: dict + description: + description: + - A description string for the import image task. + type: str + encrypted: + description: + - Specifies whether the destination AMI of the imported image should be encrypted. + type: bool + hypervisor: + description: + - The target hypervisor platform. + default: str + wait: + description: + - Wait for operation to complete before returning. + default: false + type: bool + wait_timeout: + description: + - How many seconds to wait for an operation to complete before timing out. + default: 320 + type: int + kms_key_id: + description: + - The identifier for the symmetric KMS key that was used to create the encrypted AMI. + type: str + license_type: + description: + - The license type to be used for the Amazon Machine Image (AMI) after importing. + type: str + platform: + description: + - The operating system of the virtual machine. + type: str + role_name: + description: + - The name of the role to use when not using the default role, 'vmimport'. + tags: + description: + - The tags to apply to the import image task during creation. + type: dict +""" + + +try: + from botocore.exceptions import ClientError, BotoCoreError +except ImportError: + pass # Handled by AnsibleAWSModule + +from ansible_collections.amazon.aws.plugins.module_utils.modules import AnsibleAWSModule +from ansible_collections.amazon.aws.plugins.module_utils.ec2 import helper_describe_import_image_tasks +from ansible_collections.amazon.aws.plugins.module_utils.ec2 import ensure_ec2_import_image_result + + +def main(): + argument_spec = dict( + import_task_ids=dict(type="list", elements="str", aliases=["ids"]), + filters=dict(type="list", elements="dict"), + ) + + module = AnsibleAWSModule(argument_spec=argument_spec, supports_check_mode=True) + + client = module.client("ec2", retry_decorator=AWSRetry.jittered_backoff()) + + params = { + "Filters": smodule.params["filters"], + "ImportTaskIds": module.params["import_task_ids"], + } + + import_image_info = helper_describe_import_image_tasks(client, module, **params) + + module.exit_json(import_image=**ensure_ec2_import_image_result(result)) + + +if __name__ == "__main__": + main()