def describe_subnets(connection, module): """ Describe Subnets. module : AnsibleAWSModule object connection : boto3 client connection object """ # collect parameters filters = ansible_dict_to_boto3_filter_list(module.params.get('filters')) subnet_ids = module.params.get('subnet_ids') if subnet_ids is None: # Set subnet_ids to empty list if it is None subnet_ids = [] # init empty list for return vars subnet_info = list() # Get the basic VPC info try: response = describe_subnets_with_backoff(connection, subnet_ids, filters) except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e: module.fail_json_aws(e, msg='Failed to describe subnets') for subnet in response['Subnets']: # for backwards compatibility subnet['id'] = subnet['SubnetId'] subnet_info.append(camel_dict_to_snake_dict(subnet)) # convert tag list to ansible dict subnet_info[-1]['tags'] = boto3_tag_list_to_ansible_dict( subnet.get('Tags', [])) module.exit_json(subnets=subnet_info)
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")) try: snapshots = connection.describe_snapshots( SnapshotIds=snapshot_ids, OwnerIds=owner_ids, RestorableByUserIds=restorable_by_user_ids, Filters=filters) 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') # 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') module.exit_json(snapshots=snaked_snapshots)
def get_nat_gateways(client, module): params = dict() nat_gateways = list() params['Filter'] = ansible_dict_to_boto3_filter_list( module.params.get('filters')) params['NatGatewayIds'] = module.params.get('nat_gateway_ids') try: result = normalize_boto3_result( _describe_nat_gateways(client, module, **params)) except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e: module.fail_json_aws(e, 'Unable to describe NAT gateways.') for gateway in result: # Turn the boto3 result into ansible_friendly_snaked_names converted_gateway = camel_dict_to_snake_dict(gateway) if 'tags' in converted_gateway: # Turn the boto3 result into ansible friendly tag dictionary converted_gateway['tags'] = boto3_tag_list_to_ansible_dict( converted_gateway['tags']) nat_gateways.append(converted_gateway) return nat_gateways
def 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 = AWSRetry.exponential_backoff()(self._connection.describe_transit_gateways)(Filters=filters) except (ClientError, BotoCoreError) as e: self._module.fail_json_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
def describe_peering_connections(params, client): peer_filter = { 'requester-vpc-info.vpc-id': params['VpcId'], 'accepter-vpc-info.vpc-id': params['PeerVpcId'], } result = client.describe_vpc_peering_connections( aws_retry=True, Filters=ansible_dict_to_boto3_filter_list(peer_filter), ) if result['VpcPeeringConnections'] == []: result = client.describe_vpc_peering_connections( aws_retry=True, Filters=ansible_dict_to_boto3_filter_list(peer_filter), ) return result
def main(): argument_spec = dict( filters=dict(default={}, type='dict') ) module = AnsibleAWSModule(argument_spec=argument_spec, supports_check_mode=True) if module._name == 'aws_region_facts': module.deprecate("The 'aws_region_facts' module has been renamed to 'aws_region_info'", date='2021-12-01', collection_name='community.aws') connection = module.client('ec2', retry_decorator=AWSRetry.jittered_backoff()) # Replace filter key underscores with dashes, for compatibility sanitized_filters = dict(module.params.get('filters')) for k in module.params.get('filters').keys(): if "_" in k: sanitized_filters[k.replace('_', '-')] = sanitized_filters[k] del sanitized_filters[k] try: regions = connection.describe_regions( aws_retry=True, Filters=ansible_dict_to_boto3_filter_list(sanitized_filters) ) except (BotoCoreError, ClientError) as e: module.fail_json_aws(e, msg="Unable to describe regions.") module.exit_json(regions=[camel_dict_to_snake_dict(r) for r in regions['Regions']])
def get_nat_gateways(client, module, nat_gateway_id=None): params = dict() nat_gateways = list() params['Filter'] = ansible_dict_to_boto3_filter_list( module.params.get('filters')) params['NatGatewayIds'] = module.params.get('nat_gateway_ids') try: result = json.loads( json.dumps(client.describe_nat_gateways(**params), default=date_handler)) except Exception as e: module.fail_json(msg=to_native(e)) for gateway in result['NatGateways']: # Turn the boto3 result into ansible_friendly_snaked_names converted_gateway = camel_dict_to_snake_dict(gateway) if 'tags' in converted_gateway: # Turn the boto3 result into ansible friendly tag dictionary converted_gateway['tags'] = boto3_tag_list_to_ansible_dict( converted_gateway['tags']) nat_gateways.append(converted_gateway) return nat_gateways
def allocate_address(ec2, module, domain, reuse_existing_ip_allowed, check_mode, tag_dict=None, public_ipv4_pool=None): """ Allocate a new elastic IP address (when needed) and return it """ if reuse_existing_ip_allowed: filters = [] if not domain: domain = 'standard' filters.append({'Name': 'domain', "Values": [domain]}) if tag_dict is not None: filters += ansible_dict_to_boto3_filter_list(tag_dict) try: all_addresses = ec2.describe_addresses(Filters=filters, aws_retry=True) except (botocore.exceptions.BotoCoreError, botocore.exceptions.ClientError) as e: module.fail_json_aws(e, msg="Couldn't obtain list of existing Elastic IP addresses") all_addresses = all_addresses["Addresses"] if domain == 'vpc': unassociated_addresses = [a for a in all_addresses if not a.get('AssociationId', None)] else: unassociated_addresses = [a for a in all_addresses if not a['InstanceId']] if unassociated_addresses: return unassociated_addresses[0], False if public_ipv4_pool: return allocate_address_from_pool(ec2, module, domain, check_mode, public_ipv4_pool), True try: result = ec2.allocate_address(Domain=domain, aws_retry=True), True except (botocore.exceptions.BotoCoreError, botocore.exceptions.ClientError) as e: module.fail_json_aws(e, msg="Couldn't allocate Elastic IP address") return result
def ensure_subnet_association(connection=None, module=None, vpc_id=None, route_table_id=None, subnet_id=None, check_mode=None): filters = ansible_dict_to_boto3_filter_list({'association.subnet-id': subnet_id, 'vpc-id': vpc_id}) try: route_tables = describe_route_tables_with_backoff(connection, Filters=filters) except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e: module.fail_json_aws(e, msg="Couldn't get route tables") for route_table in route_tables: if route_table['RouteTableId'] is None: continue for a in route_table['Associations']: if a['Main']: continue if a['SubnetId'] == subnet_id: if route_table['RouteTableId'] == route_table_id: return {'changed': False, 'association_id': a['RouteTableAssociationId']} else: if check_mode: return {'changed': True} try: connection.disassociate_route_table(AssociationId=a['RouteTableAssociationId']) except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e: module.fail_json_aws(e, msg="Couldn't disassociate subnet from route table") try: association_id = connection.associate_route_table(RouteTableId=route_table_id, SubnetId=subnet_id) except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e: module.fail_json_aws(e, msg="Couldn't associate subnet with route table") return {'changed': True, 'association_id': association_id}
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 is_boto3_error_code('InvalidTransitGatewayID.NotFound'): self._results['transit_gateways'] = [] return 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
def main(): argument_spec = dict(filters=dict(default={}, type='dict')) module = AnsibleAWSModule(argument_spec=argument_spec) if module._name == 'aws_az_facts': module.deprecate( "The 'aws_az_facts' module has been renamed to 'aws_az_info'", version='2.14') connection = module.client('ec2', retry_decorator=AWSRetry.jittered_backoff()) # Replace filter key underscores with dashes, for compatibility sanitized_filters = dict((k.replace('_', '-'), v) for k, v in module.params.get('filters').items()) try: availability_zones = connection.describe_availability_zones( Filters=ansible_dict_to_boto3_filter_list(sanitized_filters)) except (BotoCoreError, ClientError) as e: module.fail_json_aws(e, msg="Unable to describe availability zones.") # Turn the boto3 result into ansible_friendly_snaked_names snaked_availability_zones = [ camel_dict_to_snake_dict(az) for az in availability_zones['AvailabilityZones'] ] module.exit_json(availability_zones=snaked_availability_zones)
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_paginator = connection.get_paginator('describe_instances') reservations = reservations_paginator.paginate(InstanceIds=instance_ids, Filters=filters).build_full_result() except ClientError as e: module.fail_json_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 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 list_customer_gateways(connection, module): params = dict() params['Filters'] = ansible_dict_to_boto3_filter_list( module.params.get('filters')) params['CustomerGatewayIds'] = module.params.get('customer_gateway_ids') try: result = json.loads( json.dumps(connection.describe_customer_gateways(**params), default=date_handler)) except (ClientError, BotoCoreError) as e: module.fail_json_aws(e, msg="Could not describe customer gateways") snaked_customer_gateways = [ camel_dict_to_snake_dict(gateway) for gateway in result['CustomerGateways'] ] if snaked_customer_gateways: for customer_gateway in snaked_customer_gateways: customer_gateway['tags'] = boto3_tag_list_to_ansible_dict( customer_gateway.get('tags', [])) customer_gateway_name = customer_gateway['tags'].get('Name') if customer_gateway_name: customer_gateway[ 'customer_gateway_name'] = customer_gateway_name module.exit_json(changed=False, customer_gateways=snaked_customer_gateways)
def list_ec2_instances(connection, module): instance_ids = module.params.get("instance_ids") filters = ansible_dict_to_boto3_filter_list(module.params.get("filters")) try: reservations_paginator = connection.get_paginator('describe_instances') reservations = reservations_paginator.paginate( InstanceIds=instance_ids, Filters=filters).build_full_result() except ClientError as e: module.fail_json_aws(e, msg="Failed to list ec2 instances") # Get instances from reservations instances = [] for reservation in reservations['Reservations']: instances = instances + reservation['Instances'] # Turn the boto3 result in to ansible_friendly_snaked_names snaked_instances = [ camel_dict_to_snake_dict(instance) for instance in instances ] # Turn the boto3 result in to ansible friendly tag dictionary for instance in snaked_instances: instance['tags'] = boto3_tag_list_to_ansible_dict( instance.get('tags', []), 'key', 'value') module.exit_json(instances=snaked_instances)
def associate_gateway(connection, module, route_table, gateway_id): filters = ansible_dict_to_boto3_filter_list({'association.gateway-id': gateway_id, 'vpc-id': route_table['VpcId']}) try: route_tables = describe_route_tables_with_backoff(connection, Filters=filters) except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e: module.fail_json_aws(e, msg="Couldn't get route tables") for table in route_tables: if table.get('RouteTableId'): for association in table.get('Associations'): if association['Main']: continue if association.get('GatewayId', '') == gateway_id and (association['AssociationState']['State'] in ['associated', 'associating']): if table['RouteTableId'] == route_table['RouteTableId']: return False elif module.check_mode: return True else: try: connection.disassociate_route_table( aws_retry=True, AssociationId=association['RouteTableAssociationId']) except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e: module.fail_json_aws(e, msg="Couldn't disassociate gateway from route table") if not module.check_mode: try: connection.associate_route_table(aws_retry=True, RouteTableId=route_table['RouteTableId'], GatewayId=gateway_id) except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e: module.fail_json_aws(e, msg="Couldn't associate gateway with route table") return True
def disassociate_ipv6_cidr(conn, module, subnet, start_time): if subnet.get('assign_ipv6_address_on_creation'): ensure_assign_ipv6_on_create(conn, module, subnet, False, False, start_time) try: conn.disassociate_subnet_cidr_block( AssociationId=subnet['ipv6_association_id']) except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e: module.fail_json_aws( e, msg="Couldn't disassociate ipv6 cidr block id {0} from subnet {1}". format(subnet['ipv6_association_id'], subnet['id'])) # Wait for cidr block to be disassociated if module.params['wait']: filters = ansible_dict_to_boto3_filter_list({ 'ipv6-cidr-block-association.state': ['disassociated'], 'vpc-id': subnet['vpc_id'] }) handle_waiter(conn, module, 'subnet_exists', { 'SubnetIds': [subnet['id']], 'Filters': filters }, start_time)
def instance_info(module, conn): instance_name = module.params.get('db_instance_identifier') filters = module.params.get('filters') params = dict() if instance_name: params['DBInstanceIdentifier'] = instance_name if filters: params['Filters'] = ansible_dict_to_boto3_filter_list(filters) paginator = conn.get_paginator('describe_db_instances') try: results = paginator.paginate(**params).build_full_result()['DBInstances'] except is_boto3_error_code('DBInstanceNotFound'): results = [] except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e: # pylint: disable=duplicate-except module.fail_json_aws(e, "Couldn't get instance information") for instance in results: try: instance['Tags'] = boto3_tag_list_to_ansible_dict(conn.list_tags_for_resource(ResourceName=instance['DBInstanceArn'], aws_retry=True)['TagList']) except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e: module.fail_json_aws(e, "Couldn't get tags for instance %s" % instance['DBInstanceIdentifier']) return dict(changed=False, instances=[camel_dict_to_snake_dict(instance, ignore_list=['Tags']) for instance in results])
def parse(self, inventory, loader, path, cache=True): super(InventoryModule, self).parse(inventory, loader, path) config_data = self._read_config_data(path) self._set_credentials() # get user specifications regions = self.get_option('regions') filters = self.get_option('filters') strict_permissions = self.get_option('strict_permissions') statuses = self.get_option('statuses') include_clusters = self.get_option('include_clusters') instance_filters = ansible_dict_to_boto3_filter_list(filters) cluster_filters = [] if 'db-cluster-id' in filters and include_clusters: cluster_filters = ansible_dict_to_boto3_filter_list( {'db-cluster-id': filters['db-cluster-id']}) cache_key = self.get_cache_key(path) # false when refresh_cache or --flush-cache is used if cache: # get the user-specified directive cache = self.get_option('cache') # Generate inventory formatted_inventory = {} cache_needs_update = False if cache: try: results = self._cache[cache_key] except KeyError: # if cache expires or cache file doesn't exist cache_needs_update = True else: self._populate_from_source(results) if not cache or cache_needs_update: results = self._get_all_hosts(regions, instance_filters, cluster_filters, strict_permissions, statuses, include_clusters) self._populate(results) formatted_inventory = self._format_inventory(results) # If the cache has expired/doesn't exist or if refresh_inventory/flush cache is used # when the user is using caching, update the cached inventory if cache_needs_update or (not cache and self.get_option('cache')): self._cache[cache_key] = formatted_inventory
def ensure_tags(conn, module, subnet, tags, purge_tags, start_time): changed = False filters = ansible_dict_to_boto3_filter_list({ 'resource-id': subnet['id'], 'resource-type': 'subnet' }) try: cur_tags = conn.describe_tags(Filters=filters) except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e: module.fail_json_aws(e, msg="Couldn't describe tags") to_update, to_delete = compare_aws_tags( boto3_tag_list_to_ansible_dict(cur_tags.get('Tags')), tags, purge_tags) if to_update: try: if not module.check_mode: AWSRetry.exponential_backoff( catch_extra_error_codes=['InvalidSubnetID.NotFound'])( conn.create_tags)( Resources=[subnet['id']], Tags=ansible_dict_to_boto3_tag_list(to_update)) changed = True except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e: module.fail_json_aws(e, msg="Couldn't create tags") if to_delete: try: if not module.check_mode: tags_list = [] for key in to_delete: tags_list.append({'Key': key}) AWSRetry.exponential_backoff( catch_extra_error_codes=['InvalidSubnetID.NotFound'])( conn.delete_tags)(Resources=[subnet['id']], Tags=tags_list) changed = True except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e: module.fail_json_aws(e, msg="Couldn't delete tags") if module.params['wait'] and not module.check_mode: # Wait for tags to be updated filters = [{ 'Name': 'tag:{0}'.format(k), 'Values': [v] } for k, v in tags.items()] handle_waiter(conn, module, 'subnet_exists', { 'SubnetIds': [subnet['id']], 'Filters': filters }, start_time) return changed
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 ensure_tags(self, tgw_vpc_attachment_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_vpc_attachment_id: The AWS id of the transit gateway VPC attachment :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_vpc_attachment_id}) try: cur_tags = self._connection.describe_tags(Filters=filters) except (ClientError, BotoCoreError) as e: self._module.fail_json_aws(e, msg="Couldn't describe tags") to_update, to_delete = compare_aws_tags( boto3_tag_list_to_ansible_dict(cur_tags.get('Tags')), tags, purge_tags) if to_update: try: if not self._check_mode: AWSRetry.exponential_backoff()( self._connection.create_tags)( Resources=[tgw_vpc_attachment_id], Tags=ansible_dict_to_boto3_tag_list(to_update)) self._results['changed'] = True tags_changed = True except (ClientError, BotoCoreError) as e: self._module.fail_json_aws( e, msg="Couldn't create tags {0} for resource {1}".format( ansible_dict_to_boto3_tag_list(to_update), tgw_vpc_attachment_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_vpc_attachment_id], Tags=tags_list) self._results['changed'] = True tags_changed = True except (ClientError, BotoCoreError) as e: self._module.fail_json_aws( e, msg="Couldn't delete tags {0} for resource {1}".format( ansible_dict_to_boto3_tag_list(to_delete), tgw_vpc_attachment_id)) return tags_changed
def ensure_tags(self, igw_id, tags, purge_tags): final_tags = [] filters = ansible_dict_to_boto3_filter_list({'resource-id': igw_id, 'resource-type': 'internet-gateway'}) cur_tags = None try: cur_tags = self._connection.describe_tags(aws_retry=True, Filters=filters) except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e: self._module.fail_json_aws(e, msg="Couldn't describe tags") if tags is None: return boto3_tag_list_to_ansible_dict(cur_tags.get('Tags')) to_update, to_delete = compare_aws_tags(boto3_tag_list_to_ansible_dict(cur_tags.get('Tags')), tags, purge_tags) final_tags = boto3_tag_list_to_ansible_dict(cur_tags.get('Tags')) if to_update: try: if self._check_mode: final_tags.update(to_update) else: self._connection.create_tags( aws_retry=True, Resources=[igw_id], Tags=ansible_dict_to_boto3_tag_list(to_update) ) self._results['changed'] = True except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e: self._module.fail_json_aws(e, msg="Couldn't create tags") if to_delete: try: if self._check_mode: for key in to_delete: del final_tags[key] else: tags_list = [] for key in to_delete: tags_list.append({'Key': key}) self._connection.delete_tags(aws_retry=True, Resources=[igw_id], Tags=tags_list) self._results['changed'] = True except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e: self._module.fail_json_aws(e, msg="Couldn't delete tags") if not self._check_mode and (to_update or to_delete): try: response = self._connection.describe_tags(aws_retry=True, Filters=filters) final_tags = boto3_tag_list_to_ansible_dict(response.get('Tags')) except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e: self._module.fail_json_aws(e, msg="Couldn't describe tags") return final_tags
def test_ansible_dict_with_string_to_boto3_filter_list(self): filters = {'some-aws-id': 'i-01234567'} filter_list_string = [{ 'Name': 'some-aws-id', 'Values': [ 'i-01234567', ] }] converted_filters_list = ansible_dict_to_boto3_filter_list(filters) self.assertEqual(converted_filters_list, filter_list_string)
def test_ansible_dict_with_boolean_to_boto3_filter_list(self): filters = {'enabled': True} filter_list_boolean = [{ 'Name': 'enabled', 'Values': [ 'true', ] }] converted_filters_bool = ansible_dict_to_boto3_filter_list(filters) self.assertEqual(converted_filters_bool, filter_list_boolean)
def list_ec2_vpc_route_tables(connection, module): filters = ansible_dict_to_boto3_filter_list(module.params.get("filters")) try: results = describe_route_tables_with_backoff(connection, Filters=filters) except (botocore.exceptions.BotoCoreError, botocore.exceptions.ClientError) as e: module.fail_json_aws(e, msg="Failed to get route tables") results = normalize_results(results) module.exit_json(changed=False, **results)
def test_ansible_dict_with_integer_to_boto3_filter_list(self): filters = {'version': 1} filter_list_integer = [{ 'Name': 'version', 'Values': [ '1', ] }] converted_filters_int = ansible_dict_to_boto3_filter_list(filters) self.assertEqual(converted_filters_int, filter_list_integer)
def get_matching_subnet(conn, module, vpc_id, cidr): filters = ansible_dict_to_boto3_filter_list({'vpc-id': vpc_id, 'cidr-block': cidr}) try: subnets = get_subnet_info(describe_subnets_with_backoff(conn, Filters=filters)) except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e: module.fail_json_aws(e, msg="Couldn't get matching subnet") if subnets: return subnets[0] return None
def get_services(client, module): paginator = client.get_paginator('describe_vpc_endpoint_services') params = {} if module.params.get("filters"): params['Filters'] = ansible_dict_to_boto3_filter_list(module.params.get("filters")) if module.params.get("service_names"): params['ServiceNames'] = module.params.get("service_names") results = paginator.paginate(**params).build_full_result() return results
def get_vpc_peers(client, module): params = dict() params['Filters'] = ansible_dict_to_boto3_filter_list(module.params.get('filters')) if module.params.get('peer_connection_ids'): params['VpcPeeringConnectionIds'] = module.params.get('peer_connection_ids') try: result = json.loads(json.dumps(client.describe_vpc_peering_connections(**params), default=date_handler)) except Exception as e: module.fail_json(msg=str(e.message)) return result['VpcPeeringConnections']