def test_check_for_update_tags(placeboify, maybe_sleep):
    # setup dependencies for 1 vpn connection
    dependencies = setup_req(placeboify, 1)
    params, vpn, m, conn = dependencies['params'], dependencies[
        'vpn'], dependencies['module'], dependencies['connection']

    # add and remove a number of tags
    m.params['tags'] = {'One': 'one', 'Two': 'two'}
    ec2_vpc_vpn.ensure_present(conn, m.params)
    m.params['tags'] = {'Two': 'two', 'Three': 'three', 'Four': 'four'}
    changes = ec2_vpc_vpn.check_for_update(conn, m.params,
                                           vpn['VpnConnectionId'])

    flat_dict_changes = boto3_tag_list_to_ansible_dict(changes['tags_to_add'])
    correct_changes = boto3_tag_list_to_ansible_dict([{
        'Key': 'Three',
        'Value': 'three'
    }, {
        'Key': 'Four',
        'Value': 'four'
    }])
    assert flat_dict_changes == correct_changes
    assert changes['tags_to_remove'] == ['One']

    # delete connection
    tear_down_conn(placeboify, conn, vpn['VpnConnectionId'])
def get_subnet_info(subnet):
    if 'Subnets' in subnet:
        return [get_subnet_info(s) for s in subnet['Subnets']]
    elif 'Subnet' in subnet:
        subnet = camel_dict_to_snake_dict(subnet['Subnet'])
    else:
        subnet = camel_dict_to_snake_dict(subnet)

    if 'tags' in subnet:
        subnet['tags'] = boto3_tag_list_to_ansible_dict(subnet['tags'])
    else:
        subnet['tags'] = dict()

    if 'subnet_id' in subnet:
        subnet['id'] = subnet['subnet_id']
        del subnet['subnet_id']

    subnet['ipv6_cidr_block'] = ''
    subnet['ipv6_association_id'] = ''
    ipv6set = subnet.get('ipv6_cidr_block_association_set')
    if ipv6set:
        for item in ipv6set:
            if item.get('ipv6_cidr_block_state',
                        {}).get('state') in ('associated', 'associating'):
                subnet['ipv6_cidr_block'] = item['ipv6_cidr_block']
                subnet['ipv6_association_id'] = item['association_id']

    return subnet
Exemplo n.º 3
0
def get_trail_facts(module, client, name):
    """
    Describes existing trail in an account

    module : AnsibleModule object
    client : boto3 client connection object
    name : Name of the trail
    """
    # get Trail info
    try:
        trail_resp = client.describe_trails(trailNameList=[name])
    except ClientError as err:
        module.fail_json(msg=err.message, exception=traceback.format_exc(), **camel_dict_to_snake_dict(err.response))

    # Now check to see if our trail exists and get status and tags
    if len(trail_resp['trailList']):
        trail = trail_resp['trailList'][0]
        try:
            status_resp = client.get_trail_status(Name=trail['Name'])
            tags_list = client.list_tags(ResourceIdList=[trail['TrailARN']])
        except ClientError as err:
            module.fail_json(msg=err.message, exception=traceback.format_exc(), **camel_dict_to_snake_dict(err.response))

        trail['IsLogging'] = status_resp['IsLogging']
        trail['tags'] = boto3_tag_list_to_ansible_dict(tags_list['ResourceTagList'][0]['TagsList'])
        # Check for non-existent values and populate with None
        optional_vals = set(['S3KeyPrefix', 'SnsTopicName', 'SnsTopicARN', 'CloudWatchLogsLogGroupArn', 'CloudWatchLogsRoleArn', 'KmsKeyId'])
        for v in optional_vals - set(trail.keys()):
            trail[v] = None
        return trail

    else:
        # trail doesn't exist return None
        return None
def common_snapshot_info(module, conn, method, prefix, params):
    paginator = conn.get_paginator(method)
    try:
        results = paginator.paginate(**params).build_full_result()['%ss' %
                                                                   prefix]
    except is_boto3_error_code('%sNotFound' % prefix):
        results = []
    except (botocore.exceptions.ClientError,
            botocore.exceptions.BotoCoreError) as e:  # pylint: disable=duplicate-except
        module.fail_json_aws(e, "trying to get snapshot information")

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

    return [
        camel_dict_to_snake_dict(snapshot, ignore_list=['Tags'])
        for snapshot in results
    ]
