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 update_user_tags(connection, module, params, user): user_name = params['UserName'] existing_tags = user['user']['tags'] new_tags = params.get('Tags') if new_tags is None: return False new_tags = boto3_tag_list_to_ansible_dict(new_tags) purge_tags = module.params.get('purge_tags') tags_to_add, tags_to_remove = compare_aws_tags(existing_tags, new_tags, purge_tags=purge_tags) if not module.check_mode: try: if tags_to_remove: connection.untag_user(UserName=user_name, TagKeys=tags_to_remove) if tags_to_add: connection.tag_user( UserName=user_name, Tags=ansible_dict_to_boto3_tag_list(tags_to_add)) except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e: module.fail_json_aws(e, msg='Unable to set tags for user %s' % user_name) changed = bool(tags_to_add) or bool(tags_to_remove) return changed
def update_tags(connection, module, key, desired_tags, purge_tags): # purge_tags needs to be explicitly set, so an empty tags list means remove # all tags to_add, to_remove = compare_aws_tags(key['tags'], desired_tags, purge_tags) if not (bool(to_add) or bool(to_remove)): return False key_id = key['key_arn'] if not module.check_mode: if to_remove: try: connection.untag_resource(KeyId=key_id, TagKeys=to_remove) except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e: module.fail_json_aws(e, msg="Unable to remove tag") if to_add: try: tags = ansible_dict_to_boto3_tag_list( module.params['tags'], tag_name_key_name='TagKey', tag_value_key_name='TagValue') connection.tag_resource(KeyId=key_id, Tags=tags) except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e: module.fail_json_aws(e, msg="Unable to add tag to key") return True
def __init__(self, connection, module): self.connection = connection self.module = module self.changed = False self.new_load_balancer = False self.scheme = module.params.get("scheme") self.name = module.params.get("name") self.subnet_mappings = module.params.get("subnet_mappings") self.subnets = module.params.get("subnets") self.deletion_protection = module.params.get("deletion_protection") self.wait = module.params.get("wait") if module.params.get("tags") is not None: self.tags = ansible_dict_to_boto3_tag_list(module.params.get("tags")) else: self.tags = None self.purge_tags = module.params.get("purge_tags") self.elb = get_elb(connection, module, self.name) if self.elb is not None: self.elb_attributes = self.get_elb_attributes() self.elb['tags'] = self.get_elb_tags() else: self.elb_attributes = None
def create_option_group(client, module): changed = True params = dict() params['OptionGroupName'] = module.params.get('option_group_name') params['EngineName'] = module.params.get('engine_name') params['MajorEngineVersion'] = str( module.params.get('major_engine_version')) params['OptionGroupDescription'] = module.params.get( 'option_group_description') if module.params.get('tags'): params['Tags'] = ansible_dict_to_boto3_tag_list( module.params.get('tags')) else: params['Tags'] = list() if module.check_mode: return changed try: client.create_option_group(aws_retry=True, **params) except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e: module.fail_json_aws(e, msg='Unable to create Option Group.') return changed
def _ensure_tags(redshift, identifier, existing_tags, module): """Compares and update resource tags""" account_id = get_aws_account_id(module) region = module.params.get('region') resource_arn = "arn:aws:redshift:{0}:{1}:cluster:{2}" .format(region, account_id, identifier) tags = module.params.get('tags') purge_tags = module.params.get('purge_tags') tags_to_add, tags_to_remove = compare_aws_tags(boto3_tag_list_to_ansible_dict(existing_tags), tags, purge_tags) if tags_to_add: try: redshift.create_tags(ResourceName=resource_arn, Tags=ansible_dict_to_boto3_tag_list(tags_to_add)) except (botocore.exceptions.BotoCoreError, botocore.exceptions.ClientError) as e: module.fail_json_aws(e, msg="Failed to add tags to cluster") if tags_to_remove: try: redshift.delete_tags(ResourceName=resource_arn, TagKeys=tags_to_remove) except (botocore.exceptions.BotoCoreError, botocore.exceptions.ClientError) as e: module.fail_json_aws(e, msg="Failed to delete tags on cluster") changed = bool(tags_to_add or tags_to_remove) return changed
def copy_image(module, ec2): """ Copies an AMI module : AnsibleModule object ec2: ec2 connection object """ image = None changed = False tags = module.params.get('tags') params = { 'SourceRegion': module.params.get('source_region'), 'SourceImageId': module.params.get('source_image_id'), 'Name': module.params.get('name'), 'Description': module.params.get('description'), 'Encrypted': module.params.get('encrypted'), } if module.params.get('kms_key_id'): params['KmsKeyId'] = module.params.get('kms_key_id') try: if module.params.get('tag_equality'): filters = [{ 'Name': 'tag:%s' % k, 'Values': [v] } for (k, v) in module.params.get('tags').items()] filters.append(dict(Name='state', Values=['available', 'pending'])) images = ec2.describe_images(Filters=filters) if len(images['Images']) > 0: image = images['Images'][0] if not image: image = ec2.copy_image(**params) image_id = image['ImageId'] if tags: ec2.create_tags(Resources=[image_id], Tags=ansible_dict_to_boto3_tag_list(tags)) changed = True if module.params.get('wait'): delay = 15 max_attempts = module.params.get('wait_timeout') // delay image_id = image.get('ImageId') ec2.get_waiter('image_available').wait(ImageIds=[image_id], WaiterConfig={ 'Delay': delay, 'MaxAttempts': max_attempts }) module.exit_json(changed=changed, **camel_dict_to_snake_dict(image)) except WaiterError as e: module.fail_json_aws( e, msg='An error occurred waiting for the image to become available') except (ClientError, BotoCoreError) as e: module.fail_json_aws(e, msg="Could not copy AMI") except Exception as e: module.fail_json(msg='Unhandled exception. (%s)' % to_native(e))
def run_task(self, cluster, task_definition, overrides, count, startedBy, launch_type, tags): if overrides is None: overrides = dict() params = dict(cluster=cluster, taskDefinition=task_definition, overrides=overrides, count=count, startedBy=startedBy) if self.module.params['network_configuration']: params['networkConfiguration'] = self.format_network_configuration( self.module.params['network_configuration']) if launch_type: params['launchType'] = launch_type if tags: params['tags'] = ansible_dict_to_boto3_tag_list( tags, 'key', 'value') # TODO: need to check if long arn format enabled. try: response = self.ecs.run_task(**params) except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e: self.module.fail_json_aws(e, msg="Couldn't run task") # include tasks and failures return response['tasks']
def ensure_tags(connection=None, module=None, resource_id=None, tags=None, purge_tags=None, check_mode=None): try: cur_tags = describe_tags_with_backoff(connection, resource_id) except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e: module.fail_json_aws(e, msg='Unable to list tags for VPC') to_add, to_delete = compare_aws_tags(cur_tags, tags, purge_tags) if not to_add and not to_delete: return {'changed': False, 'tags': cur_tags} if check_mode: if not purge_tags: tags = cur_tags.update(tags) return {'changed': True, 'tags': tags} if to_delete: try: connection.delete_tags(Resources=[resource_id], Tags=[{'Key': k} for k in to_delete]) except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e: module.fail_json_aws(e, msg="Couldn't delete tags") if to_add: try: connection.create_tags(Resources=[resource_id], Tags=ansible_dict_to_boto3_tag_list(to_add)) except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e: module.fail_json_aws(e, msg="Couldn't create tags") try: latest_tags = describe_tags_with_backoff(connection, resource_id) except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e: module.fail_json_aws(e, msg='Unable to list tags for VPC') return {'changed': True, 'tags': latest_tags}
def _update_tags(current_table): _tags = module.params.get('tags') if _tags is None: return False tags_to_add, tags_to_remove = compare_aws_tags(current_table['tags'], module.params.get('tags'), purge_tags=module.params.get('purge_tags')) # If neither need updating we can return already if not (tags_to_add or tags_to_remove): return False if module.check_mode: return True if tags_to_add: try: client.tag_resource( aws_retry=True, ResourceArn=current_table['arn'], Tags=ansible_dict_to_boto3_tag_list(tags_to_add), ) except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e: module.fail_json_aws(e, msg="Failed to tag table") if tags_to_remove: try: client.untag_resource( aws_retry=True, ResourceArn=current_table['arn'], TagKeys=tags_to_remove, ) except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e: module.fail_json_aws(e, msg="Failed to untag table") return True
def update_tags(module, connection, group, tags): changed = False existing_tags = connection.list_tags_for_resource( ResourceName=group['DBParameterGroupArn'])['TagList'] to_update, to_delete = compare_aws_tags( boto3_tag_list_to_ansible_dict(existing_tags), tags, module.params['purge_tags']) if to_update: try: connection.add_tags_to_resource( ResourceName=group['DBParameterGroupArn'], Tags=ansible_dict_to_boto3_tag_list(to_update)) changed = True except botocore.exceptions.ClientError as e: module.fail_json(msg="Couldn't add tags to parameter group: %s" % str(e), exception=traceback.format_exc(), **camel_dict_to_snake_dict(e.response)) except botocore.exceptions.ParamValidationError as e: # Usually a tag value has been passed as an int or bool, needs to be a string # The AWS exception message is reasonably ok for this purpose module.fail_json(msg="Couldn't add tags to parameter group: %s." % str(e), exception=traceback.format_exc()) if to_delete: try: connection.remove_tags_from_resource( ResourceName=group['DBParameterGroupArn'], TagKeys=to_delete) changed = True except botocore.exceptions.ClientError as e: module.fail_json( msg="Couldn't remove tags from parameter group: %s" % str(e), exception=traceback.format_exc(), **camel_dict_to_snake_dict(e.response)) return changed
def update_tags(module, connection, group, tags): changed = False existing_tags = connection.list_tags_for_resource( ResourceName=group['DBParameterGroupArn'])['TagList'] to_update, to_delete = compare_aws_tags( boto3_tag_list_to_ansible_dict(existing_tags), tags, module.params['purge_tags']) if to_update: try: connection.add_tags_to_resource( ResourceName=group['DBParameterGroupArn'], Tags=ansible_dict_to_boto3_tag_list(to_update)) changed = True except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e: module.fail_json_aws(e, msg="Couldn't add tags to parameter group") if to_delete: try: connection.remove_tags_from_resource( ResourceName=group['DBParameterGroupArn'], TagKeys=to_delete) changed = True except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e: module.fail_json_aws( e, msg="Couldn't remove tags from parameter group") return changed
def ensure_tags(client, module, resource_arn, existing_tags, tags, purge_tags): if tags is None: return False tags_to_add, tags_to_remove = compare_aws_tags(existing_tags, tags, purge_tags) changed = bool(tags_to_add or tags_to_remove) if tags_to_add: try: client.add_tags_to_resource( ResourceName=resource_arn, Tags=ansible_dict_to_boto3_tag_list(tags_to_add)) except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e: module.fail_json_aws( e, "Couldn't add tags to snapshot {0}".format(resource_arn)) if tags_to_remove: try: client.remove_tags_from_resource(ResourceName=resource_arn, TagKeys=tags_to_remove) except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e: module.fail_json_aws( e, "Couldn't remove tags from snapshot {0}".format(resource_arn)) return changed
def test_ansible_dict_to_boto3_tag_list(self): converted_list = ansible_dict_to_boto3_tag_list(self.tag_example_dict) sorted_converted_list = sorted(converted_list, key=lambda i: (i['Key'])) sorted_list = sorted(self.tag_example_boto3_list, key=lambda i: (i['Key'])) self.assertEqual(sorted_converted_list, sorted_list)
def update_role_tags(connection, module, params, role): new_tags = params.get('Tags') if new_tags is None: return False new_tags = boto3_tag_list_to_ansible_dict(new_tags) role_name = module.params.get('name') purge_tags = module.params.get('purge_tags') try: existing_tags = boto3_tag_list_to_ansible_dict(connection.list_role_tags(RoleName=role_name, aws_retry=True)['Tags']) except (ClientError, KeyError): existing_tags = {} tags_to_add, tags_to_remove = compare_aws_tags(existing_tags, new_tags, purge_tags=purge_tags) if not module.check_mode: try: if tags_to_remove: connection.untag_role(RoleName=role_name, TagKeys=tags_to_remove, aws_retry=True) if tags_to_add: connection.tag_role(RoleName=role_name, Tags=ansible_dict_to_boto3_tag_list(tags_to_add), aws_retry=True) except (ClientError, BotoCoreError) as e: module.fail_json_aws(e, msg='Unable to set tags for role %s' % role_name) changed = bool(tags_to_add) or bool(tags_to_remove) return changed
def create(self, default_action, rules, sampled_requests, cloudwatch_metrics, metric_name, tags, description): req_obj = { 'Name': self.name, 'Scope': self.scope, 'DefaultAction': default_action, 'Rules': rules, 'VisibilityConfig': { 'SampledRequestsEnabled': sampled_requests, 'CloudWatchMetricsEnabled': cloudwatch_metrics, 'MetricName': metric_name } } if description: req_obj['Description'] = description if tags: req_obj['Tags'] = ansible_dict_to_boto3_tag_list(tags) try: response = self.wafv2.create_web_acl(**req_obj) except (BotoCoreError, ClientError) as e: self.fail_json_aws(e, msg="Failed to create wafv2 web acl.") self.existing_acl, self.id, self.locktoken = self.get_web_acl() return self.existing_acl
def start_task(self, cluster, task_definition, overrides, container_instances, startedBy, tags): args = dict() if cluster: args['cluster'] = cluster if task_definition: args['taskDefinition'] = task_definition if overrides: args['overrides'] = overrides if container_instances: args['containerInstances'] = container_instances if startedBy: args['startedBy'] = startedBy if self.module.params['network_configuration']: args['networkConfiguration'] = self.format_network_configuration( self.module.params['network_configuration']) if tags: args['tags'] = ansible_dict_to_boto3_tag_list(tags, 'key', 'value') try: response = self.ecs.start_task(**args) except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e: self.module.fail_json_aws(e, msg="Couldn't start task") # include tasks and failures return response['tasks']
def create_key(connection, module): params = dict(BypassPolicyLockoutSafetyCheck=False, Tags=ansible_dict_to_boto3_tag_list(module.params['tags'], tag_name_key_name='TagKey', tag_value_key_name='TagValue'), KeyUsage='ENCRYPT_DECRYPT', Origin='AWS_KMS') if module.params.get('description'): params['Description'] = module.params['description'] if module.params.get('policy'): params['Policy'] = module.params['policy'] try: result = connection.create_key(**params)['KeyMetadata'] except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e: module.fail_json_aws(e, msg="Failed to create initial key") key = get_key_details(connection, module, result['KeyId']) update_alias(connection, module, key, module.params['alias']) update_key_rotation(connection, module, key, module.params.get('enable_key_rotation')) ensure_enabled_disabled(connection, module, key, module.params.get('enabled')) update_grants(connection, module, key, module.params.get('grants'), False) # make results consistent with kms_facts result = get_key_details(connection, module, key['key_id']) result['changed'] = True return result
def ensure_present(module, connection): groupname = module.params['name'] tags = module.params.get('tags') changed = False errors = [] try: response = connection.describe_db_parameter_groups( DBParameterGroupName=groupname) except botocore.exceptions.ClientError as e: if e.response['Error']['Code'] == 'DBParameterGroupNotFound': response = None else: module.fail_json( msg="Couldn't access parameter group information: %s" % str(e), exception=traceback.format_exc(), **camel_dict_to_snake_dict(e.response)) if not response: params = dict(DBParameterGroupName=groupname, DBParameterGroupFamily=module.params['engine'], Description=module.params['description']) if tags: params['Tags'] = ansible_dict_to_boto3_tag_list(tags) try: response = connection.create_db_parameter_group(**params) changed = True except botocore.exceptions.ClientError as e: module.fail_json(msg="Couldn't create parameter group: %s" % str(e), exception=traceback.format_exc(), **camel_dict_to_snake_dict(e.response)) else: group = response['DBParameterGroups'][0] if tags: changed = update_tags(module, connection, group, tags) if module.params.get('params'): params_changed, errors = update_parameters(module, connection) changed = changed or params_changed try: response = connection.describe_db_parameter_groups( DBParameterGroupName=groupname) group = camel_dict_to_snake_dict(response['DBParameterGroups'][0]) except botocore.exceptions.ClientError as e: module.fail_json( msg="Couldn't obtain parameter group information: %s" % str(e), exception=traceback.format_exc(), **camel_dict_to_snake_dict(e.response)) try: tags = connection.list_tags_for_resource( ResourceName=group['db_parameter_group_arn'])['TagList'] except botocore.exceptions.ClientError as e: module.fail_json(msg="Couldn't obtain parameter group tags: %s" % str(e), exception=traceback.format_exc(), **camel_dict_to_snake_dict(e.response)) group['tags'] = boto3_tag_list_to_ansible_dict(tags) module.exit_json(changed=changed, errors=errors, **group)
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 _generate_attributes(): attributes = _generate_attribute_map() # Use ansible_dict_to_boto3_tag_list to generate the list of dicts # format we need attrs = ansible_dict_to_boto3_tag_list(attributes, tag_name_key_name='AttributeName', tag_value_key_name='AttributeType') return list(attrs)
def main(): ''' MAIN ''' argument_spec = dict( resource=dict(required=True), tags=dict(type='dict', required=True), purge_tags=dict(type='bool', default=False), state=dict(default='present', choices=['present', 'absent']) ) module = AnsibleAWSModule(argument_spec=argument_spec, supports_check_mode=True) resource = module.params['resource'] tags = module.params['tags'] state = module.params['state'] purge_tags = module.params['purge_tags'] result = {'changed': False} efs = module.client('efs', retry_decorator=AWSRetry.jittered_backoff()) current_tags = get_tags(efs, module, resource) add_tags, remove = compare_aws_tags(current_tags, tags, purge_tags=purge_tags) remove_tags = {} if state == 'absent': for key in tags: if key in current_tags and (tags[key] is None or current_tags[key] == tags[key]): remove_tags[key] = current_tags[key] for key in remove: remove_tags[key] = current_tags[key] if remove_tags: result['changed'] = True result['removed_tags'] = remove_tags if not module.check_mode: try: efs.untag_resource(aws_retry=True, ResourceId=resource, TagKeys=list(remove_tags.keys())) except (BotoCoreError, ClientError) as remove_tag_error: module.fail_json_aws(remove_tag_error, msg='Failed to remove tags {0} from resource {1}'.format(remove_tags, resource)) if state == 'present' and add_tags: result['changed'] = True result['added_tags'] = add_tags current_tags.update(add_tags) if not module.check_mode: try: tags = ansible_dict_to_boto3_tag_list(add_tags) efs.tag_resource(aws_retry=True, ResourceId=resource, Tags=tags) except (BotoCoreError, ClientError) as set_tag_error: module.fail_json_aws(set_tag_error, msg='Failed to set tags {0} on resource {1}'.format(add_tags, resource)) result['tags'] = get_tags(efs, module, resource) module.exit_json(**result)
def build_policy(module): policy = { 'ExecutionRoleArn': module.params['role'], 'State': 'ENABLED' if module.params['enabled'] else 'DISABLED', 'Description': module.params['description'], } details = { # This is currently the only valid value 'PolicyType': 'EBS_SNAPSHOT_MANAGEMENT', # This takes a list, but the list can currently only contain one item 'ResourceTypes': [module.params['resource_type'].upper()], 'TargetTags': process_target_tags(module.params['target_tags']), } # Another single-element list details['Schedules'] = [{ # The API docs claim Name is optional, but the API says it is required. 'Name': module.params['schedule_name'], 'CreateRule': { 'Interval': module.params['interval'], 'IntervalUnit': 'HOURS', 'Times': [module.params['start_time']], }, 'RetainRule': { 'Count': module.params['retain'], }, 'CopyTags': module.params['copy_tags'], 'TagsToAdd': ansible_dict_to_boto3_tag_list(module.params['tags_to_add']), }] if module.params['resource_type'] == 'instance': details['Parameters'] = { 'ExcludeBootVolume': module.params['exclude_boot_volume'], } details['Schedules'][0][ 'VariableTags'] = ansible_dict_to_boto3_tag_list( module.params['variable_tags']) policy['PolicyDetails'] = details return policy
def ensure_present(module, connection): groupname = module.params['name'] tags = module.params.get('tags') changed = False errors = [] try: response = connection.describe_db_parameter_groups( aws_retry=True, DBParameterGroupName=groupname) except is_boto3_error_code('DBParameterGroupNotFound'): response = None except botocore.exceptions.ClientError as e: # pylint: disable=duplicate-except module.fail_json_aws(e, msg="Couldn't access parameter group information") if not response: params = dict(DBParameterGroupName=groupname, DBParameterGroupFamily=module.params['engine'], Description=module.params['description']) if tags: params['Tags'] = ansible_dict_to_boto3_tag_list(tags) if not module.check_mode: try: response = connection.create_db_parameter_group(aws_retry=True, **params) changed = True except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e: module.fail_json_aws(e, msg="Couldn't create parameter group") else: group = response['DBParameterGroups'][0] if tags: changed = update_tags(module, connection, group, tags) if module.params.get('params'): params_changed, errors = update_parameters(module, connection) changed = changed or params_changed try: response = connection.describe_db_parameter_groups( aws_retry=True, DBParameterGroupName=groupname) group = camel_dict_to_snake_dict(response['DBParameterGroups'][0]) except is_boto3_error_code('DBParameterGroupNotFound'): module.exit_json(changed=True, errors=errors) except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e: # pylint: disable=duplicate-except module.fail_json_aws(e, msg="Couldn't obtain parameter group information") try: tags = connection.list_tags_for_resource( aws_retry=True, ResourceName=group['db_parameter_group_arn'])['TagList'] except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e: module.fail_json_aws(e, msg="Couldn't obtain parameter group tags") group['tags'] = boto3_tag_list_to_ansible_dict(tags) module.exit_json(changed=changed, errors=errors, **group)
def create_args(self): args = {"Name": self.name} if self.description: args["Description"] = self.description if self.kms_key_id: args["KmsKeyId"] = self.kms_key_id if self.tags: args["Tags"] = ansible_dict_to_boto3_tag_list(self.tags) args[self.secret_type] = self.secret return args
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 create_table(): table_name = module.params.get('name') table_class = module.params.get('table_class') hash_key_name = module.params.get('hash_key_name') billing_mode = module.params.get('billing_mode') if billing_mode is None: billing_mode = "PROVISIONED" tags = ansible_dict_to_boto3_tag_list(module.params.get('tags') or {}) if not hash_key_name: module.fail_json( '"hash_key_name" must be provided when creating a new table.') if module.check_mode: return True if billing_mode == "PROVISIONED": throughput = _generate_throughput() attributes = _generate_attributes() key_schema = _generate_schema() local_indexes = _generate_local_indexes() global_indexes = _generate_global_indexes(billing_mode) params = dict(TableName=table_name, AttributeDefinitions=attributes, KeySchema=key_schema, Tags=tags, BillingMode=billing_mode # TODO (future) # StreamSpecification, # SSESpecification, ) if table_class: params['TableClass'] = table_class if billing_mode == "PROVISIONED": params['ProvisionedThroughput'] = throughput if local_indexes: params['LocalSecondaryIndexes'] = local_indexes if global_indexes: params['GlobalSecondaryIndexes'] = global_indexes try: client.create_table(aws_retry=True, **params) except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e: module.fail_json_aws(e, msg='Failed to create table') if module.params.get('wait'): wait_exists() return True
def _create_metrics_configuration(mc_id, filter_prefix, filter_tags): payload = {'Id': mc_id} # Just a filter_prefix or just a single tag filter is a special case if filter_prefix and not filter_tags: payload['Filter'] = {'Prefix': filter_prefix} elif not filter_prefix and len(filter_tags) == 1: payload['Filter'] = { 'Tag': ansible_dict_to_boto3_tag_list(filter_tags)[0] } # Otherwise we need to use 'And' elif filter_tags: payload['Filter'] = { 'And': { 'Tags': ansible_dict_to_boto3_tag_list(filter_tags) } } if filter_prefix: payload['Filter']['And']['Prefix'] = filter_prefix return payload
def tag_trail(module, client, tags, trail_arn, curr_tags=None, dry_run=False): """ Creates, updates, removes tags on a CloudTrail resource module : AnsibleAWSModule object client : boto3 client connection object tags : Dict of tags converted from ansible_dict to boto3 list of dicts trail_arn : The ARN of the CloudTrail to operate on curr_tags : Dict of the current tags on resource, if any dry_run : true/false to determine if changes will be made if needed """ adds = [] removes = [] updates = [] changed = False if curr_tags is None: # No current tags so just convert all to a tag list adds = ansible_dict_to_boto3_tag_list(tags) else: curr_keys = set(curr_tags.keys()) new_keys = set(tags.keys()) add_keys = new_keys - curr_keys remove_keys = curr_keys - new_keys update_keys = dict() for k in curr_keys.intersection(new_keys): if curr_tags[k] != tags[k]: update_keys.update({k: tags[k]}) adds = get_tag_list(add_keys, tags) removes = get_tag_list(remove_keys, curr_tags) updates = get_tag_list(update_keys, tags) if removes or updates: changed = True if not dry_run: try: client.remove_tags(ResourceId=trail_arn, TagsList=removes + updates) except (BotoCoreError, ClientError) as err: module.fail_json_aws(err, msg="Failed to remove tags from Trail") if updates or adds: changed = True if not dry_run: try: client.add_tags(ResourceId=trail_arn, TagsList=updates + adds) except (BotoCoreError, ClientError) as err: module.fail_json_aws(err, msg="Failed to add tags to Trail") return changed
def create(sfn_client, module): check_mode(module, msg='State machine would be created.', changed=True) tags = module.params.get('tags') sfn_tags = ansible_dict_to_boto3_tag_list(tags, tag_name_key_name='key', tag_value_key_name='value') if tags else [] state_machine = sfn_client.create_state_machine( name=module.params.get('name'), definition=module.params.get('definition'), roleArn=module.params.get('role_arn'), tags=sfn_tags ) module.exit_json(changed=True, state_machine_arn=state_machine.get('stateMachineArn'))