def describe_subnets(connection, module):
    """
    Describe Subnets.

    module  : AnsibleAWSModule object
    connection  : boto3 client connection object
    """
    # collect parameters
    filters = ansible_dict_to_boto3_filter_list(module.params.get('filters'))
    subnet_ids = module.params.get('subnet_ids')

    if subnet_ids is None:
        # Set subnet_ids to empty list if it is None
        subnet_ids = []

    # init empty list for return vars
    subnet_info = list()

    # Get the basic VPC info
    try:
        response = describe_subnets_with_backoff(connection, subnet_ids,
                                                 filters)
    except (botocore.exceptions.ClientError,
            botocore.exceptions.BotoCoreError) as e:
        module.fail_json_aws(e, msg='Failed to describe subnets')

    for subnet in response['Subnets']:
        # for backwards compatibility
        subnet['id'] = subnet['SubnetId']
        subnet_info.append(camel_dict_to_snake_dict(subnet))
        # convert tag list to ansible dict
        subnet_info[-1]['tags'] = boto3_tag_list_to_ansible_dict(
            subnet.get('Tags', []))

    module.exit_json(subnets=subnet_info)
Пример #2
0
def list_ec2_snapshots(connection, module):

    snapshot_ids = module.params.get("snapshot_ids")
    owner_ids = [str(owner_id) for owner_id in module.params.get("owner_ids")]
    restorable_by_user_ids = [
        str(user_id) for user_id in module.params.get("restorable_by_user_ids")
    ]
    filters = ansible_dict_to_boto3_filter_list(module.params.get("filters"))

    try:
        snapshots = connection.describe_snapshots(
            SnapshotIds=snapshot_ids,
            OwnerIds=owner_ids,
            RestorableByUserIds=restorable_by_user_ids,
            Filters=filters)
    except is_boto3_error_code('InvalidSnapshot.NotFound') as e:
        if len(snapshot_ids) > 1:
            module.warn("Some of your snapshots may exist, but %s" % str(e))
        snapshots = {'Snapshots': []}
    except ClientError as e:  # pylint: disable=duplicate-except
        module.fail_json_aws(e, msg='Failed to describe snapshots')

    # Turn the boto3 result in to ansible_friendly_snaked_names
    snaked_snapshots = []
    for snapshot in snapshots['Snapshots']:
        snaked_snapshots.append(camel_dict_to_snake_dict(snapshot))

    # Turn the boto3 result in to ansible friendly tag dictionary
    for snapshot in snaked_snapshots:
        if 'tags' in snapshot:
            snapshot['tags'] = boto3_tag_list_to_ansible_dict(
                snapshot['tags'], 'key', 'value')

    module.exit_json(snapshots=snaked_snapshots)
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 get_matching_tgw(self, tgw_id, description=None, skip_deleted=True):
        """ search for  an existing tgw by either tgw_id or description
        :param tgw_id:  The AWS id of the transit gateway
        :param description:  The description of the transit gateway.
        :param skip_deleted: ignore deleted transit gateways
        :return dict: transit gateway object
        """
        filters = []
        if tgw_id:
            filters = ansible_dict_to_boto3_filter_list({'transit-gateway-id': tgw_id})

        try:
            response = AWSRetry.exponential_backoff()(self._connection.describe_transit_gateways)(Filters=filters)
        except (ClientError, BotoCoreError) as e:
            self._module.fail_json_aws(e)

        tgw = None
        tgws = []

        if len(response.get('TransitGateways', [])) == 1 and tgw_id:
            if (response['TransitGateways'][0]['State'] != 'deleted') or not skip_deleted:
                tgws.extend(response['TransitGateways'])

        for gateway in response.get('TransitGateways', []):
            if description == gateway['Description'] and gateway['State'] != 'deleted':
                tgws.append(gateway)

        if len(tgws) > 1:
            self._module.fail_json(
                msg='EC2 returned more than one transit Gateway for description {0}, aborting'.format(description))
        elif tgws:
            tgw = camel_dict_to_snake_dict(tgws[0], ignore_list=['Tags'])
            tgw['tags'] = boto3_tag_list_to_ansible_dict(tgws[0]['Tags'])

        return tgw