Exemplo n.º 5
0
def update_tags(module, connection, group, tags):
    changed = False
    existing_tags = connection.list_tags_for_resource(
        ResourceName=group['DBParameterGroupArn'])['TagList']
    to_update, to_delete = compare_aws_tags(
        boto3_tag_list_to_ansible_dict(existing_tags), tags,
        module.params['purge_tags'])
    if to_update:
        try:
            connection.add_tags_to_resource(
                ResourceName=group['DBParameterGroupArn'],
                Tags=ansible_dict_to_boto3_tag_list(to_update))
            changed = True
        except botocore.exceptions.ClientError as e:
            module.fail_json(msg="Couldn't add tags to parameter group: %s" %
                             str(e),
                             exception=traceback.format_exc(),
                             **camel_dict_to_snake_dict(e.response))
        except botocore.exceptions.ParamValidationError as e:
            # Usually a tag value has been passed as an int or bool, needs to be a string
            # The AWS exception message is reasonably ok for this purpose
            module.fail_json(msg="Couldn't add tags to parameter group: %s." %
                             str(e),
                             exception=traceback.format_exc())
    if to_delete:
        try:
            connection.remove_tags_from_resource(
                ResourceName=group['DBParameterGroupArn'], TagKeys=to_delete)
            changed = True
        except botocore.exceptions.ClientError as e:
            module.fail_json(
                msg="Couldn't remove tags from parameter group: %s" % str(e),
                exception=traceback.format_exc(),
                **camel_dict_to_snake_dict(e.response))
    return changed
def ensure_snapshot_present(client, module):
    db_instance_identifier = module.params.get('db_instance_identifier')
    snapshot_name = module.params.get('db_snapshot_identifier')
    changed = False
    snapshot = get_snapshot(client, module, snapshot_name)
    if not snapshot:
        try:
            snapshot = client.create_db_snapshot(
                DBSnapshotIdentifier=snapshot_name,
                DBInstanceIdentifier=db_instance_identifier)['DBSnapshot']
            changed = True
        except (botocore.exceptions.ClientError,
                botocore.exceptions.BotoCoreError) as e:
            module.fail_json_aws(e, msg="trying to create db snapshot")

    if module.params.get('wait'):
        wait_for_snapshot_status(client, module, snapshot_name,
                                 'db_snapshot_available')

    existing_tags = boto3_tag_list_to_ansible_dict(
        client.list_tags_for_resource(ResourceName=snapshot['DBSnapshotArn'],
                                      aws_retry=True)['TagList'])
    desired_tags = module.params['tags']
    purge_tags = module.params['purge_tags']
    changed |= ensure_tags(client, module, snapshot['DBSnapshotArn'],
                           existing_tags, desired_tags, purge_tags)

    snapshot = get_snapshot(client, module, snapshot_name)

    return dict(changed=changed, **snapshot_to_facts(client, module, snapshot))
