Пример #1
0
def config_details(client, module):
    """
    Returns configuration details for one or all lambda functions.

    :param client: AWS API client reference (boto3)
    :param module: Ansible module reference
    :return dict:
    """

    lambda_info = dict()

    function_name = module.params.get('function_name')
    if function_name:
        try:
            lambda_info.update(client.get_function_configuration(aws_retry=True, FunctionName=function_name))
        except is_boto3_error_code('ResourceNotFoundException'):
            lambda_info.update(function={})
        except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e:  # pylint: disable=duplicate-except
            module.fail_json_aws(e, msg="Trying to get {0} configuration".format(function_name))
    else:
        try:
            lambda_info.update(function_list=_paginate(client, 'list_functions')['Functions'])
        except is_boto3_error_code('ResourceNotFoundException'):
            lambda_info.update(function_list=[])
        except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e:  # pylint: disable=duplicate-except
            module.fail_json_aws(e, msg="Trying to get function list")

        functions = dict()
        for func in lambda_info.pop('function_list', []):
            func['tags'] = client.get_function(FunctionName=func['FunctionName']).get('Tags', {})
            functions[func['FunctionName']] = camel_dict_to_snake_dict(func)
        return functions

    return {function_name: camel_dict_to_snake_dict(lambda_info)}
Пример #2
0
def mapping_details(client, module):
    """
    Returns all lambda event source mappings.

    :param client: AWS API client reference (boto3)
    :param module: Ansible module reference
    :return dict:
    """

    lambda_info = dict()
    params = dict()
    function_name = module.params.get('function_name')

    if function_name:
        params['FunctionName'] = module.params.get('function_name')

    if module.params.get('event_source_arn'):
        params['EventSourceArn'] = module.params.get('event_source_arn')

    try:
        lambda_info.update(mappings=_paginate(client, 'list_event_source_mappings', **params)['EventSourceMappings'])
    except is_boto3_error_code('ResourceNotFoundException'):
        lambda_info.update(mappings=[])
    except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e:  # pylint: disable=duplicate-except
        module.fail_json_aws(e, msg="Trying to get source event mappings")

    if function_name:
        return {function_name: camel_dict_to_snake_dict(lambda_info)}

    return camel_dict_to_snake_dict(lambda_info)
def main():
    argument_spec = dict(
        name=dict(required=False),
        list_packages_for_domain=dict(required=False, type=bool),
        describe_elasticsearch_domain=dict(required=False, type=bool),
        describe_elasticsearch_domain_config=dict(required=False, type=bool),
    )

    module = AnsibleAWSModule(
        argument_spec=argument_spec,
        required_if=(
            ('list_packages_for_domain', True, ['name']),
            ('describe_elasticsearch_domain', True, ['name']),
            ('describe_elasticsearch_domain_config', True, ['name']),
        ),
        mutually_exclusive=[
            (
                'list_packages_for_domain',
                'describe_elasticsearch_domain',
                'describe_elasticsearch_domain_config',
            )
        ],
    )

    client = module.client('es', retry_decorator=AWSRetry.exponential_backoff())
    it, paginate = _es(client, module)

    if module.params['list_packages_for_domain']:
        module.exit_json(packages=aws_response_list_parser(paginate, it, 'DomainPackageDetailsList'))
    elif module.params['describe_elasticsearch_domain']:
        module.exit_json(domain_status=camel_dict_to_snake_dict(it['DomainStatus']))
    elif module.params['describe_elasticsearch_domain_config']:
        module.exit_json(domain_config=camel_dict_to_snake_dict(it['DomainConfig']))
    else:
        module.exit_json(domain_names=aws_response_list_parser(paginate, it, 'DomainNames'))
Пример #4
0
    def _make_api_request(self, endpoint, method, data=None):
        if data is not None:
            data = json.dumps(data)

        endpoint_url = self.url + "/v1/" + endpoint
        headers = {
            "Content-Type": "application/json",
            "X-Consul-Token": self.token
        }

        response, info = fetch_url(self.module,
                                   endpoint_url,
                                   data=data,
                                   headers=headers,
                                   method=method)
        if response is None:
            self.module.fail_json(**info)

        status_code = info["status"]
        if status_code >= 400:
            self.module.fail_json(
                msg="API request failed",
                endpoint=endpoint_url,
                method=method,
                status=status_code,
                response=info["body"],
            )

        body = json.loads(response.read())
        if type(body) is bool:
            return body
        elif type(body) is list:
            return [camel_dict_to_snake_dict(e) for e in body]
        else:
            return camel_dict_to_snake_dict(body)
