From 07a5ab2f0501e9c1e5aee1aa299d6d00aab4a5d9 Mon Sep 17 00:00:00 2001 From: Alina Buzachis Date: Thu, 26 Aug 2021 15:26:28 +0200 Subject: [PATCH] Remove modules --- ec2_vpc_nat_gateway.py | 1000 ---------------------------------- ec2_vpc_nat_gateway_facts.py | 1 - ec2_vpc_nat_gateway_info.py | 218 -------- 3 files changed, 1219 deletions(-) delete mode 100644 ec2_vpc_nat_gateway.py delete mode 120000 ec2_vpc_nat_gateway_facts.py delete mode 100644 ec2_vpc_nat_gateway_info.py diff --git a/ec2_vpc_nat_gateway.py b/ec2_vpc_nat_gateway.py deleted file mode 100644 index 30a28ca1391..00000000000 --- a/ec2_vpc_nat_gateway.py +++ /dev/null @@ -1,1000 +0,0 @@ -#!/usr/bin/python -# Copyright: Ansible Project -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -from __future__ import absolute_import, division, print_function -__metaclass__ = type - - -DOCUMENTATION = r''' ---- -module: ec2_vpc_nat_gateway -version_added: 1.0.0 -short_description: Manage AWS VPC NAT Gateways. -description: - - Ensure the state of AWS VPC NAT Gateways based on their id, allocation and subnet ids. -options: - state: - description: - - Ensure NAT Gateway is present or absent. - default: "present" - choices: ["present", "absent"] - type: str - nat_gateway_id: - description: - - The id AWS dynamically allocates to the NAT Gateway on creation. - This is required when the absent option is present. - type: str - subnet_id: - description: - - The id of the subnet to create the NAT Gateway in. This is required - with the present option. - type: str - allocation_id: - description: - - The id of the elastic IP allocation. If this is not passed and the - eip_address is not passed. An EIP is generated for this NAT Gateway. - type: str - eip_address: - description: - - The elastic IP address of the EIP you want attached to this NAT Gateway. - If this is not passed and the allocation_id is not passed, - an EIP is generated for this NAT Gateway. - type: str - if_exist_do_not_create: - description: - - if a NAT Gateway exists already in the subnet_id, then do not create a new one. - required: false - default: false - type: bool - tags: - description: - - A dict of tags to apply to the NAT gateway. - - To remove all tags set I(tags={}) and I(purge_tags=true). - aliases: [ 'resource_tags' ] - type: dict - version_added: 1.4.0 - purge_tags: - description: - - Remove tags not listed in I(tags). - type: bool - default: true - version_added: 1.4.0 - release_eip: - description: - - Deallocate the EIP from the VPC. - - Option is only valid with the absent state. - - You should use this with the wait option. Since you can not release an address while a delete operation is happening. - default: false - type: bool - 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 - client_token: - description: - - Optional unique token to be used during create to ensure idempotency. - When specifying this option, ensure you specify the eip_address parameter - as well otherwise any subsequent runs will fail. - type: str -author: - - Allen Sanabria (@linuxdynasty) - - Jon Hadfield (@jonhadfield) - - Karen Cheng (@Etherdaemon) - - Alina Buzachis (@alinabuzachis) -extends_documentation_fragment: -- amazon.aws.aws -- amazon.aws.ec2 -''' - -EXAMPLES = r''' -# Note: These examples do not set authentication details, see the AWS Guide for details. - -- name: Create new nat gateway with client token. - community.aws.ec2_vpc_nat_gateway: - state: present - subnet_id: subnet-12345678 - eip_address: 52.1.1.1 - region: ap-southeast-2 - client_token: abcd-12345678 - register: new_nat_gateway - -- name: Create new nat gateway using an allocation-id. - community.aws.ec2_vpc_nat_gateway: - state: present - subnet_id: subnet-12345678 - allocation_id: eipalloc-12345678 - region: ap-southeast-2 - register: new_nat_gateway - -- name: Create new nat gateway, using an EIP address and wait for available status. - community.aws.ec2_vpc_nat_gateway: - state: present - subnet_id: subnet-12345678 - eip_address: 52.1.1.1 - wait: true - region: ap-southeast-2 - register: new_nat_gateway - -- name: Create new nat gateway and allocate new EIP. - community.aws.ec2_vpc_nat_gateway: - state: present - subnet_id: subnet-12345678 - wait: true - region: ap-southeast-2 - register: new_nat_gateway - -- name: Create new nat gateway and allocate new EIP if a nat gateway does not yet exist in the subnet. - community.aws.ec2_vpc_nat_gateway: - state: present - subnet_id: subnet-12345678 - wait: true - region: ap-southeast-2 - if_exist_do_not_create: true - register: new_nat_gateway - -- name: Delete nat gateway using discovered nat gateways from facts module. - community.aws.ec2_vpc_nat_gateway: - state: absent - region: ap-southeast-2 - wait: true - nat_gateway_id: "{{ item.NatGatewayId }}" - release_eip: true - register: delete_nat_gateway_result - loop: "{{ gateways_to_remove.result }}" - -- name: Delete nat gateway and wait for deleted status. - community.aws.ec2_vpc_nat_gateway: - state: absent - nat_gateway_id: nat-12345678 - wait: true - wait_timeout: 500 - region: ap-southeast-2 - -- name: Delete nat gateway and release EIP. - community.aws.ec2_vpc_nat_gateway: - state: absent - nat_gateway_id: nat-12345678 - release_eip: true - wait: yes - wait_timeout: 300 - region: ap-southeast-2 - -- name: Create new nat gateway using allocation-id and tags. - community.aws.ec2_vpc_nat_gateway: - state: present - subnet_id: subnet-12345678 - allocation_id: eipalloc-12345678 - region: ap-southeast-2 - tags: - Tag1: tag1 - Tag2: tag2 - register: new_nat_gateway - -- name: Update tags without purge - community.aws.ec2_vpc_nat_gateway: - subnet_id: subnet-12345678 - allocation_id: eipalloc-12345678 - region: ap-southeast-2 - purge_tags: no - tags: - Tag3: tag3 - wait: yes - register: update_tags_nat_gateway -''' - -RETURN = r''' -create_time: - description: The ISO 8601 date time format in UTC. - returned: In all cases. - type: str - sample: "2016-03-05T05:19:20.282000+00:00'" -nat_gateway_id: - description: id of the VPC NAT Gateway - returned: In all cases. - type: str - sample: "nat-0d1e3a878585988f8" -subnet_id: - description: id of the Subnet - returned: In all cases. - type: str - sample: "subnet-12345" -state: - description: The current state of the NAT Gateway. - returned: In all cases. - type: str - sample: "available" -tags: - description: The tags associated the VPC NAT Gateway. - type: dict - returned: When tags are present. - sample: - tags: - "Ansible": "Test" -vpc_id: - description: id of the VPC. - returned: In all cases. - type: str - sample: "vpc-12345" -nat_gateway_addresses: - description: List of dictionaries containing the public_ip, network_interface_id, private_ip, and allocation_id. - returned: In all cases. - type: str - sample: [ - { - 'public_ip': '52.52.52.52', - 'network_interface_id': 'eni-12345', - 'private_ip': '10.0.0.100', - 'allocation_id': 'eipalloc-12345' - } - ] -''' - -import datetime - -try: - import botocore -except ImportError: - pass # Handled by AnsibleAWSModule - -from ansible_collections.amazon.aws.plugins.module_utils.ec2 import AWSRetry -from ansible_collections.amazon.aws.plugins.module_utils.core import AnsibleAWSModule -from ansible_collections.amazon.aws.plugins.module_utils.core import is_boto3_error_code -from ansible_collections.amazon.aws.plugins.module_utils.waiters import get_waiter -from ansible_collections.amazon.aws.plugins.module_utils.ec2 import camel_dict_to_snake_dict -from ansible_collections.amazon.aws.plugins.module_utils.ec2 import ansible_dict_to_boto3_filter_list -from ansible_collections.amazon.aws.plugins.module_utils.ec2 import ansible_dict_to_boto3_tag_list -from ansible_collections.amazon.aws.plugins.module_utils.ec2 import boto3_tag_list_to_ansible_dict -from ansible_collections.amazon.aws.plugins.module_utils.ec2 import compare_aws_tags - - -@AWSRetry.jittered_backoff(retries=10) -def _describe_nat_gateways(client, **params): - try: - paginator = client.get_paginator('describe_nat_gateways') - return paginator.paginate(**params).build_full_result()['NatGateways'] - except is_boto3_error_code('InvalidNatGatewayID.NotFound'): - return None - - -def wait_for_status(client, module, waiter_name, nat_gateway_id): - wait_timeout = module.params.get('wait_timeout') - try: - waiter = get_waiter(client, waiter_name) - attempts = 1 + int(wait_timeout / waiter.config.delay) - waiter.wait( - NatGatewayIds=[nat_gateway_id], - WaiterConfig={'MaxAttempts': attempts} - ) - except botocore.exceptions.WaiterError as e: - module.fail_json_aws(e, msg="NAT gateway failed to reach expected state.") - except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e: - module.fail_json_aws(e, msg="Unable to wait for NAT gateway state to update.") - - -def get_nat_gateways(client, module, subnet_id=None, nat_gateway_id=None, states=None): - """Retrieve a list of NAT Gateways - Args: - client (botocore.client.EC2): Boto3 client - module: AnsibleAWSModule class instance - - Kwargs: - subnet_id (str): The subnet_id the nat resides in. - nat_gateway_id (str): The Amazon NAT id. - states (list): States available (pending, failed, available, deleting, and deleted) - default=None - - Basic Usage: - >>> client = boto3.client('ec2') - >>> module = AnsibleAWSModule(...) - >>> subnet_id = 'subnet-12345678' - >>> get_nat_gateways(client, module, subnet_id) - [ - true, - "", - { - "create_time": "2016-03-05T00:33:21.209000+00:00", - "delete_time": "2016-03-05T00:36:37.329000+00:00", - "nat_gateway_addresses": [ - { - "public_ip": "55.55.55.55", - "network_interface_id": "eni-1234567", - "private_ip": "10.0.0.102", - "allocation_id": "eipalloc-1234567" - } - ], - "nat_gateway_id": "nat-123456789", - "state": "deleted", - "subnet_id": "subnet-123456789", - "tags": {}, - "vpc_id": "vpc-12345678" - } - - Returns: - Tuple (bool, str, list) - """ - - params = dict() - existing_gateways = list() - - if not states: - states = ['available', 'pending'] - if nat_gateway_id: - params['NatGatewayIds'] = [nat_gateway_id] - else: - params['Filter'] = [ - { - 'Name': 'subnet-id', - 'Values': [subnet_id] - }, - { - 'Name': 'state', - 'Values': states - } - ] - - try: - gateways = _describe_nat_gateways(client, **params) - if gateways: - for gw in gateways: - existing_gateways.append(camel_dict_to_snake_dict(gw)) - except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e: - module.fail_json_aws(e) - - return existing_gateways - - -def gateway_in_subnet_exists(client, module, subnet_id, allocation_id=None): - """Retrieve all NAT Gateways for a subnet. - Args: - client (botocore.client.EC2): Boto3 client - module: AnsibleAWSModule class instance - subnet_id (str): The subnet_id the nat resides in. - - Kwargs: - allocation_id (str): The EIP Amazon identifier. - default = None - - Basic Usage: - >>> client = boto3.client('ec2') - >>> module = AnsibleAWSModule(...) - >>> subnet_id = 'subnet-1234567' - >>> allocation_id = 'eipalloc-1234567' - >>> gateway_in_subnet_exists(client, module, subnet_id, allocation_id) - ( - [ - { - "create_time": "2016-03-05T00:33:21.209000+00:00", - "delete_time": "2016-03-05T00:36:37.329000+00:00", - "nat_gateway_addresses": [ - { - "public_ip": "55.55.55.55", - "network_interface_id": "eni-1234567", - "private_ip": "10.0.0.102", - "allocation_id": "eipalloc-1234567" - } - ], - "nat_gateway_id": "nat-123456789", - "state": "deleted", - "subnet_id": "subnet-123456789", - "tags": {}, - "vpc_id": "vpc-1234567" - } - ], - False - ) - - Returns: - Tuple (list, bool) - """ - - allocation_id_exists = False - gateways = [] - states = ['available', 'pending'] - - gws_retrieved = (get_nat_gateways(client, module, subnet_id, states=states)) - - if gws_retrieved: - for gw in gws_retrieved: - for address in gw['nat_gateway_addresses']: - if allocation_id: - if address.get('allocation_id') == allocation_id: - allocation_id_exists = True - gateways.append(gw) - else: - gateways.append(gw) - - return gateways, allocation_id_exists - - -def get_eip_allocation_id_by_address(client, module, eip_address): - """Release an EIP from your EIP Pool - Args: - client (botocore.client.EC2): Boto3 client - module: AnsibleAWSModule class instance - eip_address (str): The Elastic IP Address of the EIP. - - Basic Usage: - >>> client = boto3.client('ec2') - >>> module = AnsibleAWSModule(...) - >>> eip_address = '52.87.29.36' - >>> get_eip_allocation_id_by_address(client, module, eip_address) - 'eipalloc-36014da3' - - Returns: - Tuple (str, str) - """ - - params = { - 'PublicIps': [eip_address], - } - allocation_id = None - msg = '' - - try: - allocations = client.describe_addresses(aws_retry=True, **params)['Addresses'] - - if len(allocations) == 1: - allocation = allocations[0] - else: - allocation = None - - if allocation: - if allocation.get('Domain') != 'vpc': - msg = ( - "EIP {0} is a non-VPC EIP, please allocate a VPC scoped EIP" - .format(eip_address) - ) - else: - allocation_id = allocation.get('AllocationId') - - except is_boto3_error_code('InvalidAddress.Malformed') as e: - module.fail_json(msg='EIP address {0} is invalid.'.format(eip_address)) - except is_boto3_error_code('InvalidAddress.NotFound') as e: # pylint: disable=duplicate-except - msg = ( - "EIP {0} does not exist".format(eip_address) - ) - allocation_id = None - except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e: # pylint: disable=duplicate-except - module.fail_json_aws(e) - - return allocation_id, msg - - -def allocate_eip_address(client, module): - """Release an EIP from your EIP Pool - Args: - client (botocore.client.EC2): Boto3 client - module: AnsibleAWSModule class instance - - Basic Usage: - >>> client = boto3.client('ec2') - >>> module = AnsibleAWSModule(...) - >>> allocate_eip_address(client, module) - True - - Returns: - Tuple (bool, str) - """ - - new_eip = None - msg = '' - params = { - 'Domain': 'vpc', - } - - if module.check_mode: - ip_allocated = True - new_eip = None - return ip_allocated, msg, new_eip - - try: - new_eip = client.allocate_address(aws_retry=True, **params)['AllocationId'] - ip_allocated = True - msg = 'eipalloc id {0} created'.format(new_eip) - except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e: - module.fail_json_aws(e) - - return ip_allocated, msg, new_eip - - -def release_address(client, module, allocation_id): - """Release an EIP from your EIP Pool - Args: - client (botocore.client.EC2): Boto3 client - module: AnsibleAWSModule class instance - allocation_id (str): The eip Amazon identifier. - - Basic Usage: - >>> client = boto3.client('ec2') - >>> module = AnsibleAWSModule(...) - >>> allocation_id = "eipalloc-123456" - >>> release_address(client, module, allocation_id) - True - - Returns: - Boolean, string - """ - - msg = '' - - if module.check_mode: - return True, '' - - ip_released = False - - try: - client.describe_addresses(aws_retry=True, AllocationIds=[allocation_id]) - except is_boto3_error_code('InvalidAllocationID.NotFound') as e: - # IP address likely already released - # Happens with gateway in 'deleted' state that - # still lists associations - return True, e - except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e: # pylint: disable=duplicate-except - module.fail_json_aws(e) - - try: - client.release_address(aws_retry=True, AllocationId=allocation_id) - ip_released = True - except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e: - module.fail_json_aws(e) - - return ip_released, msg - - -def create(client, module, subnet_id, allocation_id, tags, purge_tags, client_token=None, - wait=False): - """Create an Amazon NAT Gateway. - Args: - client (botocore.client.EC2): Boto3 client - module: AnsibleAWSModule class instance - subnet_id (str): The subnet_id the nat resides in - allocation_id (str): The eip Amazon identifier - tags (dict): Tags to associate to the NAT gateway - purge_tags (bool): If true, remove tags not listed in I(tags) - type: bool - - Kwargs: - wait (bool): Wait for the nat to be in the deleted state before returning. - default = False - client_token (str): - default = None - - Basic Usage: - >>> client = boto3.client('ec2') - >>> module = AnsibleAWSModule(...) - >>> subnet_id = 'subnet-1234567' - >>> allocation_id = 'eipalloc-1234567' - >>> create(client, module, subnet_id, allocation_id, wait=True) - [ - true, - "", - { - "create_time": "2016-03-05T00:33:21.209000+00:00", - "delete_time": "2016-03-05T00:36:37.329000+00:00", - "nat_gateway_addresses": [ - { - "public_ip": "55.55.55.55", - "network_interface_id": "eni-1234567", - "private_ip": "10.0.0.102", - "allocation_id": "eipalloc-1234567" - } - ], - "nat_gateway_id": "nat-123456789", - "state": "deleted", - "subnet_id": "subnet-1234567", - "tags": {}, - "vpc_id": "vpc-1234567" - } - ] - - Returns: - Tuple (bool, str, list) - """ - - params = { - 'SubnetId': subnet_id, - 'AllocationId': allocation_id - } - request_time = datetime.datetime.utcnow() - changed = False - token_provided = False - result = {} - msg = '' - - if client_token: - token_provided = True - params['ClientToken'] = client_token - - if module.check_mode: - changed = True - return changed, result, msg - - try: - result = camel_dict_to_snake_dict(client.create_nat_gateway(aws_retry=True, **params)["NatGateway"]) - changed = True - - create_time = result['create_time'].replace(tzinfo=None) - - if token_provided and (request_time > create_time): - changed = False - - elif wait and result.get('state') != 'available': - wait_for_status(client, module, 'nat_gateway_available', result['nat_gateway_id']) - - # Get new result - result = camel_dict_to_snake_dict( - _describe_nat_gateways(client, NatGatewayIds=[result['nat_gateway_id']])[0] - ) - - result['tags'], _tags_update_exists = ensure_tags( - client, module, nat_gw_id=result['nat_gateway_id'], tags=tags, - purge_tags=purge_tags - ) - except is_boto3_error_code('IdempotentParameterMismatch') as e: - msg = ( - 'NAT Gateway does not support update and token has already been provided:' + e - ) - changed = False - result = None - except (botocore.exceptions.BotoCoreError, botocore.exceptions.ClientError) as e: # pylint: disable=duplicate-except - module.fail_json_aws(e) - - return changed, result, msg - - -def pre_create(client, module, subnet_id, tags, purge_tags, allocation_id=None, eip_address=None, - if_exist_do_not_create=False, wait=False, client_token=None): - """Create an Amazon NAT Gateway. - Args: - client (botocore.client.EC2): Boto3 client - module: AnsibleAWSModule class instance - subnet_id (str): The subnet_id the nat resides in - tags (dict): Tags to associate to the NAT gateway - purge_tags (bool): If true, remove tags not listed in I(tags) - - Kwargs: - allocation_id (str): The EIP Amazon identifier. - default = None - eip_address (str): The Elastic IP Address of the EIP. - default = None - if_exist_do_not_create (bool): if a nat gateway already exists in this - subnet, than do not create another one. - default = False - wait (bool): Wait for the nat to be in the deleted state before returning. - default = False - client_token (str): - default = None - - Basic Usage: - >>> client = boto3.client('ec2') - >>> module = AnsibleAWSModule(...) - >>> subnet_id = 'subnet-w4t12897' - >>> allocation_id = 'eipalloc-36014da3' - >>> pre_create(client, module, subnet_id, allocation_id, if_exist_do_not_create=True, wait=True) - [ - true, - "", - { - "create_time": "2016-03-05T00:33:21.209000+00:00", - "delete_time": "2016-03-05T00:36:37.329000+00:00", - "nat_gateway_addresses": [ - { - "public_ip": "52.87.29.36", - "network_interface_id": "eni-5579742d", - "private_ip": "10.0.0.102", - "allocation_id": "eipalloc-36014da3" - } - ], - "nat_gateway_id": "nat-03835afb6e31df79b", - "state": "deleted", - "subnet_id": "subnet-w4t12897", - "tags": {}, - "vpc_id": "vpc-w68571b5" - } - ] - - Returns: - Tuple (bool, bool, str, list) - """ - - changed = False - msg = '' - results = {} - - if not allocation_id and not eip_address: - existing_gateways, allocation_id_exists = (gateway_in_subnet_exists(client, module, subnet_id)) - - if len(existing_gateways) > 0 and if_exist_do_not_create: - results = existing_gateways[0] - results['tags'], tags_update_exists = ensure_tags( - client, module, results['nat_gateway_id'], tags, purge_tags - ) - - if tags_update_exists: - changed = True - return changed, msg, results - - changed = False - msg = ( - 'NAT Gateway {0} already exists in subnet_id {1}' - .format( - existing_gateways[0]['nat_gateway_id'], subnet_id - ) - ) - return changed, msg, results - else: - changed, msg, allocation_id = ( - allocate_eip_address(client, module) - ) - if not changed: - return changed, msg, dict() - - elif eip_address or allocation_id: - if eip_address and not allocation_id: - allocation_id, msg = ( - get_eip_allocation_id_by_address( - client, module, eip_address - ) - ) - if not allocation_id: - changed = False - return changed, msg, dict() - - existing_gateways, allocation_id_exists = ( - gateway_in_subnet_exists( - client, module, subnet_id, allocation_id - ) - ) - - if len(existing_gateways) > 0 and (allocation_id_exists or if_exist_do_not_create): - results = existing_gateways[0] - results['tags'], tags_update_exists = ensure_tags( - client, module, results['nat_gateway_id'], tags, purge_tags - ) - - if tags_update_exists: - changed = True - return changed, msg, results - - changed = False - msg = ( - 'NAT Gateway {0} already exists in subnet_id {1}' - .format( - existing_gateways[0]['nat_gateway_id'], subnet_id - ) - ) - return changed, msg, results - - changed, results, msg = create( - client, module, subnet_id, allocation_id, tags, purge_tags, client_token, wait - ) - - return changed, msg, results - - -def remove(client, module, nat_gateway_id, wait=False, release_eip=False): - """Delete an Amazon NAT Gateway. - Args: - client (botocore.client.EC2): Boto3 client - module: AnsibleAWSModule class instance - nat_gateway_id (str): The Amazon nat id - - Kwargs: - wait (bool): Wait for the nat to be in the deleted state before returning. - release_eip (bool): Once the nat has been deleted, you can deallocate the eip from the vpc. - - Basic Usage: - >>> client = boto3.client('ec2') - >>> module = AnsibleAWSModule(...) - >>> nat_gw_id = 'nat-03835afb6e31df79b' - >>> remove(client, module, nat_gw_id, wait=True, release_eip=True) - [ - true, - "", - { - "create_time": "2016-03-05T00:33:21.209000+00:00", - "delete_time": "2016-03-05T00:36:37.329000+00:00", - "nat_gateway_addresses": [ - { - "public_ip": "52.87.29.36", - "network_interface_id": "eni-5579742d", - "private_ip": "10.0.0.102", - "allocation_id": "eipalloc-36014da3" - } - ], - "nat_gateway_id": "nat-03835afb6e31df79b", - "state": "deleted", - "subnet_id": "subnet-w4t12897", - "tags": {}, - "vpc_id": "vpc-w68571b5" - } - ] - - Returns: - Tuple (bool, str, list) - """ - - params = { - 'NatGatewayId': nat_gateway_id - } - changed = False - results = {} - states = ['pending', 'available'] - msg = '' - - if module.check_mode: - changed = True - return changed, msg, results - - try: - gw_list = ( - get_nat_gateways( - client, module, nat_gateway_id=nat_gateway_id, - states=states - ) - ) - - if len(gw_list) == 1: - results = gw_list[0] - client.delete_nat_gateway(aws_retry=True, **params) - allocation_id = ( - results['nat_gateway_addresses'][0]['allocation_id'] - ) - changed = True - msg = ( - 'NAT gateway {0} is in a deleting state. Delete was successful' - .format(nat_gateway_id) - ) - - if wait and results.get('state') != 'deleted': - wait_for_status(client, module, 'nat_gateway_deleted', nat_gateway_id) - - # Get new results - results = camel_dict_to_snake_dict( - _describe_nat_gateways(client, NatGatewayIds=[nat_gateway_id])[0] - ) - except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e: - module.fail_json_aws(e) - - if release_eip: - eip_released, msg = ( - release_address(client, module, allocation_id)) - if not eip_released: - module.fail_json( - msg="Failed to release EIP {0}: {1}".format(allocation_id, msg) - ) - - return changed, msg, results - - -def ensure_tags(client, module, nat_gw_id, tags, purge_tags): - final_tags = [] - changed = False - - if module.check_mode and nat_gw_id is None: - # We can't describe tags without an EIP id, we might get here when creating a new EIP in check_mode - return final_tags, changed - - filters = ansible_dict_to_boto3_filter_list({'resource-id': nat_gw_id, 'resource-type': 'natgateway'}) - cur_tags = None - try: - cur_tags = client.describe_tags(aws_retry=True, Filters=filters) - except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e: - module.fail_json_aws(e, 'Couldnt describe tags') - if tags is None: - return boto3_tag_list_to_ansible_dict(cur_tags['Tags']), changed - - to_update, to_delete = compare_aws_tags(boto3_tag_list_to_ansible_dict(cur_tags.get('Tags')), tags, purge_tags) - final_tags = boto3_tag_list_to_ansible_dict(cur_tags.get('Tags')) - - if to_update: - try: - if module.check_mode: - final_tags.update(to_update) - else: - client.create_tags( - aws_retry=True, - Resources=[nat_gw_id], - Tags=ansible_dict_to_boto3_tag_list(to_update) - ) - changed = True - except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e: - module.fail_json_aws(e, "Couldn't create tags") - - if to_delete: - try: - if module.check_mode: - for key in to_delete: - del final_tags[key] - else: - tags_list = [] - for key in to_delete: - tags_list.append({'Key': key}) - - client.delete_tags(aws_retry=True, Resources=[nat_gw_id], Tags=tags_list) - changed = True - except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e: - module.fail_json_aws(e, "Couldn't delete tags") - - if not module.check_mode and (to_update or to_delete): - try: - response = client.describe_tags(aws_retry=True, Filters=filters) - final_tags = boto3_tag_list_to_ansible_dict(response.get('Tags')) - except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e: - module.fail_json_aws(e, "Couldn't describe tags") - - return final_tags, changed - - -def main(): - argument_spec = dict( - subnet_id=dict(type='str'), - eip_address=dict(type='str'), - allocation_id=dict(type='str'), - if_exist_do_not_create=dict(type='bool', default=False), - state=dict(default='present', choices=['present', 'absent']), - wait=dict(type='bool', default=False), - wait_timeout=dict(type='int', default=320, required=False), - release_eip=dict(type='bool', default=False), - nat_gateway_id=dict(type='str'), - client_token=dict(type='str', no_log=False), - tags=dict(required=False, type='dict', aliases=['resource_tags']), - purge_tags=dict(default=True, type='bool'), - ) - - module = AnsibleAWSModule( - argument_spec=argument_spec, - supports_check_mode=True, - mutually_exclusive=[ - ['allocation_id', 'eip_address'] - ], - required_if=[['state', 'absent', ['nat_gateway_id']], - ['state', 'present', ['subnet_id']]], - ) - - state = module.params.get('state').lower() - subnet_id = module.params.get('subnet_id') - allocation_id = module.params.get('allocation_id') - eip_address = module.params.get('eip_address') - nat_gateway_id = module.params.get('nat_gateway_id') - wait = module.params.get('wait') - release_eip = module.params.get('release_eip') - client_token = module.params.get('client_token') - if_exist_do_not_create = module.params.get('if_exist_do_not_create') - tags = module.params.get('tags') - purge_tags = module.params.get('purge_tags') - - try: - client = module.client('ec2', retry_decorator=AWSRetry.jittered_backoff()) - except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e: - module.fail_json_aws(e, msg='Failed to connect to AWS.') - - changed = False - msg = '' - - if state == 'present': - changed, msg, results = ( - pre_create( - client, module, subnet_id, tags, purge_tags, allocation_id, eip_address, - if_exist_do_not_create, wait, client_token - ) - ) - else: - changed, msg, results = ( - remove( - client, module, nat_gateway_id, wait, release_eip - ) - ) - - module.exit_json(msg=msg, changed=changed, **results) - - -if __name__ == '__main__': - main() diff --git a/ec2_vpc_nat_gateway_facts.py b/ec2_vpc_nat_gateway_facts.py deleted file mode 120000 index fd969989977..00000000000 --- a/ec2_vpc_nat_gateway_facts.py +++ /dev/null @@ -1 +0,0 @@ -ec2_vpc_nat_gateway_info.py \ No newline at end of file diff --git a/ec2_vpc_nat_gateway_info.py b/ec2_vpc_nat_gateway_info.py deleted file mode 100644 index 5acd59a819a..00000000000 --- a/ec2_vpc_nat_gateway_info.py +++ /dev/null @@ -1,218 +0,0 @@ -#!/usr/bin/python -# Copyright: Ansible Project -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -from __future__ import absolute_import, division, print_function -__metaclass__ = type - - -DOCUMENTATION = r''' -module: ec2_vpc_nat_gateway_info -short_description: Retrieves AWS VPC Managed Nat Gateway details using AWS methods. -version_added: 1.0.0 -description: - - Gets various details related to AWS VPC Managed Nat Gateways - - This module was called C(ec2_vpc_nat_gateway_facts) before Ansible 2.9. The usage did not change. -options: - nat_gateway_ids: - description: - - List of specific nat gateway IDs to fetch details for. - type: list - elements: str - 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_DescribeNatGateways.html) - for possible filters. - type: dict -author: Karen Cheng (@Etherdaemon) -extends_documentation_fragment: -- amazon.aws.aws -- amazon.aws.ec2 -''' - -EXAMPLES = r''' -# Simple example of listing all nat gateways -- name: List all managed nat gateways in ap-southeast-2 - community.aws.ec2_vpc_nat_gateway_info: - region: ap-southeast-2 - register: all_ngws - -- name: Debugging the result - ansible.builtin.debug: - msg: "{{ all_ngws.result }}" - -- name: Get details on specific nat gateways - community.aws.ec2_vpc_nat_gateway_info: - nat_gateway_ids: - - nat-1234567891234567 - - nat-7654321987654321 - region: ap-southeast-2 - register: specific_ngws - -- name: Get all nat gateways with specific filters - community.aws.ec2_vpc_nat_gateway_info: - region: ap-southeast-2 - filters: - state: ['pending'] - register: pending_ngws - -- name: Get nat gateways with specific filter - community.aws.ec2_vpc_nat_gateway_info: - region: ap-southeast-2 - filters: - subnet-id: subnet-12345678 - state: ['available'] - register: existing_nat_gateways -''' - -RETURN = r''' -changed: - description: True if listing the internet gateways succeeds - type: bool - returned: always - sample: false -result: - description: - - The result of the describe, converted to ansible snake case style. - - See also U(http://boto3.readthedocs.io/en/latest/reference/services/ec2.html#EC2.Client.describe_nat_gateways) - returned: suceess - type: list - contains: - create_time: - description: The date and time the NAT gateway was created - returned: always - type: str - sample: "2021-03-11T22:43:25+00:00" - delete_time: - description: The date and time the NAT gateway was deleted - returned: when the NAT gateway has been deleted - type: str - sample: "2021-03-11T22:43:25+00:00" - nat_gateway_addresses: - description: List containing a dictionary with the IP addresses and network interface associated with the NAT gateway - returned: always - type: dict - contains: - allocation_id: - description: The allocation ID of the Elastic IP address that's associated with the NAT gateway - returned: always - type: str - sample: eipalloc-0853e66a40803da76 - network_interface_id: - description: The ID of the network interface associated with the NAT gateway - returned: always - type: str - sample: eni-0a37acdbe306c661c - private_ip: - description: The private IP address associated with the Elastic IP address - returned: always - type: str - sample: 10.0.238.227 - public_ip: - description: The Elastic IP address associated with the NAT gateway - returned: always - type: str - sample: 34.204.123.52 - nat_gateway_id: - description: The ID of the NAT gateway - returned: always - type: str - sample: nat-0c242a2397acf6173 - state: - description: state of the NAT gateway - returned: always - type: str - sample: available - subnet_id: - description: The ID of the subnet in which the NAT gateway is located - returned: always - type: str - sample: subnet-098c447465d4344f9 - vpc_id: - description: The ID of the VPC in which the NAT gateway is located - returned: always - type: str - sample: vpc-02f37f48438ab7d4c - tags: - description: Tags applied to the NAT gateway - returned: always - type: dict - sample: - Tag1: tag1 - Tag_2: tag_2 -''' - - -try: - import botocore -except ImportError: - pass # Handled by AnsibleAWSModule - -from ansible_collections.amazon.aws.plugins.module_utils.ec2 import AWSRetry -from ansible_collections.amazon.aws.plugins.module_utils.core import AnsibleAWSModule -from ansible_collections.amazon.aws.plugins.module_utils.ec2 import camel_dict_to_snake_dict -from ansible_collections.amazon.aws.plugins.module_utils.ec2 import ansible_dict_to_boto3_filter_list -from ansible_collections.amazon.aws.plugins.module_utils.ec2 import boto3_tag_list_to_ansible_dict -from ansible_collections.amazon.aws.plugins.module_utils.core import is_boto3_error_code -from ansible_collections.amazon.aws.plugins.module_utils.core import normalize_boto3_result - - -@AWSRetry.jittered_backoff(retries=10) -def _describe_nat_gateways(client, module, **params): - try: - paginator = client.get_paginator('describe_nat_gateways') - return paginator.paginate(**params).build_full_result()['NatGateways'] - except is_boto3_error_code('InvalidNatGatewayID.NotFound'): - module.exit_json(msg="NAT gateway not found.") - except is_boto3_error_code('NatGatewayMalformed'): # pylint: disable=duplicate-except - module.fail_json_aws(msg="NAT gateway id is malformed.") - - -def get_nat_gateways(client, module): - params = dict() - nat_gateways = list() - - params['Filter'] = ansible_dict_to_boto3_filter_list(module.params.get('filters')) - params['NatGatewayIds'] = module.params.get('nat_gateway_ids') - - try: - result = normalize_boto3_result(_describe_nat_gateways(client, module, **params)) - except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e: - module.fail_json_aws(e, 'Unable to describe NAT gateways.') - - for gateway in result: - # Turn the boto3 result into ansible_friendly_snaked_names - converted_gateway = camel_dict_to_snake_dict(gateway) - if 'tags' in converted_gateway: - # Turn the boto3 result into ansible friendly tag dictionary - converted_gateway['tags'] = boto3_tag_list_to_ansible_dict(converted_gateway['tags']) - nat_gateways.append(converted_gateway) - - return nat_gateways - - -def main(): - argument_spec = dict( - filters=dict(default={}, type='dict'), - nat_gateway_ids=dict(default=[], type='list', elements='str'), - ) - - module = AnsibleAWSModule(argument_spec=argument_spec, - supports_check_mode=True,) - if module._name == 'ec2_vpc_nat_gateway_facts': - module.deprecate("The 'ec2_vpc_nat_gateway_facts' module has been renamed to 'ec2_vpc_nat_gateway_info'", - date='2021-12-01', collection_name='community.aws') - - try: - connection = module.client('ec2', retry_decorator=AWSRetry.jittered_backoff()) - except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e: - module.fail_json_aws(e, msg='Failed to connect to AWS') - - results = get_nat_gateways(connection, module) - - module.exit_json(result=results) - - -if __name__ == '__main__': - main()