diff --git a/plugins/modules/dynamodb_ttl.py b/plugins/modules/dynamodb_ttl.py index 52b5055db8b..ed2dc49fd4a 100644 --- a/plugins/modules/dynamodb_ttl.py +++ b/plugins/modules/dynamodb_ttl.py @@ -75,7 +75,6 @@ from ansible_collections.amazon.aws.plugins.module_utils.core import AnsibleAWSModule from ansible_collections.amazon.aws.plugins.module_utils.ec2 import boto3_conn -from ansible_collections.amazon.aws.plugins.module_utils.ec2 import camel_dict_to_snake_dict from ansible_collections.amazon.aws.plugins.module_utils.ec2 import get_aws_connection_info @@ -157,11 +156,11 @@ def main(): result['current_status'] = current_state except botocore.exceptions.ClientError as e: - module.fail_json(msg=e.message, exception=traceback.format_exc(), **camel_dict_to_snake_dict(e.response)) + module.fail_json_aws(e, msg="Failed to get or update ttl state") except botocore.exceptions.ParamValidationError as e: - module.fail_json(msg=e.message, exception=traceback.format_exc()) + module.fail_json_aws(e, msg="Failed due to invalid parameters") except ValueError as e: - module.fail_json(msg=str(e)) + module.fail_json_aws(e, msg="Failed") module.exit_json(**result) diff --git a/plugins/modules/ec2_customer_gateway.py b/plugins/modules/ec2_customer_gateway.py index 5c10f4655e4..bcaf9aca2f3 100644 --- a/plugins/modules/ec2_customer_gateway.py +++ b/plugins/modules/ec2_customer_gateway.py @@ -133,7 +133,7 @@ def __init__(self, module): module.fail_json(msg="Region must be specified as a parameter, in EC2_REGION or AWS_REGION environment variables or in boto configuration file") self.ec2 = boto3_conn(module, conn_type='client', resource='ec2', region=region, endpoint=ec2_url, **aws_connect_kwargs) except ClientError as e: - module.fail_json(msg=e.message) + module.fail_json_aws(e, msg="Failed to get connection") @AWSRetry.jittered_backoff(delay=2, max_delay=30, retries=6, catch_extra_error_codes=['IncorrectState']) def ensure_cgw_absent(self, gw_id): diff --git a/plugins/modules/ec2_instance_info.py b/plugins/modules/ec2_instance_info.py index 707df983c1b..88a07d05f61 100644 --- a/plugins/modules/ec2_instance_info.py +++ b/plugins/modules/ec2_instance_info.py @@ -516,7 +516,7 @@ def list_ec2_instances(connection, module): 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(msg=e.message, exception=traceback.format_exc(), **camel_dict_to_snake_dict(e.response)) + module.fail_json_aws(e, msg="Failed to list ec2 instances") # Get instances from reservations instances = [] diff --git a/plugins/modules/ec2_lc_info.py b/plugins/modules/ec2_lc_info.py index 8ddc71083e9..1bed66e0f65 100644 --- a/plugins/modules/ec2_lc_info.py +++ b/plugins/modules/ec2_lc_info.py @@ -175,7 +175,7 @@ def list_launch_configs(connection, module): 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(msg=e.message) + module.fail_json_aws(e, msg="Failed to list launch configs") snaked_launch_configs = [] for launch_config in launch_configs['LaunchConfigurations']: diff --git a/plugins/modules/ec2_vpc_endpoint.py b/plugins/modules/ec2_vpc_endpoint.py index e4e98fb4067..3eaf2850e6e 100644 --- a/plugins/modules/ec2_vpc_endpoint.py +++ b/plugins/modules/ec2_vpc_endpoint.py @@ -186,8 +186,10 @@ pass # Handled by AnsibleAWSModule from ansible.module_utils.six import string_types +from ansible.module_utils._text import to_native from ansible_collections.amazon.aws.plugins.module_utils.core import AnsibleAWSModule +from ansible_collections.amazon.aws.plugins.module_utils.core import is_boto3_error_code from ansible_collections.amazon.aws.plugins.module_utils.ec2 import get_aws_connection_info from ansible_collections.amazon.aws.plugins.module_utils.ec2 import boto3_conn from ansible_collections.amazon.aws.plugins.module_utils.ec2 import camel_dict_to_snake_dict @@ -289,19 +291,15 @@ def create_vpc_endpoint(client, module): 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 botocore.exceptions.ClientError as e: - if "DryRunOperation" in e.message: - changed = True - result = 'Would have created VPC Endpoint if not in check mode' - elif "IdempotentParameterMismatch" in e.message: - module.fail_json(msg="IdempotentParameterMismatch - updates of endpoints are not allowed by the API") - elif "RouteAlreadyExists" in e.message: - module.fail_json(msg="RouteAlreadyExists for one of the route tables - update is not allowed by the API") - else: - module.fail_json(msg=str(e), exception=traceback.format_exc(), - **camel_dict_to_snake_dict(e.response)) + 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 Exception as e: - module.fail_json(msg=str(e), exception=traceback.format_exc(), + module.fail_json(msg=to_native(e), exception=traceback.format_exc(), **camel_dict_to_snake_dict(e.response)) return changed, result @@ -319,15 +317,13 @@ def setup_removal(client, module): result = client.delete_vpc_endpoints(**params)['Unsuccessful'] if not module.check_mode and (result != []): module.fail_json(msg=result) - except botocore.exceptions.ClientError as e: - if "DryRunOperation" in e.message: - changed = True - result = 'Would have deleted VPC Endpoint if not in check mode' - else: - module.fail_json(msg=str(e), exception=traceback.format_exc(), - **camel_dict_to_snake_dict(e.response)) + except is_boto3_error_code('DryRunOperation'): + changed = True + result = 'Would have deleted VPC Endpoint if not in check mode' + except botocore.exceptions.ClientError as e: # pylint: disable=duplicate-except + module.fail_json_aws(e, "Failed to delete VPC endpoint") except Exception as e: - module.fail_json(msg=str(e), exception=traceback.format_exc(), + module.fail_json(msg=to_native(e), exception=traceback.format_exc(), **camel_dict_to_snake_dict(e.response)) return changed, result @@ -362,7 +358,7 @@ def main(): region, ec2_url, aws_connect_kwargs = get_aws_connection_info(module, boto3=True) except NameError as e: # Getting around the get_aws_connection_info boto reliance for region - if "global name 'boto' is not defined" in e.message: + if "global name 'boto' is not defined" in to_native(e): module.params['region'] = botocore.session.get_session().get_config_variable('region') if not module.params['region']: module.fail_json(msg="Error - no region provided") diff --git a/plugins/modules/ec2_vpc_endpoint_info.py b/plugins/modules/ec2_vpc_endpoint_info.py index a48b886a179..f2b6da3adfa 100644 --- a/plugins/modules/ec2_vpc_endpoint_info.py +++ b/plugins/modules/ec2_vpc_endpoint_info.py @@ -113,6 +113,7 @@ except ImportError: pass # Handled by AnsibleAWSModule +from ansible.module_utils._text import to_native from ansible_collections.amazon.aws.plugins.module_utils.core import AnsibleAWSModule from ansible_collections.amazon.aws.plugins.module_utils.ec2 import boto3_conn from ansible_collections.amazon.aws.plugins.module_utils.ec2 import get_aws_connection_info @@ -156,7 +157,7 @@ def get_endpoints(client, module): try: results = json.loads(json.dumps(results, default=date_handler)) except Exception as e: - module.fail_json(msg=str(e.message)) + module.fail_json_aws(e, msg="Failed to get endpoints") return dict(vpc_endpoints=[camel_dict_to_snake_dict(result) for result in results]) diff --git a/plugins/modules/ec2_vpc_nat_gateway.py b/plugins/modules/ec2_vpc_nat_gateway.py index 2216ffe2276..37dd9160084 100644 --- a/plugins/modules/ec2_vpc_nat_gateway.py +++ b/plugins/modules/ec2_vpc_nat_gateway.py @@ -204,7 +204,9 @@ except ImportError: pass # Handled by AnsibleAWSModule +from ansible.module_utils._text import to_native from ansible_collections.amazon.aws.plugins.module_utils.core import AnsibleAWSModule +from ansible_collections.amazon.aws.plugins.module_utils.core import is_boto3_error_code from ansible_collections.amazon.aws.plugins.module_utils.ec2 import get_aws_connection_info from ansible_collections.amazon.aws.plugins.module_utils.ec2 import boto3_conn from ansible_collections.amazon.aws.plugins.module_utils.ec2 import camel_dict_to_snake_dict @@ -698,13 +700,15 @@ def create(client, subnet_id, allocation_id, client_token=None, 'NAT gateway {0} created'.format(result['nat_gateway_id']) ) - except botocore.exceptions.ClientError as e: - if "IdempotentParameterMismatch" in e.message: - err_msg = ( - 'NAT Gateway does not support update and token has already been provided: ' + str(e) - ) - else: - err_msg = str(e) + except is_boto3_error_code('IdempotentParameterMismatch'): + err_msg = ( + 'NAT Gateway does not support update and token has already been provided: ' + err_msg + ) + success = False + changed = False + result = None + except botocore.exceptions.ClientError as e: # pylint: disable=duplicate-except + err_msg = to_native(e) success = False changed = False result = None diff --git a/plugins/modules/ec2_vpc_nat_gateway_info.py b/plugins/modules/ec2_vpc_nat_gateway_info.py index 7f49c708857..9ebeb63fcbb 100644 --- a/plugins/modules/ec2_vpc_nat_gateway_info.py +++ b/plugins/modules/ec2_vpc_nat_gateway_info.py @@ -83,6 +83,7 @@ except ImportError: pass # Handled by AnsibleAWSModule +from ansible.module_utils._text import to_native from ansible_collections.amazon.aws.plugins.module_utils.core import AnsibleAWSModule from ansible_collections.amazon.aws.plugins.module_utils.ec2 import get_aws_connection_info from ansible_collections.amazon.aws.plugins.module_utils.ec2 import boto3_conn @@ -105,7 +106,7 @@ def get_nat_gateways(client, module, nat_gateway_id=None): try: result = json.loads(json.dumps(client.describe_nat_gateways(**params), default=date_handler)) except Exception as e: - module.fail_json(msg=str(e.message)) + module.fail_json(msg=to_native(e)) for gateway in result['NatGateways']: # Turn the boto3 result into ansible_friendly_snaked_names diff --git a/plugins/modules/ec2_vpc_peering_info.py b/plugins/modules/ec2_vpc_peering_info.py index acd5aed83e1..423a04962da 100644 --- a/plugins/modules/ec2_vpc_peering_info.py +++ b/plugins/modules/ec2_vpc_peering_info.py @@ -74,6 +74,7 @@ except ImportError: pass # Handled by AnsibleAWSModule +from ansible.module_utils._text import to_native from ansible_collections.amazon.aws.plugins.module_utils.core import AnsibleAWSModule from ansible_collections.amazon.aws.plugins.module_utils.ec2 import boto3_tag_list_to_ansible_dict from ansible_collections.amazon.aws.plugins.module_utils.ec2 import boto3_conn @@ -94,7 +95,7 @@ def get_vpc_peers(client, module): 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)) + module.fail_json(msg=to_native(e)) return result['VpcPeeringConnections'] @@ -114,7 +115,7 @@ def main(): region, ec2_url, aws_connect_kwargs = get_aws_connection_info(module, boto3=True) except NameError as e: # Getting around the get_aws_connection_info boto reliance for region - if "global name 'boto' is not defined" in e.message: + if "global name 'boto' is not defined" in to_native(e): module.params['region'] = botocore.session.get_session().get_config_variable('region') if not module.params['region']: module.fail_json(msg="Error - no region provided") diff --git a/plugins/modules/ec2_vpc_route_table_info.py b/plugins/modules/ec2_vpc_route_table_info.py index 1b8dc09c6c5..9ff9959c271 100644 --- a/plugins/modules/ec2_vpc_route_table_info.py +++ b/plugins/modules/ec2_vpc_route_table_info.py @@ -91,7 +91,7 @@ def list_ec2_vpc_route_tables(connection, module): try: all_route_tables = connection.get_all_route_tables(filters=filters) except BotoServerError as e: - module.fail_json(msg=e.message) + module.fail_json_aws(e, msg="Failed to get route tables") for route_table in all_route_tables: route_table_dict_array.append(get_route_table_info(route_table)) diff --git a/plugins/modules/ecs_taskdefinition.py b/plugins/modules/ecs_taskdefinition.py index 98831a850e8..b7afe864ee8 100644 --- a/plugins/modules/ecs_taskdefinition.py +++ b/plugins/modules/ecs_taskdefinition.py @@ -273,7 +273,7 @@ def register_task(self, family, task_role_arn, execution_role_arn, network_mode, try: response = self.ecs.register_task_definition(**params) except botocore.exceptions.ClientError as e: - self.module.fail_json(msg=e.message, **camel_dict_to_snake_dict(e.response)) + self.module.fail_json_aws(e, msg="Failed to register task") return response['taskDefinition'] diff --git a/plugins/modules/elasticache.py b/plugins/modules/elasticache.py index b74dce611e2..ab2a9f18fdb 100644 --- a/plugins/modules/elasticache.py +++ b/plugins/modules/elasticache.py @@ -227,8 +227,7 @@ def create(self): self.conn.create_cache_cluster(**kwargs) except botocore.exceptions.ClientError as e: - self.module.fail_json(msg=e.message, exception=format_exc(), - **camel_dict_to_snake_dict(e.response)) + self.module.fail_json_aws(e, msg="Failed to create cache cluster") self._refresh_data() @@ -255,8 +254,7 @@ def delete(self): try: response = self.conn.delete_cache_cluster(CacheClusterId=self.name) except botocore.exceptions.ClientError as e: - self.module.fail_json(msg=e.message, exception=format_exc(), - **camel_dict_to_snake_dict(e.response)) + self.module.fail_json_aws(e, msg="Failed to delete cache cluster") cache_cluster_data = response['CacheCluster'] self._refresh_data(cache_cluster_data) @@ -306,8 +304,7 @@ def modify(self): ApplyImmediately=True, EngineVersion=self.cache_engine_version) except botocore.exceptions.ClientError as e: - self.module.fail_json(msg=e.message, exception=format_exc(), - **camel_dict_to_snake_dict(e.response)) + self.module.fail_json_aws(e, msg="Failed to modify cache cluster") self._refresh_data() @@ -335,8 +332,7 @@ def reboot(self): self.conn.reboot_cache_cluster(CacheClusterId=self.name, CacheNodeIdsToReboot=cache_node_ids) except botocore.exceptions.ClientError as e: - self.module.fail_json(msg=e.message, exception=format_exc(), - **camel_dict_to_snake_dict(e.response)) + self.module.fail_json_aws(e, msg="Failed to reboot cache cluster") self._refresh_data() @@ -455,8 +451,7 @@ def _refresh_data(self, cache_cluster_data=None): self.status = 'gone' return else: - self.module.fail_json(msg=e.message, exception=format_exc(), - **camel_dict_to_snake_dict(e.response)) + self.module.fail_json_aws(e, msg="Failed to describe cache clusters") cache_cluster_data = response['CacheClusters'][0] self.data = cache_cluster_data self.status = self.data['CacheClusterStatus'] diff --git a/plugins/modules/elasticache_subnet_group.py b/plugins/modules/elasticache_subnet_group.py index 15cbd596843..ab25e294eeb 100644 --- a/plugins/modules/elasticache_subnet_group.py +++ b/plugins/modules/elasticache_subnet_group.py @@ -64,6 +64,7 @@ except ImportError: pass # Handled by HAS_BOTO +from ansible.module_utils._text import to_native from ansible_collections.amazon.aws.plugins.module_utils.core import AnsibleAWSModule from ansible_collections.amazon.aws.plugins.module_utils.ec2 import HAS_BOTO from ansible_collections.amazon.aws.plugins.module_utils.ec2 import get_aws_connection_info @@ -105,7 +106,7 @@ def main(): try: conn = connect_to_region(region_name=region, **aws_connect_kwargs) except boto.exception.NoAuthHandlerFound as e: - module.fail_json(msg=e.message) + module.fail_json(msg=to_native(e)) try: changed = False diff --git a/plugins/modules/elb_application_lb_info.py b/plugins/modules/elb_application_lb_info.py index ef02d59e54f..1ed3d4c7cd2 100644 --- a/plugins/modules/elb_application_lb_info.py +++ b/plugins/modules/elb_application_lb_info.py @@ -170,7 +170,9 @@ except ImportError: pass # Handled by AnsibleAWSModule +from ansible.module_utils._text import to_native from ansible_collections.amazon.aws.plugins.module_utils.core import AnsibleAWSModule +from ansible_collections.amazon.aws.plugins.module_utils.core import is_boto3_error_code from ansible_collections.amazon.aws.plugins.module_utils.ec2 import boto3_conn from ansible_collections.amazon.aws.plugins.module_utils.ec2 import boto3_tag_list_to_ansible_dict from ansible_collections.amazon.aws.plugins.module_utils.ec2 import camel_dict_to_snake_dict @@ -182,7 +184,7 @@ def get_elb_listeners(connection, module, elb_arn): try: return connection.describe_listeners(LoadBalancerArn=elb_arn)['Listeners'] except ClientError as e: - module.fail_json(msg=e.message, exception=traceback.format_exc(), **camel_dict_to_snake_dict(e.response)) + module.fail_json_aws(e, msg="Failed to describe elb listeners") def get_listener_rules(connection, module, listener_arn): @@ -190,7 +192,7 @@ def get_listener_rules(connection, module, listener_arn): try: return connection.describe_rules(ListenerArn=listener_arn)['Rules'] except ClientError as e: - module.fail_json(msg=e.message, exception=traceback.format_exc(), **camel_dict_to_snake_dict(e.response)) + module.fail_json_aws(e, msg="Failed to describe listener rules") def get_load_balancer_attributes(connection, module, load_balancer_arn): @@ -198,7 +200,7 @@ def get_load_balancer_attributes(connection, module, load_balancer_arn): try: load_balancer_attributes = boto3_tag_list_to_ansible_dict(connection.describe_load_balancer_attributes(LoadBalancerArn=load_balancer_arn)['Attributes']) except ClientError as e: - module.fail_json(msg=e.message, exception=traceback.format_exc(), **camel_dict_to_snake_dict(e.response)) + module.fail_json_aws(e, msg="Failed to describe load balancer attributes") # Replace '.' with '_' in attribute key names to make it more Ansibley for k, v in list(load_balancer_attributes.items()): @@ -213,7 +215,7 @@ def get_load_balancer_tags(connection, module, load_balancer_arn): try: return boto3_tag_list_to_ansible_dict(connection.describe_tags(ResourceArns=[load_balancer_arn])['TagDescriptions'][0]['Tags']) except ClientError as e: - module.fail_json(msg=e.message, exception=traceback.format_exc(), **camel_dict_to_snake_dict(e.response)) + module.fail_json_aws(e, msg="Failed to describe load balancer tags") def list_load_balancers(connection, module): @@ -229,13 +231,12 @@ def list_load_balancers(connection, module): load_balancers = load_balancer_paginator.paginate(LoadBalancerArns=load_balancer_arns).build_full_result() if names: load_balancers = load_balancer_paginator.paginate(Names=names).build_full_result() - except ClientError as e: - if e.response['Error']['Code'] == 'LoadBalancerNotFound': - module.exit_json(load_balancers=[]) - else: - module.fail_json(msg=e.message, exception=traceback.format_exc(), **camel_dict_to_snake_dict(e.response)) + except is_boto3_error_code('LoadBalancerNotFound'): + module.exit_json(load_balancers=[]) + except ClientError as e: # pylint: disable=duplicate-except + module.fail_json_aws(e, msg="Failed to list load balancers") except NoCredentialsError as e: - module.fail_json(msg="AWS authentication problem. " + e.message, exception=traceback.format_exc()) + module.fail_json(msg="AWS authentication problem. " + to_native(e), exception=traceback.format_exc()) for load_balancer in load_balancers['LoadBalancers']: # Get the attributes for each elb diff --git a/plugins/modules/elb_classic_lb.py b/plugins/modules/elb_classic_lb.py index 52aee159373..5d35fca3bc5 100644 --- a/plugins/modules/elb_classic_lb.py +++ b/plugins/modules/elb_classic_lb.py @@ -459,7 +459,7 @@ def __init__(self, module, name, listeners=None, purge_listeners=None, try: self.elb = self._get_elb() except boto.exception.BotoServerError as e: - module.fail_json(msg='unable to get all load balancers: %s' % e.message, exception=traceback.format_exc()) + module.fail_json(msg='unable to get all load balancers: %s' % to_native(e), exception=traceback.format_exc()) self.ec2_conn = self._get_ec2_connection() @@ -820,7 +820,7 @@ def _enable_zones(self, zones): try: self.elb.enable_zones(zones) except boto.exception.BotoServerError as e: - self.module.fail_json(msg='unable to enable zones: %s' % e.message, exception=traceback.format_exc()) + self.module.fail_json(msg='unable to enable zones: %s' % to_native(e), exception=traceback.format_exc()) self.changed = True @@ -828,7 +828,7 @@ def _disable_zones(self, zones): try: self.elb.disable_zones(zones) except boto.exception.BotoServerError as e: - self.module.fail_json(msg='unable to disable zones: %s' % e.message, exception=traceback.format_exc()) + self.module.fail_json(msg='unable to disable zones: %s' % to_native(e), exception=traceback.format_exc()) self.changed = True def _attach_subnets(self, subnets): diff --git a/plugins/modules/elb_target_group_info.py b/plugins/modules/elb_target_group_info.py index 88f670f8e04..c444521d887 100644 --- a/plugins/modules/elb_target_group_info.py +++ b/plugins/modules/elb_target_group_info.py @@ -215,7 +215,9 @@ except ImportError: pass # Handled by AnsibleAWSModule +from ansible.module_utils._text import to_native from ansible_collections.amazon.aws.plugins.module_utils.core import AnsibleAWSModule +from ansible_collections.amazon.aws.plugins.module_utils.core import is_boto3_error_code from ansible_collections.amazon.aws.plugins.module_utils.ec2 import boto3_conn from ansible_collections.amazon.aws.plugins.module_utils.ec2 import boto3_tag_list_to_ansible_dict from ansible_collections.amazon.aws.plugins.module_utils.ec2 import camel_dict_to_snake_dict @@ -227,7 +229,7 @@ def get_target_group_attributes(connection, module, target_group_arn): try: target_group_attributes = boto3_tag_list_to_ansible_dict(connection.describe_target_group_attributes(TargetGroupArn=target_group_arn)['Attributes']) except ClientError as e: - module.fail_json(msg=e.message, exception=traceback.format_exc(), **camel_dict_to_snake_dict(e.response)) + module.fail_json_aws(e, msg="Failed to describe target group attributes") # Replace '.' with '_' in attribute key names to make it more Ansibley return dict((k.replace('.', '_'), v) @@ -239,7 +241,7 @@ def get_target_group_tags(connection, module, target_group_arn): try: return boto3_tag_list_to_ansible_dict(connection.describe_tags(ResourceArns=[target_group_arn])['TagDescriptions'][0]['Tags']) except ClientError as e: - module.fail_json(msg=e.message, exception=traceback.format_exc(), **camel_dict_to_snake_dict(e.response)) + module.fail_json_aws(e, msg="Failed to describe group tags") def get_target_group_targets_health(connection, module, target_group_arn): @@ -247,7 +249,7 @@ def get_target_group_targets_health(connection, module, target_group_arn): try: return connection.describe_target_health(TargetGroupArn=target_group_arn)['TargetHealthDescriptions'] except ClientError as e: - module.fail_json(msg=e.message, exception=traceback.format_exc(), **camel_dict_to_snake_dict(e.response)) + module.fail_json_aws(e, msg="Failed to get target health") def list_target_groups(connection, module): @@ -267,13 +269,12 @@ def list_target_groups(connection, module): 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 ClientError as e: - if e.response['Error']['Code'] == 'TargetGroupNotFound': - module.exit_json(target_groups=[]) - else: - module.fail_json(msg=e.message, exception=traceback.format_exc(), **camel_dict_to_snake_dict(e.response)) + 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. " + e.message, exception=traceback.format_exc()) + 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']: diff --git a/plugins/modules/iam_mfa_device_info.py b/plugins/modules/iam_mfa_device_info.py index 727242751a6..c107c39f67b 100644 --- a/plugins/modules/iam_mfa_device_info.py +++ b/plugins/modules/iam_mfa_device_info.py @@ -82,7 +82,7 @@ def list_mfa_devices(connection, module): try: response = connection.list_mfa_devices(**args) except ClientError as e: - module.fail_json(msg=e.message, **camel_dict_to_snake_dict(e.response)) + module.fail_json_aws(e, msg="Failed to list MFA devices") module.exit_json(changed=changed, **camel_dict_to_snake_dict(response)) diff --git a/plugins/modules/rds.py b/plugins/modules/rds.py index 38e60662c05..1321186497a 100644 --- a/plugins/modules/rds.py +++ b/plugins/modules/rds.py @@ -532,6 +532,7 @@ except ImportError: HAS_RDS2 = False +from ansible.module_utils._text import to_native from ansible_collections.amazon.aws.plugins.module_utils.core import AnsibleAWSModule from ansible_collections.amazon.aws.plugins.module_utils.ec2 import AWSRetry from ansible_collections.amazon.aws.plugins.module_utils.ec2 import HAS_BOTO @@ -983,7 +984,7 @@ def create_db_instance(module, conn): module.params.get('username'), module.params.get('password'), **params) changed = True except RDSException as e: - module.fail_json(msg="Failed to create instance: %s" % e.message) + module.fail_json(msg="Failed to create instance: %s" % to_native(e)) if module.params.get('wait'): resource = await_resource(conn, result, 'available', module) @@ -1010,7 +1011,7 @@ def replicate_db_instance(module, conn): result = conn.create_db_instance_read_replica(instance_name, source_instance, **params) changed = True except RDSException as e: - module.fail_json(msg="Failed to create replica instance: %s " % e.message) + module.fail_json(msg="Failed to create replica instance: %s " % to_native(e)) if module.params.get('wait'): resource = await_resource(conn, result, 'available', module) @@ -1049,7 +1050,7 @@ def delete_db_instance_or_snapshot(module, conn): else: result = conn.delete_db_snapshot(snapshot) except RDSException as e: - module.fail_json(msg="Failed to delete instance: %s" % e.message) + module.fail_json(msg="Failed to delete instance: %s" % to_native(e)) # If we're not waiting for a delete to complete then we're all done # so just return @@ -1062,7 +1063,7 @@ def delete_db_instance_or_snapshot(module, conn): if e.code == 'DBInstanceNotFound': module.exit_json(changed=True) else: - module.fail_json(msg=e.message) + module.fail_json(msg=to_native(e)) except Exception as e: module.fail_json(msg=str(e)) @@ -1099,7 +1100,7 @@ def modify_db_instance(module, conn): try: result = conn.modify_db_instance(instance_name, **params) except RDSException as e: - module.fail_json(msg=e.message) + module.fail_json(msg=to_native(e)) if params.get('apply_immediately'): if new_instance_name: # Wait until the new instance name is valid @@ -1137,7 +1138,7 @@ def promote_db_instance(module, conn): result = conn.promote_read_replica(instance_name, **params) changed = True except RDSException as e: - module.fail_json(msg=e.message) + module.fail_json(msg=to_native(e)) else: changed = False @@ -1162,7 +1163,7 @@ def snapshot_db_instance(module, conn): result = conn.create_db_snapshot(snapshot, instance_name, **params) changed = True except RDSException as e: - module.fail_json(msg=e.message) + module.fail_json(msg=to_native(e)) if module.params.get('wait'): resource = await_resource(conn, result, 'available', module) @@ -1187,7 +1188,7 @@ def reboot_db_instance(module, conn): result = conn.reboot_db_instance(instance_name, **params) changed = True except RDSException as e: - module.fail_json(msg=e.message) + module.fail_json(msg=to_native(e)) if module.params.get('wait'): resource = await_resource(conn, result, 'available', module) @@ -1218,7 +1219,7 @@ def restore_db_instance(module, conn): result = conn.restore_db_instance_from_db_snapshot(instance_name, snapshot, instance_type, **params) changed = True except RDSException as e: - module.fail_json(msg=e.message) + module.fail_json(msg=to_native(e)) if module.params.get('wait'): resource = await_resource(conn, result, 'available', module) diff --git a/plugins/modules/s3_logging.py b/plugins/modules/s3_logging.py index 7cc2f58d733..24f4004eec7 100644 --- a/plugins/modules/s3_logging.py +++ b/plugins/modules/s3_logging.py @@ -65,6 +65,7 @@ except ImportError: pass # Handled by HAS_BOTO +from ansible.module_utils._text import to_native from ansible_collections.amazon.aws.plugins.module_utils.core import AnsibleAWSModule from ansible_collections.amazon.aws.plugins.module_utils.ec2 import AnsibleAWSError from ansible_collections.amazon.aws.plugins.module_utils.ec2 import get_aws_connection_info @@ -90,7 +91,7 @@ def enable_bucket_logging(connection, module): try: bucket = connection.get_bucket(bucket_name) except S3ResponseError as e: - module.fail_json(msg=e.message) + module.fail_json(msg=to_native(e)) try: if not compare_bucket_logging(bucket, target_bucket, target_prefix): @@ -101,14 +102,14 @@ def enable_bucket_logging(connection, module): if e.status == 301: module.fail_json(msg="the logging target bucket must be in the same region as the bucket being logged") else: - module.fail_json(msg=e.message) + module.fail_json(msg=to_native(e)) target_bucket_obj.set_as_logging_target() bucket.enable_logging(target_bucket, target_prefix) changed = True except S3ResponseError as e: - module.fail_json(msg=e.message) + module.fail_json(msg=to_native(e)) module.exit_json(changed=changed) @@ -124,7 +125,7 @@ def disable_bucket_logging(connection, module): bucket.disable_logging() changed = True except S3ResponseError as e: - module.fail_json(msg=e.message) + module.fail_json(msg=to_native(e)) module.exit_json(changed=changed) diff --git a/plugins/modules/s3_website.py b/plugins/modules/s3_website.py index a003331adaf..a281f60f37e 100644 --- a/plugins/modules/s3_website.py +++ b/plugins/modules/s3_website.py @@ -168,6 +168,7 @@ pass # Handled by AnsibleAWSModule from ansible_collections.amazon.aws.plugins.module_utils.core import AnsibleAWSModule +from ansible_collections.amazon.aws.plugins.module_utils.core import is_boto3_error_code from ansible_collections.amazon.aws.plugins.module_utils.ec2 import boto3_conn from ansible_collections.amazon.aws.plugins.module_utils.ec2 import camel_dict_to_snake_dict from ansible_collections.amazon.aws.plugins.module_utils.ec2 import get_aws_connection_info @@ -221,22 +222,21 @@ def enable_or_update_bucket_as_website(client_connection, resource_connection, m try: bucket_website = resource_connection.BucketWebsite(bucket_name) except ClientError as e: - module.fail_json(msg=e.message, **camel_dict_to_snake_dict(e.response)) + module.fail_json_aws(e, msg="Failed to get bucket") try: website_config = client_connection.get_bucket_website(Bucket=bucket_name) - except ClientError as e: - if e.response['Error']['Code'] == 'NoSuchWebsiteConfiguration': - website_config = None - else: - module.fail_json(msg=e.message, **camel_dict_to_snake_dict(e.response)) + except is_boto3_error_code('NoSuchWebsiteConfiguration'): + website_config = None + except ClientError as e: # pylint: disable=duplicate-except + module.fail_json_aws(e, msg="Failed to get website configuration") if website_config is None: try: bucket_website.put(WebsiteConfiguration=_create_website_configuration(suffix, error_key, redirect_all_requests)) changed = True except (ClientError, ParamValidationError) as e: - module.fail_json(msg=e.message, **camel_dict_to_snake_dict(e.response)) + module.fail_json_aws(e, msg="Failed to set bucket website configuration") except ValueError as e: module.fail_json(msg=str(e)) else: @@ -249,13 +249,13 @@ def enable_or_update_bucket_as_website(client_connection, resource_connection, m bucket_website.put(WebsiteConfiguration=_create_website_configuration(suffix, error_key, redirect_all_requests)) changed = True except (ClientError, ParamValidationError) as e: - module.fail_json(msg=e.message, **camel_dict_to_snake_dict(e.response)) + module.fail_json_aws(e, msg="Failed to update bucket website configuration") except KeyError as e: try: bucket_website.put(WebsiteConfiguration=_create_website_configuration(suffix, error_key, redirect_all_requests)) changed = True except (ClientError, ParamValidationError) as e: - module.fail_json(msg=e.message, **camel_dict_to_snake_dict(e.response)) + module.fail_json(e, msg="Failed to update bucket website configuration") except ValueError as e: module.fail_json(msg=str(e)) @@ -273,17 +273,16 @@ def disable_bucket_as_website(client_connection, module): try: client_connection.get_bucket_website(Bucket=bucket_name) - except ClientError as e: - if e.response['Error']['Code'] == 'NoSuchWebsiteConfiguration': - module.exit_json(changed=changed) - else: - module.fail_json(msg=e.message, **camel_dict_to_snake_dict(e.response)) + except is_boto3_error_code('NoSuchWebsiteConfiguration'): + module.exit_json(changed=changed) + except ClientError as e: # pylint: disable=duplicate-except + module.fail_json_aws(e, msg="Failed to get bucket website") try: client_connection.delete_bucket_website(Bucket=bucket_name) changed = True except ClientError as e: - module.fail_json(msg=e.message, **camel_dict_to_snake_dict(e.response)) + module.fail_json_aws(e, msg="Failed to delete bucket website") module.exit_json(changed=changed)