Пример #5
0
def create_instance(module, client, instance_name):

    inst = find_instance_info(module, client, instance_name)
    if inst:
        module.exit_json(changed=False,
                         instance=camel_dict_to_snake_dict(inst))
    else:
        create_params = {
            'instanceNames': [instance_name],
            'availabilityZone': module.params.get('zone'),
            'blueprintId': module.params.get('blueprint_id'),
            'bundleId': module.params.get('bundle_id'),
            'userData': module.params.get('user_data')
        }

        key_pair_name = module.params.get('key_pair_name')
        if key_pair_name:
            create_params['keyPairName'] = key_pair_name

        try:
            client.create_instances(**create_params)
        except botocore.exceptions.ClientError as e:
            module.fail_json_aws(e)

        wait = module.params.get('wait')
        if wait:
            desired_states = ['running']
            wait_for_instance_state(module, client, instance_name,
                                    desired_states)
        inst = find_instance_info(module,
                                  client,
                                  instance_name,
                                  fail_if_not_found=True)

        module.exit_json(changed=True, instance=camel_dict_to_snake_dict(inst))
Пример #6
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
Пример #7
0
def setup_creation(client, module):
    endpoint_id = module.params.get('vpc_endpoint_id')
    route_table_ids = module.params.get('route_table_ids')
    service_name = module.params.get('service')
    vpc_id = module.params.get('vpc_id')
    changed = False

    if not endpoint_id:
        # Try to use the module parameters to match any existing endpoints
        all_endpoints = get_endpoints(client, module, endpoint_id)
        if len(all_endpoints['VpcEndpoints']) > 0:
            for endpoint in all_endpoints['VpcEndpoints']:
                if match_endpoints(route_table_ids, service_name, vpc_id,
                                   endpoint):
                    endpoint_id = endpoint['VpcEndpointId']
                    break

    if endpoint_id:
        # If we have an endpoint now, just ensure tags and exit
        if module.params.get('tags'):
            changed = ensure_tags(client, module, endpoint_id)
        normalized_result = get_endpoints(
            client, module, endpoint_id=endpoint_id)['VpcEndpoints'][0]
        return changed, camel_dict_to_snake_dict(normalized_result,
                                                 ignore_list=['Tags'])

    changed, result = create_vpc_endpoint(client, module)

    return changed, camel_dict_to_snake_dict(result, ignore_list=['Tags'])
Пример #8
0
def delete_template(module):
    ec2 = module.client('ec2', retry_decorator=AWSRetry.jittered_backoff())
    template, template_versions = existing_templates(module)
    deleted_versions = []
    if template or template_versions:
        non_default_versions = [to_text(t['VersionNumber']) for t in template_versions if not t['DefaultVersion']]
        if non_default_versions:
            try:
                v_resp = ec2.delete_launch_template_versions(
                    LaunchTemplateId=template['LaunchTemplateId'],
                    Versions=non_default_versions,
                )
                if v_resp['UnsuccessfullyDeletedLaunchTemplateVersions']:
                    module.warn('Failed to delete template versions {0} on launch template {1}'.format(
                        v_resp['UnsuccessfullyDeletedLaunchTemplateVersions'],
                        template['LaunchTemplateId'],
                    ))
                deleted_versions = [camel_dict_to_snake_dict(v) for v in v_resp['SuccessfullyDeletedLaunchTemplateVersions']]
            except (ClientError, BotoCoreError) as e:
                module.fail_json_aws(e, msg="Could not delete existing versions of the launch template {0}".format(template['LaunchTemplateId']))
        try:
            resp = ec2.delete_launch_template(
                LaunchTemplateId=template['LaunchTemplateId'],
            )
        except (ClientError, BotoCoreError) as e:
            module.fail_json_aws(e, msg="Could not delete launch template {0}".format(template['LaunchTemplateId']))
        return {
            'deleted_versions': deleted_versions,
            'deleted_template': camel_dict_to_snake_dict(resp['LaunchTemplate']),
            'changed': True,
        }
    else:
        return {'changed': False}