Пример #5
0
def describe_peering_connections(params, client):
    peer_filter = {
        'requester-vpc-info.vpc-id': params['VpcId'],
        'accepter-vpc-info.vpc-id': params['PeerVpcId'],
    }
    result = client.describe_vpc_peering_connections(
        aws_retry=True,
        Filters=ansible_dict_to_boto3_filter_list(peer_filter),
    )
    if result['VpcPeeringConnections'] == []:
        result = client.describe_vpc_peering_connections(
            aws_retry=True,
            Filters=ansible_dict_to_boto3_filter_list(peer_filter),
        )

    return result
Пример #6
0
def main():
    argument_spec = dict(
        filters=dict(default={}, type='dict')
    )

    module = AnsibleAWSModule(argument_spec=argument_spec, supports_check_mode=True)
    if module._name == 'aws_region_facts':
        module.deprecate("The 'aws_region_facts' module has been renamed to 'aws_region_info'", date='2021-12-01', collection_name='community.aws')

    connection = module.client('ec2', retry_decorator=AWSRetry.jittered_backoff())

    # Replace filter key underscores with dashes, for compatibility
    sanitized_filters = dict(module.params.get('filters'))
    for k in module.params.get('filters').keys():
        if "_" in k:
            sanitized_filters[k.replace('_', '-')] = sanitized_filters[k]
            del sanitized_filters[k]

    try:
        regions = connection.describe_regions(
            aws_retry=True,
            Filters=ansible_dict_to_boto3_filter_list(sanitized_filters)
        )
    except (BotoCoreError, ClientError) as e:
        module.fail_json_aws(e, msg="Unable to describe regions.")

    module.exit_json(regions=[camel_dict_to_snake_dict(r) for r in regions['Regions']])
def get_nat_gateways(client, module, nat_gateway_id=None):
    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 = json.loads(
            json.dumps(client.describe_nat_gateways(**params),
                       default=date_handler))
    except Exception as e:
        module.fail_json(msg=to_native(e))

    for gateway in result['NatGateways']:
        # 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
Пример #8
0
def allocate_address(ec2, module, domain, reuse_existing_ip_allowed, check_mode, tag_dict=None, public_ipv4_pool=None):
    """ Allocate a new elastic IP address (when needed) and return it """
    if reuse_existing_ip_allowed:
        filters = []
        if not domain:
            domain = 'standard'
        filters.append({'Name': 'domain', "Values": [domain]})

        if tag_dict is not None:
            filters += ansible_dict_to_boto3_filter_list(tag_dict)

        try:
            all_addresses = ec2.describe_addresses(Filters=filters, aws_retry=True)
        except (botocore.exceptions.BotoCoreError, botocore.exceptions.ClientError) as e:
            module.fail_json_aws(e, msg="Couldn't obtain list of existing Elastic IP addresses")

        all_addresses = all_addresses["Addresses"]

        if domain == 'vpc':
            unassociated_addresses = [a for a in all_addresses
                                      if not a.get('AssociationId', None)]
        else:
            unassociated_addresses = [a for a in all_addresses
                                      if not a['InstanceId']]
        if unassociated_addresses:
            return unassociated_addresses[0], False

    if public_ipv4_pool:
        return allocate_address_from_pool(ec2, module, domain, check_mode, public_ipv4_pool), True

    try:
        result = ec2.allocate_address(Domain=domain, aws_retry=True), True
    except (botocore.exceptions.BotoCoreError, botocore.exceptions.ClientError) as e:
        module.fail_json_aws(e, msg="Couldn't allocate Elastic IP address")
    return result
