Exemplo n.º 1
0
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_jctanner.cloud_amazon.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],
                    jctanner.cloud_amazon.aws_retry=True)['TagList'])
        except (botocore.exceptions.ClientError,
                botocore.exceptions.BotoCoreError) as e:
            module.fail_json_jctanner.cloud_amazon.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
    ]
def await_stack_set_exists(cfn, stack_set_name):
    # AWSRetry will retry on `NotFound` errors for us
    ss = cfn.describe_stack_set(
        StackSetName=stack_set_name,
        jctanner.cloud_amazon.aws_retry=True)['StackSet']
    ss['Tags'] = boto3_tag_list_to_ansible_dict(ss['Tags'])
    return camel_dict_to_snake_dict(ss, ignore_list=('Tags', ))
Exemplo n.º 3
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_jctanner.cloud_amazon.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_jctanner.cloud_amazon.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_jctanner.cloud_amazon.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.º 4
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_jctanner.cloud_amazon.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 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 = self._connection.describe_transit_gateways(Filters=filters)
        except (ClientError, BotoCoreError) as e:
            self._module.fail_json_jctanner.cloud_amazon.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
Exemplo n.º 6
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')
    )
Exemplo n.º 7
0
 def summary_get_distribution_list(self, streaming=False):
     try:
         list_name = 'streaming_distributions' if streaming else 'distributions'
         key_list = ['Id', 'ARN', 'Status', 'LastModifiedTime', 'DomainName', 'Comment', 'PriceClass', 'Enabled']
         distribution_list = {list_name: []}
         distributions = self.list_streaming_distributions(False) if streaming else self.list_distributions(False)
         for dist in distributions:
             temp_distribution = {}
             for key_name in key_list:
                 temp_distribution[key_name] = dist[key_name]
             temp_distribution['Aliases'] = [alias for alias in dist['Aliases'].get('Items', [])]
             temp_distribution['ETag'] = self.get_etag_from_distribution_id(dist['Id'], streaming)
             if not streaming:
                 temp_distribution['WebACLId'] = dist['WebACLId']
                 invalidation_ids = self.get_list_of_invalidation_ids_from_distribution_id(dist['Id'])
                 if invalidation_ids:
                     temp_distribution['Invalidations'] = invalidation_ids
             resource_tags = self.client.list_tags_for_resource(Resource=dist['ARN'])
             temp_distribution['Tags'] = boto3_tag_list_to_ansible_dict(resource_tags['Tags'].get('Items', []))
             distribution_list[list_name].append(temp_distribution)
         return distribution_list
     except botocore.exceptions.ClientError as e:
         self.module.fail_json(msg="Error generating summary of distributions - " + str(e),
                               exception=traceback.format_exc(),
                               **camel_dict_to_snake_dict(e.response))
     except Exception as e:
         self.module.fail_json(msg="Error generating summary of distributions - " + str(e),
                               exception=traceback.format_exc())