Пример #9
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, 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'], [])

    if result['Origin'] == 'AWS_KMS':
        result['enable_key_rotation'] = get_enable_key_rotation_with_backoff(connection, key_id)
    else:
        result['enable_key_rotation'] = None

    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, 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 = 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
Пример #10
0
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
Пример #11
0
def get_subnet_group(name):
    try:
        groups = client.describe_cluster_subnet_groups(
            aws_retry=True,
            ClusterSubnetGroupName=name,
        )['ClusterSubnetGroups']
    except is_boto3_error_code('ClusterSubnetGroupNotFoundFault'):
        return None
    except (botocore.exceptions.ClientError,
            botocore.exceptions.BotoCoreError) as e:  # pylint: disable=duplicate-except
        module.fail_json_aws(e, msg="Failed to describe subnet group")

    if not groups:
        return None

    if len(groups) > 1:
        module.fail_aws(
            msg="Found multiple matches for subnet group",
            cluster_subnet_groups=camel_dict_to_snake_dict(groups),
        )

    # No support for managing tags yet, but make sure that we don't need to
    # change the return value structure after it's been available in a release.
    tags = boto3_tag_list_to_ansible_dict(groups[0]['Tags'])

    subnet_group = camel_dict_to_snake_dict(groups[0])

    subnet_group['tags'] = tags
    subnet_group['name'] = subnet_group['cluster_subnet_group_name']

    subnet_ids = list(s['subnet_identifier'] for s in subnet_group['subnets'])
    subnet_group['subnet_ids'] = subnet_ids

    return subnet_group
Пример #12
0
def get_subnet_group(name):
    try:
        groups = client.describe_cache_subnet_groups(
            aws_retry=True,
            CacheSubnetGroupName=name,
        )['CacheSubnetGroups']
    except is_boto3_error_code('CacheSubnetGroupNotFoundFault'):
        return None
    except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e:  # pylint: disable=duplicate-except
        module.fail_json_aws(e, msg="Failed to describe subnet group")

    if not groups:
        return None

    if len(groups) > 1:
        module.fail_aws(
            msg="Found multiple matches for subnet group",
            cache_subnet_groups=camel_dict_to_snake_dict(groups),
        )

    subnet_group = camel_dict_to_snake_dict(groups[0])

    subnet_group['name'] = subnet_group['cache_subnet_group_name']
    subnet_group['description'] = subnet_group['cache_subnet_group_description']

    subnet_ids = list(s['subnet_identifier'] for s in subnet_group['subnets'])
    subnet_group['subnet_ids'] = subnet_ids

    return subnet_group
 def setup_method(self):
     # Basic information that ClientError needs to spawn off an error
     self.EXAMPLE_EXCEPTION_DATA = {
         "Error": {
             "Code": "InvalidParameterValue",
             "Message": "The filter 'exampleFilter' is invalid"
         },
         "ResponseMetadata": {
             "RequestId": "01234567-89ab-cdef-0123-456789abcdef",
             "HTTPStatusCode": 400,
             "HTTPHeaders": {
                 "transfer-encoding": "chunked",
                 "date": "Fri, 13 Nov 2020 00:00:00 GMT",
                 "connection": "close",
                 "server": "AmazonEC2"
             },
             "RetryAttempts": 0
         }
     }
     self.CAMEL_RESPONSE = camel_dict_to_snake_dict(
         self.EXAMPLE_EXCEPTION_DATA.get("ResponseMetadata"))
     self.CAMEL_ERROR = camel_dict_to_snake_dict(
         self.EXAMPLE_EXCEPTION_DATA.get("Error"))
     # ClientError(EXAMPLE_EXCEPTION_DATA, "testCall") will generate this
     self.EXAMPLE_MSG = "An error occurred (InvalidParameterValue) when calling the testCall operation: The filter 'exampleFilter' is invalid"
     self.DEFAULT_CORE_MSG = "An unspecified error occurred"
     self.FAIL_MSG = "I Failed!"