def format_module_output(module):
    output = {}
    template, template_versions = existing_templates(module)
    template = camel_dict_to_snake_dict(template)
    template_versions = [camel_dict_to_snake_dict(v) for v in template_versions]
    for v in template_versions:
        for ts in (v['launch_template_data'].get('tag_specifications') or []):
            ts['tags'] = boto3_tag_list_to_ansible_dict(ts.pop('tags'))
    output.update(dict(template=template, versions=template_versions))
    output['default_template'] = [
        v for v in template_versions
        if v.get('default_version')
    ][0]
    output['latest_template'] = [
        v for v in template_versions
        if (
            v.get('version_number') and
            int(v['version_number']) == int(template['latest_version_number'])
        )
    ][0]
    if "version_number" in output['default_template']:
        output['default_version'] = output['default_template']['version_number']
    if "version_number" in output['latest_template']:
        output['latest_version'] = output['latest_template']['version_number']
    return output
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)
def describe_iam_role(module, client, role):
    name = role['RoleName']
    try:
        role['InlinePolicies'] = list_iam_role_policies_with_backoff(
            client, name)
    except (botocore.exceptions.ClientError,
            botocore.exceptions.BotoCoreError) as e:
        module.fail_json_aws(e,
                             msg="Couldn't get inline policies for role %s" %
                             name)
    try:
        role['ManagedPolicies'] = list_iam_attached_role_policies_with_backoff(
            client, name)
    except (botocore.exceptions.ClientError,
            botocore.exceptions.BotoCoreError) as e:
        module.fail_json_aws(e,
                             msg="Couldn't get managed  policies for role %s" %
                             name)
    try:
        role[
            'InstanceProfiles'] = list_iam_instance_profiles_for_role_with_backoff(
                client, name)
    except (botocore.exceptions.ClientError,
            botocore.exceptions.BotoCoreError) as e:
        module.fail_json_aws(e,
                             msg="Couldn't get instance profiles for role %s" %
                             name)
    try:
        role['tags'] = boto3_tag_list_to_ansible_dict(role['Tags'])
        del role['Tags']
    except KeyError:
        role['tags'] = {}
    return role
def get_key_details(connection, module, key_id):
    try:
        result = get_kms_metadata_with_backoff(connection,
                                               key_id)['KeyMetadata']
    except (botocore.exceptions.ClientError,
            botocore.exceptions.BotoCoreError) as e:
        module.fail_json_aws(e, msg="Failed to obtain key metadata")
    result['KeyArn'] = result.pop('Arn')

    try:
        aliases = get_kms_aliases_lookup(connection)
    except (botocore.exceptions.ClientError,
            botocore.exceptions.BotoCoreError) as e:
        module.fail_json_aws(e, msg="Failed to obtain aliases")

    result['aliases'] = aliases.get(result['KeyId'], [])

    result = camel_dict_to_snake_dict(result)

    # grants and tags get snakified differently
    try:
        result['grants'] = [
            camel_to_snake_grant(grant) for grant in
            get_kms_grants_with_backoff(connection, key_id)['Grants']
        ]
    except (botocore.exceptions.ClientError,
            botocore.exceptions.BotoCoreError) as e:
        module.fail_json_aws(e, msg="Failed to obtain key grants")
    tags = get_kms_tags(connection, module, key_id)
    result['tags'] = boto3_tag_list_to_ansible_dict(tags, 'TagKey', 'TagValue')
    result['policies'] = get_kms_policies(connection, module, key_id)
    return result