def ensure_subnet_association(connection=None, module=None, vpc_id=None, route_table_id=None, subnet_id=None,
                              check_mode=None):
    filters = ansible_dict_to_boto3_filter_list({'association.subnet-id': subnet_id, 'vpc-id': vpc_id})
    try:
        route_tables = describe_route_tables_with_backoff(connection, Filters=filters)
    except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e:
        module.fail_json_aws(e, msg="Couldn't get route tables")
    for route_table in route_tables:
        if route_table['RouteTableId'] is None:
            continue
        for a in route_table['Associations']:
            if a['Main']:
                continue
            if a['SubnetId'] == subnet_id:
                if route_table['RouteTableId'] == route_table_id:
                    return {'changed': False, 'association_id': a['RouteTableAssociationId']}
                else:
                    if check_mode:
                        return {'changed': True}
                    try:
                        connection.disassociate_route_table(AssociationId=a['RouteTableAssociationId'])
                    except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e:
                        module.fail_json_aws(e, msg="Couldn't disassociate subnet from route table")

    try:
        association_id = connection.associate_route_table(RouteTableId=route_table_id, SubnetId=subnet_id)
    except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e:
        module.fail_json_aws(e, msg="Couldn't associate subnet with route table")
    return {'changed': True, 'association_id': association_id}
    def describe_transit_gateways(self):
        """
        Describe transit gateways.

        module  : AnsibleAWSModule object
        connection  : boto3 client connection object
        """
        # collect parameters
        filters = ansible_dict_to_boto3_filter_list(
            self._module.params['filters'])
        transit_gateway_ids = self._module.params['transit_gateway_ids']

        # init empty list for return vars
        transit_gateway_info = list()

        # Get the basic transit gateway info
        try:
            response = self._connection.describe_transit_gateways(
                TransitGatewayIds=transit_gateway_ids, Filters=filters)
        except is_boto3_error_code('InvalidTransitGatewayID.NotFound'):
            self._results['transit_gateways'] = []
            return

        for transit_gateway in response['TransitGateways']:
            transit_gateway_info.append(
                camel_dict_to_snake_dict(transit_gateway,
                                         ignore_list=['Tags']))
            # convert tag list to ansible dict
            transit_gateway_info[-1]['tags'] = boto3_tag_list_to_ansible_dict(
                transit_gateway.get('Tags', []))

        self._results['transit_gateways'] = transit_gateway_info
        return
Пример #11
0
def main():
    argument_spec = dict(filters=dict(default={}, type='dict'))

    module = AnsibleAWSModule(argument_spec=argument_spec)
    if module._name == 'aws_az_facts':
        module.deprecate(
            "The 'aws_az_facts' module has been renamed to 'aws_az_info'",
            version='2.14')

    connection = module.client('ec2',
                               retry_decorator=AWSRetry.jittered_backoff())

    # Replace filter key underscores with dashes, for compatibility
    sanitized_filters = dict((k.replace('_', '-'), v)
                             for k, v in module.params.get('filters').items())

    try:
        availability_zones = connection.describe_availability_zones(
            Filters=ansible_dict_to_boto3_filter_list(sanitized_filters))
    except (BotoCoreError, ClientError) as e:
        module.fail_json_aws(e, msg="Unable to describe availability zones.")

    # Turn the boto3 result into ansible_friendly_snaked_names
    snaked_availability_zones = [
        camel_dict_to_snake_dict(az)
        for az in availability_zones['AvailabilityZones']
    ]

    module.exit_json(availability_zones=snaked_availability_zones)