Пример #14
0
def main():
    argument_spec = dict(
        api_id=dict(type='str', required=False),
        state=dict(type='str', default='present', choices=['present', 'absent']),
        swagger_file=dict(type='path', default=None, aliases=['src', 'api_file']),
        swagger_dict=dict(type='json', default=None),
        swagger_text=dict(type='str', default=None),
        stage=dict(type='str', default=None),
        deploy_desc=dict(type='str', default="Automatic deployment by Ansible."),
        cache_enabled=dict(type='bool', default=False),
        cache_size=dict(type='str', default='0.5', choices=['0.5', '1.6', '6.1', '13.5', '28.4', '58.2', '118', '237']),
        stage_variables=dict(type='dict', default={}),
        stage_canary_settings=dict(type='dict', default={}),
        tracing_enabled=dict(type='bool', default=False),
        endpoint_type=dict(type='str', default='EDGE', choices=['EDGE', 'REGIONAL', 'PRIVATE'])
    )

    mutually_exclusive = [['swagger_file', 'swagger_dict', 'swagger_text']]  # noqa: F841

    module = AnsibleAWSModule(
        argument_spec=argument_spec,
        supports_check_mode=False,
        mutually_exclusive=mutually_exclusive,
    )

    api_id = module.params.get('api_id')
    state = module.params.get('state')   # noqa: F841
    swagger_file = module.params.get('swagger_file')
    swagger_dict = module.params.get('swagger_dict')
    swagger_text = module.params.get('swagger_text')
    endpoint_type = module.params.get('endpoint_type')

    client = module.client('apigateway')

    changed = True   # for now it will stay that way until we can sometimes avoid change
    conf_res = None
    dep_res = None
    del_res = None

    if state == "present":
        if api_id is None:
            api_id = create_empty_api(module, client, endpoint_type)
        api_data = get_api_definitions(module, swagger_file=swagger_file,
                                       swagger_dict=swagger_dict, swagger_text=swagger_text)
        conf_res, dep_res = ensure_api_in_correct_state(module, client, api_id, api_data)
    if state == "absent":
        del_res = delete_rest_api(module, client, api_id)

    exit_args = {"changed": changed, "api_id": api_id}

    if conf_res is not None:
        exit_args['configure_response'] = camel_dict_to_snake_dict(conf_res)
    if dep_res is not None:
        exit_args['deploy_response'] = camel_dict_to_snake_dict(dep_res)
    if del_res is not None:
        exit_args['delete_response'] = camel_dict_to_snake_dict(del_res)

    module.exit_json(**exit_args)
Пример #15
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)
Пример #16
0
def main():
    argument_spec = dict(
        state=dict(required=True, choices=['present', 'absent']),
        name=dict(),
        link_aggregation_group_id=dict(),
        num_connections=dict(type='int'),
        min_links=dict(type='int'),
        location=dict(),
        bandwidth=dict(),
        connection_id=dict(),
        delete_with_disassociation=dict(type='bool', default=False),
        force_delete=dict(type='bool', default=False),
        wait=dict(type='bool', default=False),
        wait_timeout=dict(type='int', default=120),
    )

    module = AnsibleAWSModule(
        argument_spec=argument_spec,
        required_one_of=[('link_aggregation_group_id', 'name')],
        required_if=[('state', 'present', ('location', 'bandwidth'))],
    )

    try:
        connection = module.client('directconnect')
    except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e:
        module.fail_json_aws(e, msg='Failed to connect to AWS')

    state = module.params.get('state')
    response = {}
    try:
        if state == 'present':
            changed, lag_id = ensure_present(connection,
                                             num_connections=module.params.get("num_connections"),
                                             lag_id=module.params.get("link_aggregation_group_id"),
                                             lag_name=module.params.get("name"),
                                             location=module.params.get("location"),
                                             bandwidth=module.params.get("bandwidth"),
                                             connection_id=module.params.get("connection_id"),
                                             min_links=module.params.get("min_links"),
                                             wait=module.params.get("wait"),
                                             wait_timeout=module.params.get("wait_timeout"))
            response = lag_status(connection, lag_id)
        elif state == "absent":
            changed = ensure_absent(connection,
                                    lag_id=module.params.get("link_aggregation_group_id"),
                                    lag_name=module.params.get("name"),
                                    force_delete=module.params.get("force_delete"),
                                    delete_with_disassociation=module.params.get("delete_with_disassociation"),
                                    wait=module.params.get('wait'),
                                    wait_timeout=module.params.get('wait_timeout'))
    except DirectConnectError as e:
        if e.last_traceback:
            module.fail_json(msg=e.msg, exception=e.last_traceback, **camel_dict_to_snake_dict(e.exception))
        else:
            module.fail_json(msg=e.msg)

    module.exit_json(changed=changed, **camel_dict_to_snake_dict(response))