Exemplo n.º 11
0
def describe_subnets(connection, module):
    """
    Describe Subnets.

    module  : AnsibleModule 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 as e:
        module.fail_json(msg=to_native(e), exception=traceback.format_exc(), **camel_dict_to_snake_dict(e.response))

    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)
Exemplo n.º 12
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 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=str(e.message))

    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
Exemplo n.º 14
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(msg=e.message,
                         exception=traceback.format_exc(),
                         **camel_dict_to_snake_dict(e.response))

    # 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)
Exemplo n.º 15
0
def update_role_tags(connection, module):
    new_tags = module.params.get('tags')
    if new_tags is None:
        return False

    role_name = module.params.get('name')
    purge_tags = module.params.get('purge_tags')

    try:
        existing_tags = boto3_tag_list_to_ansible_dict(
            connection.list_role_tags(RoleName=role_name)['Tags'])
    except (ClientError, KeyError):
        existing_tags = {}

    tags_to_add, tags_to_remove = compare_aws_tags(existing_tags,
                                                   new_tags,
                                                   purge_tags=purge_tags)

    if not module.check_mode:
        try:
            if tags_to_remove:
                connection.untag_role(RoleName=role_name,
                                      TagKeys=tags_to_remove)
            if tags_to_add:
                connection.tag_role(
                    RoleName=role_name,
                    Tags=ansible_dict_to_boto3_tag_list(tags_to_add))
        except (ClientError, BotoCoreError) as e:
            module.fail_json_aws(e,
                                 msg='Unable to set tags for role %s' %
                                 role_name)

    changed = bool(tags_to_add) or bool(tags_to_remove)
    return changed
Exemplo n.º 16
0
def get_ami_info(camel_image):
    image = camel_dict_to_snake_dict(camel_image)
    return dict(image_id=image.get("image_id"),
                state=image.get("state"),
                architecture=image.get("architecture"),
                block_device_mapping=get_block_device_mapping(image),
                creationDate=image.get("creation_date"),
                description=image.get("description"),
                hypervisor=image.get("hypervisor"),
                is_public=image.get("public"),
                location=image.get("image_location"),
                ownerId=image.get("owner_id"),
                root_device_name=image.get("root_device_name"),
                root_device_type=image.get("root_device_type"),
                virtualization_type=image.get("virtualization_type"),
                name=image.get("name"),
                tags=boto3_tag_list_to_ansible_dict(image.get('tags')),
                platform=image.get("platform"),
                enhanced_networking=image.get("ena_support"),
                image_owner_alias=image.get("image_owner_alias"),
                image_type=image.get("image_type"),
                kernel_id=image.get("kernel_id"),
                product_codes=image.get("product_codes"),
                ramdisk_id=image.get("ramdisk_id"),
                sriov_net_support=image.get("sriov_net_support"),
                state_reason=image.get("state_reason"),
                launch_permissions=image.get('launch_permissions'))
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
Exemplo n.º 18
0
def ensure_present(module, connection):
    groupname = module.params['name']
    tags = module.params.get('tags')
    changed = False
    errors = []
    try:
        response = connection.describe_db_parameter_groups(
            DBParameterGroupName=groupname)
    except botocore.exceptions.ClientError as e:
        if e.response['Error']['Code'] == 'DBParameterGroupNotFound':
            response = None
        else:
            module.fail_json(
                msg="Couldn't access parameter group information: %s" % str(e),
                exception=traceback.format_exc(),
                **camel_dict_to_snake_dict(e.response))
    if not response:
        params = dict(DBParameterGroupName=groupname,
                      DBParameterGroupFamily=module.params['engine'],
                      Description=module.params['description'])
        if tags:
            params['Tags'] = ansible_dict_to_boto3_tag_list(tags)
        try:
            response = connection.create_db_parameter_group(**params)
            changed = True
        except botocore.exceptions.ClientError as e:
            module.fail_json(msg="Couldn't create parameter group: %s" %
                             str(e),
                             exception=traceback.format_exc(),
                             **camel_dict_to_snake_dict(e.response))
    else:
        group = response['DBParameterGroups'][0]
        if tags:
            changed = update_tags(module, connection, group, tags)

    if module.params.get('params'):
        params_changed, errors = update_parameters(module, connection)
        changed = changed or params_changed

    try:
        response = connection.describe_db_parameter_groups(
            DBParameterGroupName=groupname)
        group = camel_dict_to_snake_dict(response['DBParameterGroups'][0])
    except botocore.exceptions.ClientError as e:
        module.fail_json(
            msg="Couldn't obtain parameter group information: %s" % str(e),
            exception=traceback.format_exc(),
            **camel_dict_to_snake_dict(e.response))
    try:
        tags = connection.list_tags_for_resource(
            ResourceName=group['db_parameter_group_arn'])['TagList']
    except botocore.exceptions.ClientError as e:
        module.fail_json(msg="Couldn't obtain parameter group tags: %s" %
                         str(e),
                         exception=traceback.format_exc(),
                         **camel_dict_to_snake_dict(e.response))
    group['tags'] = boto3_tag_list_to_ansible_dict(tags)

    module.exit_json(changed=changed, errors=errors, **group)
Exemplo n.º 19
0
 def get_tags(self, file_system_id):
     """
     Returns tag list for selected instance of EFS
     """
     paginator = self.connection.get_paginator('describe_tags')
     return boto3_tag_list_to_ansible_dict(
         paginator.paginate(
             FileSystemId=file_system_id).build_full_result()['Tags'])
def get_tags(ec2, module, resource):
    filters = [{'Name': 'resource-id', 'Values': [resource]}]
    try:
        return boto3_tag_list_to_ansible_dict(
            ec2.describe_tags(Filters=filters)['Tags'])
    except (BotoCoreError, ClientError) as e:
        module.fail_json_aws(
            e, msg='Failed to fetch tags for resource {0}'.format(resource))
def get_tg_attributes(connection, module, tg_arn):
    try:
        tg_attributes = boto3_tag_list_to_ansible_dict(connection.describe_target_group_attributes(TargetGroupArn=tg_arn)['Attributes'])
    except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e:
        module.fail_json_aws(e, msg="Couldn't get target group attributes")

    # Replace '.' with '_' in attribute key names to make it more Ansibley
    return dict((k.replace('.', '_'), v) for k, v in tg_attributes.items())
Exemplo n.º 22
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)
Exemplo n.º 23
0
def stack_set_facts(cfn, stack_set_name):
    try:
        ss = cfn.describe_stack_set(StackSetName=stack_set_name)['StackSet']
        ss['Tags'] = boto3_tag_list_to_ansible_dict(ss['Tags'])
        return ss
    except cfn.exceptions.from_code('StackSetNotFound'):
        # catch NotFound error before the retry kicks in to avoid waiting
        # if the stack does not exist
        return
Exemplo n.º 24
0
def get_role_tags(connection, module):
    role_name = module.params.get('name')
    if not hasattr(connection, 'list_role_tags'):
        return {}
    try:
        return boto3_tag_list_to_ansible_dict(
            connection.list_role_tags(RoleName=role_name)['Tags'])
    except ClientError:
        return {}
def get_current_bucket_tags_dict(s3_client, bucket_name):
    try:
        current_tags = s3_client.get_bucket_tagging(
            Bucket=bucket_name).get('TagSet')
    except ClientError as e:
        if e.response['Error']['Code'] == 'NoSuchTagSet':
            return {}
        raise e

    return boto3_tag_list_to_ansible_dict(current_tags)
def get_load_balancer_tags(connection, module, load_balancer_arn):

    try:
        return boto3_tag_list_to_ansible_dict(
            connection.describe_tags(ResourceArns=[load_balancer_arn])
            ['TagDescriptions'][0]['Tags'])
    except ClientError as e:
        module.fail_json(msg=e.message,
                         exception=traceback.format_exc(),
                         **camel_dict_to_snake_dict(e.response))
Exemplo n.º 27
0
    def ensure_tags(self, tgw_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_id:  The AWS id of the transit gateway
        :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_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_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_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_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_id))

        return tags_changed
def main():
    argument_spec = ec2_argument_spec()
    argument_spec.update(
        dict(
            filters=dict(default=dict(), type='dict'),
            peer_connection_ids=dict(default=None, type='list'),
        ))

    module = AnsibleModule(argument_spec=argument_spec,
                           supports_check_mode=True)
    if module._name == 'ec2_vpc_peering_facts':
        module.deprecate(
            "The 'ec2_vpc_peering_facts' module has been renamed to 'ec2_vpc_peering_info'",
            version='2.13')

    # Validate Requirements
    if not HAS_BOTO3:
        module.fail_json(msg='botocore and boto3 are required.')

    try:
        region, ec2_url, aws_connect_kwargs = get_aws_connection_info(
            module, boto3=True)
    except NameError as e:
        # Getting around the get_aws_connection_info boto reliance for region
        if "global name 'boto' is not defined" in e.message:
            module.params['region'] = botocore.session.get_session(
            ).get_config_variable('region')
            if not module.params['region']:
                module.fail_json(msg="Error - no region provided")
        else:
            module.fail_json(msg="Can't retrieve connection information - " +
                             str(e))

    try:
        region, ec2_url, aws_connect_kwargs = get_aws_connection_info(
            module, boto3=True)
        ec2 = boto3_conn(module,
                         conn_type='client',
                         resource='ec2',
                         region=region,
                         endpoint=ec2_url,
                         **aws_connect_kwargs)
    except botocore.exceptions.NoCredentialsError as e:
        module.fail_json(msg=str(e))

    # Turn the boto3 result in to ansible friendly_snaked_names
    results = [
        camel_dict_to_snake_dict(peer) for peer in get_vpc_peers(ec2, module)
    ]

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

    module.exit_json(result=results)
Exemplo n.º 29
0
def ensure_present(connection, module_params, check_mode=False):
    """ Creates and adds tags to a VPN connection. If the connection already exists update tags. """
    vpn_connection = find_connection(connection, module_params)
    changed = False
    delay = module_params.get('delay')
    max_attempts = module_params.get('wait_timeout') // delay

    # No match but vpn_connection_id was specified.
    if not vpn_connection and module_params.get('vpn_connection_id'):
        raise VPNConnectionException(
            msg=
            "There is no VPN connection available or pending with that id. Did you delete it?"
        )

    # Unique match was found. Check if attributes provided differ.
    elif vpn_connection:
        vpn_connection_id = vpn_connection['VpnConnectionId']
        # check_for_update returns a dict with the keys tags_to_add, tags_to_remove, routes_to_add, routes_to_remove
        changes = check_for_update(connection, module_params,
                                   vpn_connection_id)
        if check_mode:
            return get_check_mode_results(connection,
                                          module_params,
                                          vpn_connection_id,
                                          current_state=vpn_connection)
        changed = make_changes(connection, vpn_connection_id, changes)

    # No match was found. Create and tag a connection and add routes.
    else:
        changed = True
        if check_mode:
            return get_check_mode_results(connection, module_params)
        vpn_connection = create_connection(
            connection,
            customer_gateway_id=module_params.get('customer_gateway_id'),
            static_only=module_params.get('static_only'),
            vpn_gateway_id=module_params.get('vpn_gateway_id'),
            connection_type=module_params.get('connection_type'),
            tunnel_options=module_params.get('tunnel_options'),
            max_attempts=max_attempts,
            delay=delay)
        changes = check_for_update(connection, module_params,
                                   vpn_connection['VpnConnectionId'])
        make_changes(connection, vpn_connection['VpnConnectionId'], changes)

    # get latest version if a change has been made and make tags output nice before returning it
    if vpn_connection:
        vpn_connection = find_connection(connection, module_params,
                                         vpn_connection['VpnConnectionId'])
        if 'Tags' in vpn_connection:
            vpn_connection['Tags'] = boto3_tag_list_to_ansible_dict(
                vpn_connection['Tags'])

    return changed, vpn_connection
def main():
    argument_spec = ec2_argument_spec()
    argument_spec.update(dict(filters=dict(default={}, type='dict')))

    module = AnsibleModule(argument_spec=argument_spec,
                           supports_check_mode=True)
    if module._name == 'ec2_group_facts':
        module.deprecate(
            "The 'ec2_group_facts' module has been renamed to 'ec2_group_info'",
            version='2.13')

    if not HAS_BOTO3:
        module.fail_json(msg='boto3 required for this module')

    region, ec2_url, aws_connect_params = get_aws_connection_info(module,
                                                                  boto3=True)

    if region:
        connection = boto3_conn(module,
                                conn_type='client',
                                resource='ec2',
                                region=region,
                                endpoint=ec2_url,
                                **aws_connect_params)
    else:
        module.fail_json(msg="region must be specified")

    # Replace filter key underscores with dashes, for compatibility, except if we're dealing with tags
    sanitized_filters = module.params.get("filters")
    for key in list(sanitized_filters):
        if not key.startswith("tag:"):
            sanitized_filters[key.replace("_",
                                          "-")] = sanitized_filters.pop(key)

    try:
        security_groups = connection.describe_security_groups(
            Filters=ansible_dict_to_boto3_filter_list(sanitized_filters))
    except ClientError as e:
        module.fail_json(msg=e.message, exception=traceback.format_exc())

    snaked_security_groups = []
    for security_group in security_groups['SecurityGroups']:
        # Modify boto3 tags list to be ansible friendly dict
        # but don't camel case tags
        security_group = camel_dict_to_snake_dict(security_group)
        security_group['tags'] = boto3_tag_list_to_ansible_dict(
            security_group.get('tags', {}),
            tag_name_key_name='key',
            tag_value_key_name='value')
        snaked_security_groups.append(security_group)

    module.exit_json(security_groups=snaked_security_groups)