Пример #12
0
def list_ec2_instances(connection, module):

    instance_ids = module.params.get("instance_ids")
    uptime = module.params.get('minimum_uptime')
    filters = ansible_dict_to_boto3_filter_list(module.params.get("filters"))

    try:
        reservations_paginator = connection.get_paginator('describe_instances')
        reservations = reservations_paginator.paginate(InstanceIds=instance_ids, Filters=filters).build_full_result()
    except ClientError as e:
        module.fail_json_aws(e, msg="Failed to list ec2 instances")

    instances = []

    if uptime:
        timedelta = int(uptime) if uptime else 0
        oldest_launch_time = datetime.datetime.utcnow() - datetime.timedelta(minutes=timedelta)
        # Get instances from reservations
        for reservation in reservations['Reservations']:
            instances += [instance for instance in reservation['Instances'] if instance['LaunchTime'].replace(tzinfo=None) < oldest_launch_time]
    else:
        for reservation in reservations['Reservations']:
            instances = instances + reservation['Instances']

    # Turn the boto3 result in to ansible_friendly_snaked_names
    snaked_instances = [camel_dict_to_snake_dict(instance) for instance in instances]

    # Turn the boto3 result in to ansible friendly tag dictionary
    for instance in snaked_instances:
        instance['tags'] = boto3_tag_list_to_ansible_dict(instance.get('tags', []), 'key', 'value')

    module.exit_json(instances=snaked_instances)
Пример #13
0
def list_eni(connection, module):

    if module.params.get("filters") is None:
        filters = []
    else:
        filters = ansible_dict_to_boto3_filter_list(
            module.params.get("filters"))

    try:
        network_interfaces_result = connection.describe_network_interfaces(
            Filters=filters)['NetworkInterfaces']
    except (ClientError, NoCredentialsError) as e:
        module.fail_json_aws(e)

    # Modify boto3 tags list to be ansible friendly dict and then camel_case
    camel_network_interfaces = []
    for network_interface in network_interfaces_result:
        network_interface['TagSet'] = boto3_tag_list_to_ansible_dict(
            network_interface['TagSet'])
        # Added id to interface info to be compatible with return values of ec2_eni module:
        network_interface['Id'] = network_interface['NetworkInterfaceId']
        camel_network_interfaces.append(
            camel_dict_to_snake_dict(network_interface))

    module.exit_json(network_interfaces=camel_network_interfaces)
Пример #14
0
def list_customer_gateways(connection, module):
    params = dict()

    params['Filters'] = ansible_dict_to_boto3_filter_list(
        module.params.get('filters'))
    params['CustomerGatewayIds'] = module.params.get('customer_gateway_ids')

    try:
        result = json.loads(
            json.dumps(connection.describe_customer_gateways(**params),
                       default=date_handler))
    except (ClientError, BotoCoreError) as e:
        module.fail_json_aws(e, msg="Could not describe customer gateways")
    snaked_customer_gateways = [
        camel_dict_to_snake_dict(gateway)
        for gateway in result['CustomerGateways']
    ]
    if snaked_customer_gateways:
        for customer_gateway in snaked_customer_gateways:
            customer_gateway['tags'] = boto3_tag_list_to_ansible_dict(
                customer_gateway.get('tags', []))
            customer_gateway_name = customer_gateway['tags'].get('Name')
            if customer_gateway_name:
                customer_gateway[
                    'customer_gateway_name'] = customer_gateway_name
    module.exit_json(changed=False, customer_gateways=snaked_customer_gateways)
Пример #15
0
def list_ec2_instances(connection, module):

    instance_ids = module.params.get("instance_ids")
    filters = ansible_dict_to_boto3_filter_list(module.params.get("filters"))

    try:
        reservations_paginator = connection.get_paginator('describe_instances')
        reservations = reservations_paginator.paginate(
            InstanceIds=instance_ids, Filters=filters).build_full_result()
    except ClientError as e:
        module.fail_json_aws(e, msg="Failed to list ec2 instances")

    # Get instances from reservations
    instances = []
    for reservation in reservations['Reservations']:
        instances = instances + reservation['Instances']

    # Turn the boto3 result in to ansible_friendly_snaked_names
    snaked_instances = [
        camel_dict_to_snake_dict(instance) for instance in instances
    ]

    # Turn the boto3 result in to ansible friendly tag dictionary
    for instance in snaked_instances:
        instance['tags'] = boto3_tag_list_to_ansible_dict(
            instance.get('tags', []), 'key', 'value')

    module.exit_json(instances=snaked_instances)