Пример #17
0
def create_or_update_role():

    params = generate_create_params()
    role_name = params['RoleName']
    create_instance_profile = module.params.get('create_instance_profile')
    purge_policies = module.params.get('purge_policies')
    if purge_policies is None:
        purge_policies = True
    managed_policies = module.params.get('managed_policies')
    if managed_policies:
        # Attempt to list the policies early so we don't leave things behind if we can't find them.
        managed_policies = convert_friendly_names_to_arns(managed_policies)

    changed = False

    # Get role
    role = get_role(role_name)

    # If role is None, create it
    if role is None:
        role = create_basic_role(params)

        if not module.check_mode and module.params.get('wait'):
            wait_iam_exists()

        changed = True
    else:
        changed |= update_role_tags(params, role)
        changed |= update_role_assumed_policy(params, role)
        changed |= update_role_description(params, role)
        changed |= update_role_max_session_duration(params, role)
        changed |= update_role_permissions_boundary(params, role)

        if not module.check_mode and module.params.get('wait'):
            wait_iam_exists()

    if create_instance_profile:
        changed |= create_instance_profiles(params, role)

        if not module.check_mode and module.params.get('wait'):
            wait_iam_exists()

    changed |= update_managed_policies(params, role, managed_policies,
                                       purge_policies)
    wait_iam_exists()

    # Get the role again
    if not role.get('MadeInCheckMode', False):
        role = get_role(params['RoleName'])
        role['AttachedPolicies'] = get_attached_policy_list(params['RoleName'])
        role['tags'] = get_role_tags()

    module.exit_json(changed=changed,
                     iam_role=camel_dict_to_snake_dict(role,
                                                       ignore_list=['tags']),
                     **camel_dict_to_snake_dict(role, ignore_list=['tags']))
Пример #18
0
def create_vpc_endpoint(client, module):
    params = dict()
    changed = False
    token_provided = False
    params['VpcId'] = module.params.get('vpc_id')
    params['VpcEndpointType'] = module.params.get('vpc_endpoint_type')
    params['ServiceName'] = module.params.get('service')
    params['DryRun'] = module.check_mode

    if module.params.get('route_table_ids'):
        params['RouteTableIds'] = module.params.get('route_table_ids')

    if module.params.get('client_token'):
        token_provided = True
        request_time = datetime.datetime.utcnow()
        params['ClientToken'] = module.params.get('client_token')

    policy = None
    if module.params.get('policy'):
        try:
            policy = json.loads(module.params.get('policy'))
        except ValueError as e:
            module.fail_json(msg=str(e), exception=traceback.format_exc(),
                             **camel_dict_to_snake_dict(e.response))

    elif module.params.get('policy_file'):
        try:
            with open(module.params.get('policy_file'), 'r') as json_data:
                policy = json.load(json_data)
        except Exception as e:
            module.fail_json(msg=str(e), exception=traceback.format_exc(),
                             **camel_dict_to_snake_dict(e.response))

    if policy:
        params['PolicyDocument'] = json.dumps(policy)

    try:
        changed = True
        result = camel_dict_to_snake_dict(client.create_vpc_endpoint(**params)['VpcEndpoint'])
        if token_provided and (request_time > result['creation_timestamp'].replace(tzinfo=None)):
            changed = False
        elif module.params.get('wait') and not module.check_mode:
            status_achieved, result = wait_for_status(client, module, result['vpc_endpoint_id'], 'available')
            if not status_achieved:
                module.fail_json(msg='Error waiting for vpc endpoint to become available - please check the AWS console')
    except is_boto3_error_code('DryRunOperation'):
        changed = True
        result = 'Would have created VPC Endpoint if not in check mode'
    except is_boto3_error_code('IdempotentParameterMismatch'):  # pylint: disable=duplicate-except
        module.fail_json(msg="IdempotentParameterMismatch - updates of endpoints are not allowed by the API")
    except is_boto3_error_code('RouteAlreadyExists'):  # pylint: disable=duplicate-except
        module.fail_json(msg="RouteAlreadyExists for one of the route tables - update is not allowed by the API")
    except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e:  # pylint: disable=duplicate-except
        module.fail_json_aws(e, msg="Failed to create VPC.")

    return changed, result