Exemplo n.º 8
0
def get_key_details(connection, module, key_id, tokens=None):
    if not tokens:
        tokens = []
    try:
        result = get_kms_metadata_with_backoff(connection, key_id)['KeyMetadata']
    except botocore.exceptions.ClientError as e:
        module.fail_json(msg="Failed to obtain key metadata",
                         exception=traceback.format_exc(),
                         **camel_dict_to_snake_dict(e.response))
    result['KeyArn'] = result.pop('Arn')

    try:
        aliases = get_kms_aliases_lookup(connection)
    except botocore.exceptions.ClientError as e:
        module.fail_json(msg="Failed to obtain aliases",
                         exception=traceback.format_exc(),
                         **camel_dict_to_snake_dict(e.response))
    result['aliases'] = aliases.get(result['KeyId'], [])

    if module.params.get('pending_deletion'):
        return camel_dict_to_snake_dict(result)

    try:
        result['grants'] = get_kms_grants_with_backoff(connection, key_id, tokens=tokens)['Grants']
    except botocore.exceptions.ClientError as e:
        module.fail_json(msg="Failed to obtain key grants",
                         exception=traceback.format_exc(),
                         **camel_dict_to_snake_dict(e.response))
    tags = get_kms_tags(connection, module, key_id)

    result = camel_dict_to_snake_dict(result)
    result['tags'] = boto3_tag_list_to_ansible_dict(tags, 'TagKey', 'TagValue')
    result['policies'] = get_kms_policies(connection, module, key_id)
    return result
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_jctanner.cloud_amazon.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.º 10
0
def get_check_mode_results(connection, module_params, vpn_connection_id=None, current_state=None):
    """ Returns the changes that would be made to a VPN Connection """
    state = module_params.get('state')
    if state == 'absent':
        if vpn_connection_id:
            return True, {}
        else:
            return False, {}

    changed = False
    results = {'customer_gateway_configuration': '',
               'customer_gateway_id': module_params.get('customer_gateway_id'),
               'vpn_gateway_id': module_params.get('vpn_gateway_id'),
               'options': {'static_routes_only': module_params.get('static_only')},
               'routes': [module_params.get('routes')]}

    # get combined current tags and tags to set
    present_tags = module_params.get('tags')
    if current_state and 'Tags' in current_state:
        current_tags = boto3_tag_list_to_ansible_dict(current_state['Tags'])
        if module_params.get('purge_tags'):
            if current_tags != present_tags:
                changed = True
        elif current_tags != present_tags:
            if not set(present_tags.keys()) < set(current_tags.keys()):
                changed = True
            # add preexisting tags that new tags didn't overwrite
            present_tags.update((tag, current_tags[tag]) for tag in current_tags if tag not in present_tags)
        elif current_tags.keys() == present_tags.keys() and set(present_tags.values()) != set(current_tags.values()):
            changed = True
    elif module_params.get('tags'):
        changed = True
    if present_tags:
        results['tags'] = present_tags

    # get combined current routes and routes to add
    present_routes = module_params.get('routes')
    if current_state and 'Routes' in current_state:
        current_routes = [route['DestinationCidrBlock'] for route in current_state['Routes']]
        if module_params.get('purge_routes'):
            if set(current_routes) != set(present_routes):
                changed = True
        elif set(present_routes) != set(current_routes):
            if not set(present_routes) < set(current_routes):
                changed = True
            present_routes.extend([route for route in current_routes if route not in present_routes])
    elif module_params.get('routes'):
        changed = True
    results['routes'] = [{"destination_cidr_block": cidr, "state": "available"} for cidr in present_routes]

    # return the vpn_connection_id if it's known
    if vpn_connection_id:
        results['vpn_connection_id'] = vpn_connection_id
    else:
        changed = True
        results['vpn_connection_id'] = 'vpn-XXXXXXXX'

    return changed, results
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
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())
Exemplo n.º 13
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.º 14
0
def get_load_balancer_attributes(connection, module, load_balancer_arn):

    try:
        load_balancer_attributes = boto3_tag_list_to_ansible_dict(connection.describe_load_balancer_attributes(LoadBalancerArn=load_balancer_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
    for k, v in list(load_balancer_attributes.items()):
        load_balancer_attributes[k.replace('.', '_')] = v
        del load_balancer_attributes[k]

    return load_balancer_attributes
    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_jctanner.cloud_amazon.aws(e, msg="Couldn't describe tags")

        to_update, to_delete = compare_jctanner.cloud_amazon.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_jctanner.cloud_amazon.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_jctanner.cloud_amazon.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
Exemplo n.º 16
0
def get_eips_details(module):
    connection = module.client('jctanner.cloud_amazon.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_jctanner.cloud_amazon.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
Exemplo n.º 17
0
def check_for_update(connection, module_params, vpn_connection_id):
    """ Determines if there are any tags or routes that need to be updated. Ensures non-modifiable attributes aren't expected to change. """
    tags = module_params.get('tags')
    routes = module_params.get('routes')
    purge_tags = module_params.get('purge_tags')
    purge_routes = module_params.get('purge_routes')

    vpn_connection = find_connection(connection, module_params, vpn_connection_id=vpn_connection_id)
    current_attrs = camel_dict_to_snake_dict(vpn_connection)

    # Initialize changes dict
    changes = {'tags_to_add': [],
               'tags_to_remove': [],
               'routes_to_add': [],
               'routes_to_remove': []}

    # Get changes to tags
    current_tags = boto3_tag_list_to_ansible_dict(current_attrs.get('tags', []), u'key', u'value')
    tags_to_add, changes['tags_to_remove'] = compare_jctanner.cloud_amazon.aws_tags(current_tags, tags, purge_tags)
    changes['tags_to_add'] = ansible_dict_to_boto3_tag_list(tags_to_add)
    # Get changes to routes
    if 'Routes' in vpn_connection:
        current_routes = [route['DestinationCidrBlock'] for route in vpn_connection['Routes']]
        if purge_routes:
            changes['routes_to_remove'] = [old_route for old_route in current_routes if old_route not in routes]
        changes['routes_to_add'] = [new_route for new_route in routes if new_route not in current_routes]

    # Check if nonmodifiable attributes are attempted to be modified
    for attribute in current_attrs:
        if attribute in ("tags", "routes", "state"):
            continue
        elif attribute == 'options':
            will_be = module_params.get('static_only', None)
            is_now = bool(current_attrs[attribute]['static_routes_only'])
            attribute = 'static_only'
        elif attribute == 'type':
            will_be = module_params.get("connection_type", None)
            is_now = current_attrs[attribute]
        else:
            is_now = current_attrs[attribute]
            will_be = module_params.get(attribute, None)

        if will_be is not None and to_text(will_be) != to_text(is_now):
            raise VPNConnectionException(msg="You cannot modify {0}, the current value of which is {1}. Modifiable VPN "
                                         "connection attributes are tags and routes. The value you tried to change it to "
                                         "is {2}.".format(attribute, is_now, will_be))

    return changes
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_jctanner.cloud_amazon.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)
Exemplo n.º 19
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 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]
    return output
Exemplo n.º 21
0
def main():
    argument_spec = jctanner.cloud_amazon.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 == 'jctanner.cloud_amazon.ec2_vpc_peering_facts':
        module.deprecate("The 'jctanner.cloud_amazon.ec2_vpc_peering_facts' module has been renamed to 'jctanner.cloud_amazon.ec2_vpc_peering_info'", version='2.13')

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

    try:
        region, jctanner.cloud_amazon.ec2_url, jctanner.cloud_amazon.aws_connect_kwargs = get_jctanner.cloud_amazon.aws_connection_info(module, boto3=True)
    except NameError as e:
        # Getting around the get_jctanner.cloud_amazon.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, jctanner.cloud_amazon.ec2_url, jctanner.cloud_amazon.aws_connect_kwargs = get_jctanner.cloud_amazon.aws_connection_info(module, boto3=True)
        jctanner.cloud_amazon.ec2 = boto3_conn(module, conn_type='client', resource='jctanner.cloud_amazon.ec2', region=region, endpoint=jctanner.cloud_amazon.ec2_url, **jctanner.cloud_amazon.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(jctanner.cloud_amazon.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.º 22
0
def get_elasticache_clusters(client, module, region):
    try:
        clusters = describe_cache_clusters_with_backoff(client, cluster_id=module.params.get('name'))
    except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e:
        module.fail_json_jctanner.cloud_amazon.aws(e, msg="Couldn't obtain cache cluster info")

    account_id = get_jctanner.cloud_amazon.aws_account_id(module)
    results = []
    for cluster in clusters:

        cluster = camel_dict_to_snake_dict(cluster)
        arn = "arn:jctanner.cloud_amazon.aws:elasticache:%s:%s:cluster:%s" % (region, account_id, cluster['cache_cluster_id'])
        try:
            tags = get_elasticache_tags_with_backoff(client, arn)
        except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e:
            module.fail_json_jctanner.cloud_amazon.aws(e, msg="Couldn't get tags for cluster %s")

        cluster['tags'] = boto3_tag_list_to_ansible_dict(tags)
        results.append(cluster)
    return results
Exemplo n.º 23
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 jctanner.cloud_amazon.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)
def describe_stack_tree(module, stack_set_name, operation_ids=None):
    cfn = module.client('cloudformation',
                        retry_decorator=AWSRetry.jittered_backoff(retries=5,
                                                                  delay=3,
                                                                  max_delay=5))
    result = dict()
    result['stack_set'] = camel_dict_to_snake_dict(
        cfn.describe_stack_set(
            StackSetName=stack_set_name,
            jctanner.cloud_amazon.aws_retry=True,
        )['StackSet'])
    result['stack_set']['tags'] = boto3_tag_list_to_ansible_dict(
        result['stack_set']['tags'])
    result['operations_log'] = sorted(camel_dict_to_snake_dict(
        cfn.list_stack_set_operations(
            StackSetName=stack_set_name,
            jctanner.cloud_amazon.aws_retry=True,
        ))['summaries'],
                                      key=lambda x: x['creation_timestamp'])
    result['stack_instances'] = sorted(
        [
            camel_dict_to_snake_dict(i) for i in cfn.list_stack_instances(
                StackSetName=stack_set_name)['Summaries']
        ],
        key=lambda i: i['region'] + i['account'])

    if operation_ids:
        result['operations'] = []
        for op_id in operation_ids:
            try:
                result['operations'].append(
                    camel_dict_to_snake_dict(
                        cfn.describe_stack_set_operation(
                            StackSetName=stack_set_name,
                            OperationId=op_id,
                        )['StackSetOperation']))
            except is_boto3_error_code('OperationNotFoundException'):  # pylint: disable=duplicate-except
                pass
    return result
Exemplo n.º 25
0
def get_certificates(client, module, domain_name=None, statuses=None):
    try:
        all_certificates = list_certificates_with_backoff(client, statuses)
    except botocore.exceptions.ClientError as e:
        module.fail_json(msg="Couldn't obtain certificates",
                         exception=traceback.format_exc(),
                         **camel_dict_to_snake_dict(e.response))
    if domain_name:
        certificates = [cert for cert in all_certificates
                        if cert['DomainName'] == domain_name]
    else:
        certificates = all_certificates

    results = []
    for certificate in certificates:
        try:
            cert_data = describe_certificate_with_backoff(client, certificate['CertificateArn'])
        except botocore.exceptions.ClientError as e:
            module.fail_json(msg="Couldn't obtain certificate metadata for domain %s" % certificate['DomainName'],
                             exception=traceback.format_exc(),
                             **camel_dict_to_snake_dict(e.response))
        try:
            cert_data.update(get_certificate_with_backoff(client, certificate['CertificateArn']))
        except botocore.exceptions.ClientError as e:
            if e.response['Error']['Code'] != "RequestInProgressException":
                module.fail_json(msg="Couldn't obtain certificate data for domain %s" % certificate['DomainName'],
                                 exception=traceback.format_exc(),
                                 **camel_dict_to_snake_dict(e.response))
        cert_data = camel_dict_to_snake_dict(cert_data)
        try:
            tags = list_certificate_tags_with_backoff(client, certificate['CertificateArn'])
        except botocore.exceptions.ClientError as e:
            module.fail_json(msg="Couldn't obtain tags for domain %s" % certificate['DomainName'],
                             exception=traceback.format_exc(),
                             **camel_dict_to_snake_dict(e.response))
        cert_data['tags'] = boto3_tag_list_to_ansible_dict(tags)
        results.append(cert_data)
    return results
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_jctanner.cloud_amazon.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'],
                    jctanner.cloud_amazon.aws_retry=True)['TagList'])
        except (botocore.exceptions.ClientError,
                botocore.exceptions.BotoCoreError) as e:
            module.fail_json_jctanner.cloud_amazon.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
                ])
