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)}
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'))
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)
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))
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
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'])
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}
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
def format_module_output(module): output = {} template, template_versions = existing_templates(module) template = camel_dict_to_snake_dict(template) template_versions = [camel_dict_to_snake_dict(v) for v in template_versions] for v in template_versions: for ts in (v['launch_template_data'].get('tag_specifications') or []): ts['tags'] = boto3_tag_list_to_ansible_dict(ts.pop('tags')) output.update(dict(template=template, versions=template_versions)) output['default_template'] = [ v for v in template_versions if v.get('default_version') ][0] output['latest_template'] = [ v for v in template_versions if ( v.get('version_number') and int(v['version_number']) == int(template['latest_version_number']) ) ][0] if "version_number" in output['default_template']: output['default_version'] = output['default_template']['version_number'] if "version_number" in output['latest_template']: output['latest_version'] = output['latest_template']['version_number'] return output
def 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
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!"
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)
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)
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))
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']))
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
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)
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
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))
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
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)
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)
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)
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())
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)
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)