Пример #19
0
def list_target_groups(connection, module):

    load_balancer_arn = module.params.get("load_balancer_arn")
    target_group_arns = module.params.get("target_group_arns")
    names = module.params.get("names")
    collect_targets_health = module.params.get("collect_targets_health")

    try:
        target_group_paginator = connection.get_paginator(
            'describe_target_groups')
        if not load_balancer_arn and not target_group_arns and not names:
            target_groups = target_group_paginator.paginate(
            ).build_full_result()
        if load_balancer_arn:
            target_groups = target_group_paginator.paginate(
                LoadBalancerArn=load_balancer_arn).build_full_result()
        if target_group_arns:
            target_groups = target_group_paginator.paginate(
                TargetGroupArns=target_group_arns).build_full_result()
        if names:
            target_groups = target_group_paginator.paginate(
                Names=names).build_full_result()
    except is_boto3_error_code('TargetGroupNotFound'):
        module.exit_json(target_groups=[])
    except ClientError as e:  # pylint: disable=duplicate-except
        module.fail_json_aws(e, msg="Failed to list target groups")
    except NoCredentialsError as e:
        module.fail_json(msg="AWS authentication problem. " + to_native(e),
                         exception=traceback.format_exc())

    # Get the attributes and tags for each target group
    for target_group in target_groups['TargetGroups']:
        target_group.update(
            get_target_group_attributes(connection, module,
                                        target_group['TargetGroupArn']))

    # Turn the boto3 result in to ansible_friendly_snaked_names
    snaked_target_groups = [
        camel_dict_to_snake_dict(target_group)
        for target_group in target_groups['TargetGroups']
    ]

    # Get tags for each target group
    for snaked_target_group in snaked_target_groups:
        snaked_target_group['tags'] = get_target_group_tags(
            connection, module, snaked_target_group['target_group_arn'])
        if collect_targets_health:
            snaked_target_group['targets_health_description'] = [
                camel_dict_to_snake_dict(target)
                for target in get_target_group_targets_health(
                    connection, module,
                    snaked_target_group['target_group_arn'])
            ]

    module.exit_json(target_groups=snaked_target_groups)
Пример #20
0
    def convert_camel_to_snake(self, data):
        """
        Converts a dictionary or list to snake case from camel case
        :type data: dict or list
        :return: Converted data structure, if list or dict
        """

        if isinstance(data, dict):
            return camel_dict_to_snake_dict(data, ignore_list=('tags', 'tag'))
        elif isinstance(data, list):
            return [camel_dict_to_snake_dict(item, ignore_list=('tags', 'tag')) for item in data]
        else:
            return data
Пример #21
0
def list_ec2_snapshots(connection, module):

    snapshot_ids = module.params.get("snapshot_ids")
    owner_ids = [str(owner_id) for owner_id in module.params.get("owner_ids")]
    restorable_by_user_ids = [
        str(user_id) for user_id in module.params.get("restorable_by_user_ids")
    ]
    filters = ansible_dict_to_boto3_filter_list(module.params.get("filters"))
    max_results = module.params.get('max_results')
    next_token = module.params.get('next_token_id')
    optional_param = {}
    if max_results:
        optional_param['MaxResults'] = max_results
    if next_token:
        optional_param['NextToken'] = next_token

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

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

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

    result['snapshots'] = snaked_snapshots

    if snapshots.get('NextToken'):
        result.update(
            camel_dict_to_snake_dict(
                {'NextTokenId': snapshots.get('NextToken')}))

    module.exit_json(**result)