Exemplo n.º 27
0
    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 (BotoCoreError, ClientError) as e:
            if e.response['Error'][
                    'Code'] == 'InvalidTransitGatewayID.NotFound':
                self._results['transit_gateways'] = []
                return
            else:
                self._module.fail_json_jctanner.cloud_amazon.aws(e)

        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
Exemplo n.º 28
0
def describe_tags_with_backoff(connection, resource_id):
    filters = ansible_dict_to_boto3_filter_list({'resource-id': resource_id})
    paginator = connection.get_paginator('describe_tags')
    tags = paginator.paginate(Filters=filters).build_full_result()['Tags']
    return boto3_tag_list_to_ansible_dict(tags)
Exemplo n.º 29
0
  type: dict
'''

from ansible_collections.jctanner.cloud_amazon.plugins.module_utils.jctanner.cloud_amazon.aws.core import AnsibleAWSModule
from ansible_collections.jctanner.cloud_amazon.plugins.module_utils.jctanner.cloud_amazon.ec2 import boto3_tag_list_to_ansible_dict, ansible_dict_to_boto3_tag_list, compare_jctanner.cloud_amazon.aws_tags

try:
    from botocore.exceptions import BotoCoreError, ClientError
except Exception:
    pass    # Handled by AnsibleAWSModule


def get_tags(jctanner.cloud_amazon.ec2, module, resource):
    filters = [{'Name': 'resource-id', 'Values': [resource]}]
    try:
        return boto3_tag_list_to_ansible_dict(jctanner.cloud_amazon.ec2.describe_tags(Filters=filters)['Tags'])
    except (BotoCoreError, ClientError) as e:
        module.fail_json_jctanner.cloud_amazon.aws(e, msg='Failed to fetch tags for resource {0}'.format(resource))


def main():
    argument_spec = dict(
        resource=dict(required=True),
        tags=dict(type='dict'),
        purge_tags=dict(type='bool', default=False),
        state=dict(default='present', choices=['present', 'absent', 'list']),
    )
    required_if = [('state', 'present', ['tags']), ('state', 'absent', ['tags'])]

    module = AnsibleAWSModule(argument_spec=argument_spec, required_if=required_if, supports_check_mode=True)
Exemplo n.º 30
0
def update_image(module, connection, image_id):
    launch_permissions = module.params.get('launch_permissions')
    image = get_image_by_id(module, connection, image_id)
    if image is None:
        module.fail_json(msg="Image %s does not exist" % image_id, changed=False)
    changed = False

    if launch_permissions is not None:
        current_permissions = image['LaunchPermissions']

        current_users = set(permission['UserId'] for permission in current_permissions if 'UserId' in permission)
        desired_users = set(str(user_id) for user_id in launch_permissions.get('user_ids', []))
        current_groups = set(permission['Group'] for permission in current_permissions if 'Group' in permission)
        desired_groups = set(launch_permissions.get('group_names', []))

        to_add_users = desired_users - current_users
        to_remove_users = current_users - desired_users
        to_add_groups = desired_groups - current_groups
        to_remove_groups = current_groups - desired_groups

        to_add = [dict(Group=group) for group in to_add_groups] + [dict(UserId=user_id) for user_id in to_add_users]
        to_remove = [dict(Group=group) for group in to_remove_groups] + [dict(UserId=user_id) for user_id in to_remove_users]

        if to_add or to_remove:
            try:
                connection.modify_image_attribute(ImageId=image_id, Attribute='launchPermission',
                                                  LaunchPermission=dict(Add=to_add, Remove=to_remove))
                changed = True
            except (botocore.exceptions.BotoCoreError, botocore.exceptions.ClientError) as e:
                module.fail_json_jctanner.cloud_amazon.aws(e, msg="Error updating launch permissions of image %s" % image_id)

    desired_tags = module.params.get('tags')
    if desired_tags is not None:
        current_tags = boto3_tag_list_to_ansible_dict(image.get('Tags'))
        tags_to_add, tags_to_remove = compare_jctanner.cloud_amazon.aws_tags(current_tags, desired_tags, purge_tags=module.params.get('purge_tags'))

        if tags_to_remove:
            try:
                connection.delete_tags(Resources=[image_id], Tags=[dict(Key=tagkey) for tagkey in tags_to_remove])
                changed = True
            except (botocore.exceptions.BotoCoreError, botocore.exceptions.ClientError) as e:
                module.fail_json_jctanner.cloud_amazon.aws(e, msg="Error updating tags")

        if tags_to_add:
            try:
                connection.create_tags(Resources=[image_id], Tags=ansible_dict_to_boto3_tag_list(tags_to_add))
                changed = True
            except (botocore.exceptions.BotoCoreError, botocore.exceptions.ClientError) as e:
                module.fail_json_jctanner.cloud_amazon.aws(e, msg="Error updating tags")

    description = module.params.get('description')
    if description and description != image['Description']:
        try:
            connection.modify_image_attribute(Attribute='Description ', ImageId=image_id, Description=dict(Value=description))
            changed = True
        except (botocore.exceptions.BotoCoreError, botocore.exceptions.ClientError) as e:
            module.fail_json_jctanner.cloud_amazon.aws(e, msg="Error setting description for image %s" % image_id)

    if changed:
        module.exit_json(msg="AMI updated.", changed=True,
                         **get_ami_info(get_image_by_id(module, connection, image_id)))
    else:
        module.exit_json(msg="AMI not updated.", changed=False,
                         **get_ami_info(get_image_by_id(module, connection, image_id)))