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'])
예제 #2
0
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
예제 #3
0
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))
예제 #4
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'))
예제 #5
0
def update_vpc_tags(connection, module, vpc_id, tags, name):
    if tags is None:
        tags = dict()

    tags.update({'Name': name})
    tags = dict((k, to_native(v)) for k, v in tags.items())
    try:
        current_tags = dict((t['Key'], t['Value']) for t in connection.describe_tags(Filters=[{'Name': 'resource-id', 'Values': [vpc_id]}])['Tags'])
        tags_to_update, dummy = compare_aws_tags(current_tags, tags, False)
        if tags_to_update:
            if not module.check_mode:
                tags = ansible_dict_to_boto3_tag_list(tags_to_update)
                vpc_obj = AWSRetry.backoff(
                    delay=1, tries=5,
                    catch_extra_error_codes=['InvalidVpcID.NotFound'],
                )(connection.create_tags)(Resources=[vpc_id], Tags=tags)

                # Wait for tags to be updated
                expected_tags = boto3_tag_list_to_ansible_dict(tags)
                filters = [{'Name': 'tag:{0}'.format(key), 'Values': [value]} for key, value in expected_tags.items()]
                connection.get_waiter('vpc_available').wait(VpcIds=[vpc_id], Filters=filters)

            return True
        else:
            return False
    except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e:
        module.fail_json_aws(e, msg="Failed to update tags")
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
예제 #7
0
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
예제 #8
0
    def _add_hosts(self, hosts, group):
        '''
            :param hosts: a list of hosts to be added to a group
            :param group: the name of the group to which the hosts belong
        '''
        for host in hosts:
            hostname = self._get_hostname(host)
            host = camel_dict_to_snake_dict(host, ignore_list=['Tags'])
            host['tags'] = boto3_tag_list_to_ansible_dict(host.get('tags', []))

            # Allow easier grouping by region
            if 'availability_zone' in host:
                host['region'] = host['availability_zone'][:-1]
            elif 'availability_zones' in host:
                host['region'] = host['availability_zones'][0][:-1]

            self.inventory.add_host(hostname, group=group)
            for hostvar, hostval in host.items():
                self.inventory.set_variable(hostname, hostvar, hostval)

            # Use constructed if applicable
            strict = self.get_option('strict')
            # Composed variables
            self._set_composite_vars(self.get_option('compose'), host, hostname, strict=strict)
            # Complex groups based on jinja2 conditionals, hosts that meet the conditional are added to group
            self._add_host_to_composed_groups(self.get_option('groups'), host, hostname, strict=strict)
            # Create groups based on variable values and add the corresponding hosts to it
            self._add_host_to_keyed_groups(self.get_option('keyed_groups'), host, hostname, strict=strict)
예제 #9
0
def get_tags(client, module, cluster_arn):
    try:
        return boto3_tag_list_to_ansible_dict(
            client.list_tags_for_resource(ResourceName=cluster_arn)['TagList']
        )
    except (BotoCoreError, ClientError) as e:
        module.fail_json_aws(e, msg="Unable to describe tags")
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)
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)
예제 #12
0
def compare_tags(state_machine_arn, sfn_client, module):
    new_tags = module.params.get('tags')
    current_tags = sfn_client.list_tags_for_resource(
        resourceArn=state_machine_arn).get('tags')
    return compare_aws_tags(boto3_tag_list_to_ansible_dict(current_tags),
                            new_tags if new_tags else {},
                            module.params.get('purge_tags'))
예제 #13
0
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
예제 #14
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(msg=e.message)

    # 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)
예제 #15
0
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
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)
예제 #17
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'])
예제 #18
0
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))
예제 #19
0
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)
예제 #20
0
def get_target_group_tags(connection, module, target_group_arn):

    try:
        return boto3_tag_list_to_ansible_dict(
            connection.describe_tags(
                ResourceArns=[target_group_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))
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)
    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 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
예제 #24
0
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())
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)
예제 #26
0
def get_target_group_attributes(connection, module, target_group_arn):

    try:
        target_group_attributes = boto3_tag_list_to_ansible_dict(
            connection.describe_target_group_attributes(
                TargetGroupArn=target_group_arn)['Attributes'])
    except ClientError as e:
        module.fail_json(msg=e.message,
                         exception=traceback.format_exc(),
                         **camel_dict_to_snake_dict(e.response))

    # Replace '.' with '_' in attribute key names to make it more Ansibley
    return dict(
        (k.replace('.', '_'), v) for (k, v) in target_group_attributes.items())
예제 #27
0
def list_ec2_vpc_nacls(connection, module):

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

    if nacl_ids is None:
        nacl_ids = []

    try:
        nacls = connection.describe_network_acls(NetworkAclIds=nacl_ids,
                                                 Filters=filters)
    except ClientError as e:
        module.fail_json_aws(
            e,
            msg="Unable to describe network ACLs {0}: {1}".format(
                nacl_ids, to_native(e)))
    except BotoCoreError as e:
        module.fail_json_aws(
            e,
            msg="Unable to describe network ACLs {0}: {1}".format(
                nacl_ids, to_native(e)))

    # Turn the boto3 result in to ansible_friendly_snaked_names
    snaked_nacls = []
    for nacl in nacls['NetworkAcls']:
        snaked_nacls.append(camel_dict_to_snake_dict(nacl))

    # Turn the boto3 result in to ansible friendly tag dictionary
    for nacl in snaked_nacls:
        if 'tags' in nacl:
            nacl['tags'] = boto3_tag_list_to_ansible_dict(
                nacl['tags'], 'key', 'value')
        if 'entries' in nacl:
            nacl['egress'] = [
                nacl_entry_to_list(entry) for entry in nacl['entries']
                if entry['rule_number'] < 32767 and entry['egress']
            ]
            nacl['ingress'] = [
                nacl_entry_to_list(entry) for entry in nacl['entries']
                if entry['rule_number'] < 32767 and not entry['egress']
            ]
            del nacl['entries']
        if 'associations' in nacl:
            nacl['subnets'] = [a['subnet_id'] for a in nacl['associations']]
            del nacl['associations']
        if 'network_acl_id' in nacl:
            nacl['nacl_id'] = nacl['network_acl_id']
            del nacl['network_acl_id']

    module.exit_json(nacls=snaked_nacls)
예제 #28
0
def snapshot_to_facts(client, module, snapshot):
    try:
        snapshot['Tags'] = boto3_tag_list_to_ansible_dict(
            client.list_tags_for_resource(
                ResourceName=snapshot['DBSnapshotArn'],
                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['DBSnapshotIdentifier'])
    except KeyError:
        module.fail_json(msg=str(snapshot))

    return camel_dict_to_snake_dict(snapshot, ignore_list=['Tags'])
예제 #29
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
예제 #30
0
def get_eips_details(module):
    connection = module.client('ec2')
    filters = module.params.get("filters")
    try:
        response = connection.describe_addresses(
            Filters=ansible_dict_to_boto3_filter_list(filters)
        )
    except (BotoCoreError, ClientError) as e:
        module.fail_json_aws(
            e,
            msg="Error retrieving EIPs")

    addresses = camel_dict_to_snake_dict(response)['addresses']
    for address in addresses:
        if 'tags' in address:
            address['tags'] = boto3_tag_list_to_ansible_dict(address['tags'])
    return addresses