def main():
    argument_spec = dict(state=dict(required=True,
                                    choices=['present', 'absent']),
                         name=dict(),
                         location=dict(),
                         bandwidth=dict(choices=['1Gbps', '10Gbps']),
                         link_aggregation_group=dict(),
                         connection_id=dict(),
                         forced_update=dict(type='bool', default=False))

    module = AnsibleAWSModule(argument_spec=argument_spec,
                              required_one_of=[('connection_id', 'name')],
                              required_if=[('state', 'present',
                                            ('location', 'bandwidth'))])

    connection = module.client('directconnect')

    state = module.params.get('state')
    try:
        connection_id = connection_exists(
            connection,
            connection_id=module.params.get('connection_id'),
            connection_name=module.params.get('name'))
        if not connection_id and module.params.get('connection_id'):
            module.fail_json(
                msg="The Direct Connect connection {0} does not exist.".format(
                    module.params.get('connection_id')))

        if state == 'present':
            changed, connection_id = ensure_present(
                connection,
                connection_id=connection_id,
                connection_name=module.params.get('name'),
                location=module.params.get('location'),
                bandwidth=module.params.get('bandwidth'),
                lag_id=module.params.get('link_aggregation_group'),
                forced_update=module.params.get('forced_update'))
            response = connection_status(connection, connection_id)
        elif state == 'absent':
            changed = ensure_absent(connection, connection_id)
            response = {}
    except DirectConnectError as e:
        if e.last_traceback:
            module.fail_json(msg=e.msg,
                             exception=e.last_traceback,
                             **camel_dict_to_snake_dict(e.exception.response))
        else:
            module.fail_json(msg=e.msg)

    module.exit_json(changed=changed, **camel_dict_to_snake_dict(response))
Пример #23
0
def get_result(client, dp_id):
    """ Get the current state of the data pipeline and reformat it to snake_case for exit_json

    :param object client: boto3 datapipeline client
    :param string dp_id: pipeline id
    :returns: reformatted dict of pipeline description

     """
    # pipeline_description returns a pipelineDescriptionList of length 1
    # dp is a dict with keys "description" (str), "fields" (list), "name" (str), "pipelineId" (str), "tags" (dict)
    dp = pipeline_description(client, dp_id)['pipelineDescriptionList'][0]

    # Get uniqueId and pipelineState in fields to add to the exit_json result
    dp["unique_id"] = pipeline_field(client, dp_id, field="uniqueId")
    dp["pipeline_state"] = pipeline_field(client,
                                          dp_id,
                                          field="@pipelineState")

    # Remove fields; can't make a list snake_case and most of the data is redundant
    del dp["fields"]

    # Note: tags is already formatted fine so we don't need to do anything with it

    # Reformat data pipeline and add reformatted fields back
    dp = camel_dict_to_snake_dict(dp)
    return dp
Пример #24
0
def list_eni(connection, module):

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

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

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

    module.exit_json(network_interfaces=camel_network_interfaces)
Пример #25
0
def delete_policy(existing_policy):
    # Check for existing policy
    if existing_policy:
        if module.check_mode:
            module.exit_json(changed=True)

        # Detach policy
        detach_all_entities(existing_policy)
        # Delete Versions
        try:
            versions = client.list_policy_versions(PolicyArn=existing_policy['Arn'])['Versions']
        except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e:
            module.fail_json_aws(e, msg="Couldn't list policy versions")
        for v in versions:
            if not v['IsDefaultVersion']:
                try:
                    client.delete_policy_version(PolicyArn=existing_policy['Arn'], VersionId=v['VersionId'])
                except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e:
                    module.fail_json_aws(
                        e, msg="Couldn't delete policy version {0}".format(v['VersionId']))
        # Delete policy
        try:
            client.delete_policy(PolicyArn=existing_policy['Arn'])
        except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e:
            module.fail_json_aws(e, msg="Couldn't delete policy {0}".format(existing_policy['PolicyName']))

        # This is the one case where we will return the old policy
        module.exit_json(changed=True, policy=camel_dict_to_snake_dict(existing_policy))
    else:
        module.exit_json(changed=False, policy=None)
Пример #26
0
def list_eni(connection, module):

    params = {}
    # Options are mutually exclusive
    if module.params.get("eni_id"):
        params['NetworkInterfaceIds'] = [module.params.get("eni_id")]
    elif module.params.get("filters"):
        params['Filters'] = ansible_dict_to_boto3_filter_list(
            module.params.get("filters"))
    else:
        params['Filters'] = []

    try:
        network_interfaces_result = connection.describe_network_interfaces(
            aws_retry=True, **params)['NetworkInterfaces']
    except is_boto3_error_code('InvalidNetworkInterfaceID.NotFound'):
        module.exit_json(network_interfaces=[])
    except (ClientError, NoCredentialsError) as e:
        module.fail_json_aws(e)

    # Modify boto3 tags list to be ansible friendly dict and then camel_case
    camel_network_interfaces = []
    for network_interface in network_interfaces_result:
        network_interface['TagSet'] = boto3_tag_list_to_ansible_dict(
            network_interface['TagSet'])
        network_interface['Tags'] = network_interface['TagSet']
        if 'Name' in network_interface['Tags']:
            network_interface['Name'] = network_interface['Tags']['Name']
        # 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,
                                     ignore_list=['Tags', 'TagSet']))

    module.exit_json(network_interfaces=camel_network_interfaces)