Пример #16
0
def associate_gateway(connection, module, route_table, gateway_id):
    filters = ansible_dict_to_boto3_filter_list({'association.gateway-id': gateway_id, 'vpc-id': route_table['VpcId']})
    try:
        route_tables = describe_route_tables_with_backoff(connection, Filters=filters)
    except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e:
        module.fail_json_aws(e, msg="Couldn't get route tables")
    for table in route_tables:
        if table.get('RouteTableId'):
            for association in table.get('Associations'):
                if association['Main']:
                    continue
                if association.get('GatewayId', '') == gateway_id and (association['AssociationState']['State'] in ['associated', 'associating']):
                    if table['RouteTableId'] == route_table['RouteTableId']:
                        return False
                    elif module.check_mode:
                        return True
                    else:
                        try:
                            connection.disassociate_route_table(
                                aws_retry=True, AssociationId=association['RouteTableAssociationId'])
                        except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e:
                            module.fail_json_aws(e, msg="Couldn't disassociate gateway from route table")

    if not module.check_mode:
        try:
            connection.associate_route_table(aws_retry=True,
                                             RouteTableId=route_table['RouteTableId'],
                                             GatewayId=gateway_id)
        except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e:
            module.fail_json_aws(e, msg="Couldn't associate gateway with route table")
    return True
Пример #17
0
def disassociate_ipv6_cidr(conn, module, subnet, start_time):
    if subnet.get('assign_ipv6_address_on_creation'):
        ensure_assign_ipv6_on_create(conn, module, subnet, False, False,
                                     start_time)

    try:
        conn.disassociate_subnet_cidr_block(
            AssociationId=subnet['ipv6_association_id'])
    except (botocore.exceptions.ClientError,
            botocore.exceptions.BotoCoreError) as e:
        module.fail_json_aws(
            e,
            msg="Couldn't disassociate ipv6 cidr block id {0} from subnet {1}".
            format(subnet['ipv6_association_id'], subnet['id']))

    # Wait for cidr block to be disassociated
    if module.params['wait']:
        filters = ansible_dict_to_boto3_filter_list({
            'ipv6-cidr-block-association.state': ['disassociated'],
            'vpc-id':
            subnet['vpc_id']
        })
        handle_waiter(conn, module, 'subnet_exists', {
            'SubnetIds': [subnet['id']],
            'Filters': filters
        }, start_time)
Пример #18
0
def instance_info(module, conn):
    instance_name = module.params.get('db_instance_identifier')
    filters = module.params.get('filters')

    params = dict()
    if instance_name:
        params['DBInstanceIdentifier'] = instance_name
    if filters:
        params['Filters'] = ansible_dict_to_boto3_filter_list(filters)

    paginator = conn.get_paginator('describe_db_instances')
    try:
        results = paginator.paginate(**params).build_full_result()['DBInstances']
    except is_boto3_error_code('DBInstanceNotFound'):
        results = []
    except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e:  # pylint: disable=duplicate-except
        module.fail_json_aws(e, "Couldn't get instance information")

    for instance in results:
        try:
            instance['Tags'] = boto3_tag_list_to_ansible_dict(conn.list_tags_for_resource(ResourceName=instance['DBInstanceArn'],
                                                                                          aws_retry=True)['TagList'])
        except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e:
            module.fail_json_aws(e, "Couldn't get tags for instance %s" % instance['DBInstanceIdentifier'])

    return dict(changed=False, instances=[camel_dict_to_snake_dict(instance, ignore_list=['Tags']) for instance in results])
    def parse(self, inventory, loader, path, cache=True):
        super(InventoryModule, self).parse(inventory, loader, path)

        config_data = self._read_config_data(path)
        self._set_credentials()

        # get user specifications
        regions = self.get_option('regions')
        filters = self.get_option('filters')
        strict_permissions = self.get_option('strict_permissions')
        statuses = self.get_option('statuses')
        include_clusters = self.get_option('include_clusters')
        instance_filters = ansible_dict_to_boto3_filter_list(filters)
        cluster_filters = []
        if 'db-cluster-id' in filters and include_clusters:
            cluster_filters = ansible_dict_to_boto3_filter_list(
                {'db-cluster-id': filters['db-cluster-id']})

        cache_key = self.get_cache_key(path)
        # false when refresh_cache or --flush-cache is used
        if cache:
            # get the user-specified directive
            cache = self.get_option('cache')

        # Generate inventory
        formatted_inventory = {}
        cache_needs_update = False
        if cache:
            try:
                results = self._cache[cache_key]
            except KeyError:
                # if cache expires or cache file doesn't exist
                cache_needs_update = True
            else:
                self._populate_from_source(results)

        if not cache or cache_needs_update:
            results = self._get_all_hosts(regions, instance_filters,
                                          cluster_filters, strict_permissions,
                                          statuses, include_clusters)
            self._populate(results)
            formatted_inventory = self._format_inventory(results)

        # If the cache has expired/doesn't exist or if refresh_inventory/flush cache is used
        # when the user is using caching, update the cached inventory
        if cache_needs_update or (not cache and self.get_option('cache')):
            self._cache[cache_key] = formatted_inventory