Пример #27
0
def list_ec2_instances(connection, module):

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

    try:
        reservations = _describe_instances(connection, InstanceIds=instance_ids, Filters=filters)
    except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e:
        module.fail_json_aws(e, msg="Failed to list ec2 instances")

    instances = []

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

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

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

    module.exit_json(instances=snaked_instances)
def main():
    argument_spec = dict()
    argument_spec.update(get_client_argument_spec())
    argument_spec.update(get_network_argument_spec())
    argument_spec.update(get_state_argument_spec())
    argument_spec.update(get_resolve_existing_argument_spec())
    argument_spec.update(get_wait_for_server_argument_spec())
    argument_spec.update(get_connection_argument_spec())
    argument_spec.update(get_cloud_connection_argument_spec())
    argument_spec.update(get_peering_connection_argument_spec())
    argument_spec.update(dict(service_key=dict(type='str', required=True)))
    mutually_exclusive = []
    mutually_exclusive += get_client_mutually_exclusive()
    required_one_of = []
    required_one_of += get_network_mutually_exclusive()
    required_one_of += get_connection_required_one_of()
    module = AnsibleModule(argument_spec=argument_spec,
                           mutually_exclusive=mutually_exclusive,
                           required_one_of=required_one_of)
    # Using partials to fill in the method params
    try:
        (changed, changed_connection, argument_connection,
         existing_connection) = connection_crud(
             module, partial(construct_connection, module))
        module.exit_json(changed=changed,
                         **camel_dict_to_snake_dict(changed_connection))
    except ClientHttpException as e:
        module.fail_json(msg=e.response.text, exception=format_exc())
Пример #29
0
def list_launch_configs(connection, module):

    launch_config_name = module.params.get("name")
    sort = module.params.get('sort')
    sort_order = module.params.get('sort_order')
    sort_start = module.params.get('sort_start')
    sort_end = module.params.get('sort_end')

    try:
        pg = connection.get_paginator('describe_launch_configurations')
        launch_configs = pg.paginate(LaunchConfigurationNames=launch_config_name).build_full_result()
    except ClientError as e:
        module.fail_json_aws(e, msg="Failed to list launch configs")

    snaked_launch_configs = []
    for launch_config in launch_configs['LaunchConfigurations']:
        snaked_launch_configs.append(camel_dict_to_snake_dict(launch_config))

    for launch_config in snaked_launch_configs:
        if 'CreatedTime' in launch_config:
            launch_config['CreatedTime'] = str(launch_config['CreatedTime'])

    if sort:
        snaked_launch_configs.sort(key=lambda e: e[sort], reverse=(sort_order == 'descending'))

    if sort and sort_start and sort_end:
        snaked_launch_configs = snaked_launch_configs[sort_start:sort_end]
    elif sort and sort_start:
        snaked_launch_configs = snaked_launch_configs[sort_start:]
    elif sort and sort_end:
        snaked_launch_configs = snaked_launch_configs[:sort_end]

    module.exit_json(launch_configurations=snaked_launch_configs)
Пример #30
0
def list_eni(connection, module):

    # Options are mutually exclusive
    if module.params.get("eni_id"):
        filters = {'network-interface-id': module.params.get("eni_id")}
    elif module.params.get("filters"):
        filters = module.params.get("filters")
    else:
        filters = {}
    filters = ansible_dict_to_boto3_filter_list(filters)

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

    # Modify boto3 tags list to be ansible friendly dict and then camel_case
    camel_network_interfaces = []
    for network_interface in network_interfaces_result:
        network_interface['TagSet'] = boto3_tag_list_to_ansible_dict(
            network_interface['TagSet'])
        network_interface['Tags'] = network_interface['TagSet']
        if 'Name' in network_interface['Tags']:
            network_interface['Name'] = network_interface['Tags']['Name']
        # 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,
                                     ignore_list=['Tags', 'TagSet']))

    module.exit_json(network_interfaces=camel_network_interfaces)