Пример #20
0
def ensure_tags(conn, module, subnet, tags, purge_tags, start_time):
    changed = False

    filters = ansible_dict_to_boto3_filter_list({
        'resource-id': subnet['id'],
        'resource-type': 'subnet'
    })
    try:
        cur_tags = conn.describe_tags(Filters=filters)
    except (botocore.exceptions.ClientError,
            botocore.exceptions.BotoCoreError) as e:
        module.fail_json_aws(e, msg="Couldn't describe tags")

    to_update, to_delete = compare_aws_tags(
        boto3_tag_list_to_ansible_dict(cur_tags.get('Tags')), tags, purge_tags)

    if to_update:
        try:
            if not module.check_mode:
                AWSRetry.exponential_backoff(
                    catch_extra_error_codes=['InvalidSubnetID.NotFound'])(
                        conn.create_tags)(
                            Resources=[subnet['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, msg="Couldn't create tags")

    if to_delete:
        try:
            if not module.check_mode:
                tags_list = []
                for key in to_delete:
                    tags_list.append({'Key': key})

                AWSRetry.exponential_backoff(
                    catch_extra_error_codes=['InvalidSubnetID.NotFound'])(
                        conn.delete_tags)(Resources=[subnet['id']],
                                          Tags=tags_list)

            changed = True
        except (botocore.exceptions.ClientError,
                botocore.exceptions.BotoCoreError) as e:
            module.fail_json_aws(e, msg="Couldn't delete tags")

    if module.params['wait'] and not module.check_mode:
        # Wait for tags to be updated
        filters = [{
            'Name': 'tag:{0}'.format(k),
            'Values': [v]
        } for k, v in tags.items()]
        handle_waiter(conn, module, 'subnet_exists', {
            'SubnetIds': [subnet['id']],
            'Filters': filters
        }, start_time)

    return changed
Пример #21
0
def list_ec2_images(ec2_client, module):

    image_ids = module.params.get("image_ids")
    owners = module.params.get("owners")
    executable_users = module.params.get("executable_users")
    filters = module.params.get("filters")
    owner_param = []

    # describe_images is *very* slow if you pass the `Owners`
    # param (unless it's self), for some reason.
    # Converting the owners to filters and removing from the
    # owners param greatly speeds things up.
    # Implementation based on aioue's suggestion in #24886
    for owner in owners:
        if owner.isdigit():
            if 'owner-id' not in filters:
                filters['owner-id'] = list()
            filters['owner-id'].append(owner)
        elif owner == 'self':
            # self not a valid owner-alias filter (https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_DescribeImages.html)
            owner_param.append(owner)
        else:
            if 'owner-alias' not in filters:
                filters['owner-alias'] = list()
            filters['owner-alias'].append(owner)

    filters = ansible_dict_to_boto3_filter_list(filters)

    try:
        images = ec2_client.describe_images(ImageIds=image_ids,
                                            Filters=filters,
                                            Owners=owner_param,
                                            ExecutableUsers=executable_users)
        images = [
            camel_dict_to_snake_dict(image) for image in images["Images"]
        ]
    except (ClientError, BotoCoreError) as err:
        module.fail_json_aws(err, msg="error describing images")
    for image in images:
        try:
            image['tags'] = boto3_tag_list_to_ansible_dict(
                image.get('tags', []))
            if module.params.get("describe_image_attributes"):
                launch_permissions = ec2_client.describe_image_attribute(
                    Attribute='launchPermission',
                    ImageId=image['image_id'])['LaunchPermissions']
                image['launch_permissions'] = [
                    camel_dict_to_snake_dict(perm)
                    for perm in launch_permissions
                ]
        except (ClientError, BotoCoreError) as err:
            # describing launch permissions of images owned by others is not permitted, but shouldn't cause failures
            pass

    images.sort(
        key=lambda e: e.get('creation_date', '')
    )  # it may be possible that creation_date does not always exist
    module.exit_json(images=images)
Пример #22
0
    def ensure_tags(self, tgw_vpc_attachment_id, tags, purge_tags):
        """
        Ensures tags are applied to the transit gateway.  Optionally will remove any
        existing tags not in the tags argument if purge_tags is set to true

        :param tgw_vpc_attachment_id:  The AWS id of the transit gateway VPC attachment
        :param tags:  list of tags to  apply to the  transit gateway.
        :param purge_tags:  when true existing tags not in tags parms are removed
        :return:  true if tags were updated
        """
        tags_changed = False
        filters = ansible_dict_to_boto3_filter_list(
            {'resource-id': tgw_vpc_attachment_id})
        try:
            cur_tags = self._connection.describe_tags(Filters=filters)
        except (ClientError, BotoCoreError) as e:
            self._module.fail_json_aws(e, msg="Couldn't describe tags")

        to_update, to_delete = compare_aws_tags(
            boto3_tag_list_to_ansible_dict(cur_tags.get('Tags')), tags,
            purge_tags)

        if to_update:
            try:
                if not self._check_mode:
                    AWSRetry.exponential_backoff()(
                        self._connection.create_tags)(
                            Resources=[tgw_vpc_attachment_id],
                            Tags=ansible_dict_to_boto3_tag_list(to_update))
                self._results['changed'] = True
                tags_changed = True
            except (ClientError, BotoCoreError) as e:
                self._module.fail_json_aws(
                    e,
                    msg="Couldn't create tags {0} for resource {1}".format(
                        ansible_dict_to_boto3_tag_list(to_update),
                        tgw_vpc_attachment_id))

        if to_delete:
            try:
                if not self._check_mode:
                    tags_list = []
                    for key in to_delete:
                        tags_list.append({'Key': key})

                    AWSRetry.exponential_backoff()(
                        self._connection.delete_tags)(
                            Resources=[tgw_vpc_attachment_id], Tags=tags_list)
                self._results['changed'] = True
                tags_changed = True
            except (ClientError, BotoCoreError) as e:
                self._module.fail_json_aws(
                    e,
                    msg="Couldn't delete tags {0} for resource {1}".format(
                        ansible_dict_to_boto3_tag_list(to_delete),
                        tgw_vpc_attachment_id))

        return tags_changed
Пример #23
0
    def ensure_tags(self, igw_id, tags, purge_tags):
        final_tags = []

        filters = ansible_dict_to_boto3_filter_list({'resource-id': igw_id, 'resource-type': 'internet-gateway'})
        cur_tags = None
        try:
            cur_tags = self._connection.describe_tags(aws_retry=True, Filters=filters)
        except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e:
            self._module.fail_json_aws(e, msg="Couldn't describe tags")

        if tags is None:
            return boto3_tag_list_to_ansible_dict(cur_tags.get('Tags'))

        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 self._check_mode:
                    final_tags.update(to_update)
                else:
                    self._connection.create_tags(
                        aws_retry=True,
                        Resources=[igw_id],
                        Tags=ansible_dict_to_boto3_tag_list(to_update)
                    )

                self._results['changed'] = True
            except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e:
                self._module.fail_json_aws(e, msg="Couldn't create tags")

        if to_delete:
            try:
                if self._check_mode:
                    for key in to_delete:
                        del final_tags[key]
                else:
                    tags_list = []
                    for key in to_delete:
                        tags_list.append({'Key': key})

                    self._connection.delete_tags(aws_retry=True, Resources=[igw_id], Tags=tags_list)

                self._results['changed'] = True
            except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e:
                self._module.fail_json_aws(e, msg="Couldn't delete tags")

        if not self._check_mode and (to_update or to_delete):
            try:
                response = self._connection.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:
                self._module.fail_json_aws(e, msg="Couldn't describe tags")

        return final_tags
Пример #24
0
    def test_ansible_dict_with_string_to_boto3_filter_list(self):
        filters = {'some-aws-id': 'i-01234567'}
        filter_list_string = [{
            'Name': 'some-aws-id',
            'Values': [
                'i-01234567',
            ]
        }]

        converted_filters_list = ansible_dict_to_boto3_filter_list(filters)
        self.assertEqual(converted_filters_list, filter_list_string)
Пример #25
0
    def test_ansible_dict_with_boolean_to_boto3_filter_list(self):
        filters = {'enabled': True}
        filter_list_boolean = [{
            'Name': 'enabled',
            'Values': [
                'true',
            ]
        }]

        converted_filters_bool = ansible_dict_to_boto3_filter_list(filters)
        self.assertEqual(converted_filters_bool, filter_list_boolean)
def list_ec2_vpc_route_tables(connection, module):

    filters = ansible_dict_to_boto3_filter_list(module.params.get("filters"))

    try:
        results = describe_route_tables_with_backoff(connection, Filters=filters)
    except (botocore.exceptions.BotoCoreError, botocore.exceptions.ClientError) as e:
        module.fail_json_aws(e, msg="Failed to get route tables")

    results = normalize_results(results)
    module.exit_json(changed=False, **results)
Пример #27
0
    def test_ansible_dict_with_integer_to_boto3_filter_list(self):
        filters = {'version': 1}
        filter_list_integer = [{
            'Name': 'version',
            'Values': [
                '1',
            ]
        }]

        converted_filters_int = ansible_dict_to_boto3_filter_list(filters)
        self.assertEqual(converted_filters_int, filter_list_integer)
Пример #28
0
def get_matching_subnet(conn, module, vpc_id, cidr):
    filters = ansible_dict_to_boto3_filter_list({'vpc-id': vpc_id, 'cidr-block': cidr})
    try:
        subnets = get_subnet_info(describe_subnets_with_backoff(conn, Filters=filters))
    except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e:
        module.fail_json_aws(e, msg="Couldn't get matching subnet")

    if subnets:
        return subnets[0]

    return None
def get_services(client, module):
    paginator = client.get_paginator('describe_vpc_endpoint_services')
    params = {}
    if module.params.get("filters"):
        params['Filters'] = ansible_dict_to_boto3_filter_list(module.params.get("filters"))

    if module.params.get("service_names"):
        params['ServiceNames'] = module.params.get("service_names")

    results = paginator.paginate(**params).build_full_result()
    return results
def get_vpc_peers(client, module):
    params = dict()
    params['Filters'] = ansible_dict_to_boto3_filter_list(module.params.get('filters'))
    if module.params.get('peer_connection_ids'):
        params['VpcPeeringConnectionIds'] = module.params.get('peer_connection_ids')
    try:
        result = json.loads(json.dumps(client.describe_vpc_peering_connections(**params), default=date_handler))
    except Exception as e:
        module.fail_json(msg=str(e.message))

    return result['VpcPeeringConnections']