From a52d0efc0d00087413e9401e34f53d245ef01df1 Mon Sep 17 00:00:00 2001 From: Vincent Vinet Date: Mon, 6 Apr 2020 13:32:27 -0400 Subject: [PATCH 1/5] Py3 compat error handling: use to_native(e) instead of str(e) or e.message --- plugins/modules/dynamodb_ttl.py | 5 +++-- plugins/modules/ec2_customer_gateway.py | 3 ++- plugins/modules/ec2_instance_info.py | 3 ++- plugins/modules/ec2_lc_info.py | 3 ++- plugins/modules/ec2_vpc_endpoint.py | 21 ++++++++++++--------- plugins/modules/ec2_vpc_endpoint_info.py | 3 ++- plugins/modules/ec2_vpc_nat_gateway.py | 8 ++++---- plugins/modules/ec2_vpc_nat_gateway_info.py | 3 ++- plugins/modules/ec2_vpc_peering_info.py | 5 +++-- plugins/modules/ec2_vpc_route_table_info.py | 3 ++- plugins/modules/ecs_taskdefinition.py | 4 ++-- plugins/modules/elasticache.py | 11 ++++++----- plugins/modules/elasticache_subnet_group.py | 3 ++- plugins/modules/elb_application_lb_info.py | 13 +++++++------ plugins/modules/elb_classic_lb.py | 6 +++--- plugins/modules/elb_target_group_info.py | 11 ++++++----- plugins/modules/iam_mfa_device_info.py | 3 ++- plugins/modules/lambda.py | 2 +- plugins/modules/rds.py | 19 ++++++++++--------- plugins/modules/s3_logging.py | 9 +++++---- plugins/modules/s3_website.py | 15 ++++++++------- 21 files changed, 86 insertions(+), 67 deletions(-) diff --git a/plugins/modules/dynamodb_ttl.py b/plugins/modules/dynamodb_ttl.py index d4ed856c215..76ce5762ceb 100644 --- a/plugins/modules/dynamodb_ttl.py +++ b/plugins/modules/dynamodb_ttl.py @@ -77,6 +77,7 @@ pass from ansible.module_utils.basic import AnsibleModule +from ansible.module_utils._text import to_native from ansible_collections.amazon.aws.plugins.module_utils.ec2 import (HAS_BOTO3, boto3_conn, camel_dict_to_snake_dict, @@ -166,9 +167,9 @@ 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(msg=to_native(e), exception=traceback.format_exc(), **camel_dict_to_snake_dict(e.response)) except botocore.exceptions.ParamValidationError as e: - module.fail_json(msg=e.message, exception=traceback.format_exc()) + module.fail_json(msg=to_native(e), exception=traceback.format_exc()) except ValueError as e: module.fail_json(msg=str(e)) diff --git a/plugins/modules/ec2_customer_gateway.py b/plugins/modules/ec2_customer_gateway.py index d14ffcfbce4..fb528ee0739 100644 --- a/plugins/modules/ec2_customer_gateway.py +++ b/plugins/modules/ec2_customer_gateway.py @@ -126,6 +126,7 @@ HAS_BOTO3 = False from ansible.module_utils.basic import AnsibleModule +from ansible.module_utils._text import to_native from ansible_collections.amazon.aws.plugins.module_utils.ec2 import (boto3_conn, AWSRetry, camel_dict_to_snake_dict, @@ -145,7 +146,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(msg=to_native(e)) @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 9bb1ff56e7d..9b1d6b60658 100644 --- a/plugins/modules/ec2_instance_info.py +++ b/plugins/modules/ec2_instance_info.py @@ -503,6 +503,7 @@ HAS_BOTO3 = False from ansible.module_utils.basic import AnsibleModule +from ansible.module_utils._text import to_native from ansible_collections.amazon.aws.plugins.module_utils.ec2 import (ansible_dict_to_boto3_filter_list, boto3_conn, boto3_tag_list_to_ansible_dict, @@ -521,7 +522,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(msg=to_native(e), exception=traceback.format_exc(), **camel_dict_to_snake_dict(e.response)) # Get instances from reservations instances = [] diff --git a/plugins/modules/ec2_lc_info.py b/plugins/modules/ec2_lc_info.py index 9a16f2fd0ab..5c5c509a721 100644 --- a/plugins/modules/ec2_lc_info.py +++ b/plugins/modules/ec2_lc_info.py @@ -163,6 +163,7 @@ HAS_BOTO3 = False from ansible.module_utils.basic import AnsibleModule +from ansible.module_utils._text import to_native from ansible_collections.amazon.aws.plugins.module_utils.ec2 import (HAS_BOTO3, boto3_conn, camel_dict_to_snake_dict, @@ -183,7 +184,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(msg=to_native(e)) 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 760af35c62e..7909c63037b 100644 --- a/plugins/modules/ec2_vpc_endpoint.py +++ b/plugins/modules/ec2_vpc_endpoint.py @@ -190,6 +190,7 @@ pass # will be picked up by imported HAS_BOTO3 from ansible.module_utils.basic import AnsibleModule +from ansible.module_utils._text import to_native from ansible_collections.amazon.aws.plugins.module_utils.ec2 import (get_aws_connection_info, boto3_conn, ec2_argument_spec, @@ -296,18 +297,19 @@ def create_vpc_endpoint(client, module): 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: + message = to_native(e) + if "DryRunOperation" in message: changed = True result = 'Would have created VPC Endpoint if not in check mode' - elif "IdempotentParameterMismatch" in e.message: + elif "IdempotentParameterMismatch" in message: module.fail_json(msg="IdempotentParameterMismatch - updates of endpoints are not allowed by the API") - elif "RouteAlreadyExists" in e.message: + elif "RouteAlreadyExists" in 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(), + module.fail_json(msg=message, exception=traceback.format_exc(), **camel_dict_to_snake_dict(e.response)) 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 @@ -326,14 +328,15 @@ def setup_removal(client, module): if not module.check_mode and (result != []): module.fail_json(msg=result) except botocore.exceptions.ClientError as e: - if "DryRunOperation" in e.message: + message = to_native(e) + if "DryRunOperation" in 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(), + module.fail_json(msg=message, exception=traceback.format_exc(), **camel_dict_to_snake_dict(e.response)) 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 @@ -374,7 +377,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 a43ef54ac13..a04819ccfa5 100644 --- a/plugins/modules/ec2_vpc_endpoint_info.py +++ b/plugins/modules/ec2_vpc_endpoint_info.py @@ -117,6 +117,7 @@ pass # will be picked up from imported HAS_BOTO3 from ansible.module_utils.basic import AnsibleModule +from ansible.module_utils._text import to_native from ansible_collections.amazon.aws.plugins.module_utils.ec2 import (ec2_argument_spec, boto3_conn, get_aws_connection_info, @@ -162,7 +163,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(msg=to_native(e)) 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 09fc70de335..2db84eea1a8 100644 --- a/plugins/modules/ec2_vpc_nat_gateway.py +++ b/plugins/modules/ec2_vpc_nat_gateway.py @@ -209,6 +209,7 @@ pass # caught by imported HAS_BOTO3 from ansible.module_utils.basic import AnsibleModule +from ansible.module_utils._text import to_native from ansible_collections.amazon.aws.plugins.module_utils.ec2 import (ec2_argument_spec, get_aws_connection_info, boto3_conn, @@ -706,12 +707,11 @@ def create(client, subnet_id, allocation_id, client_token=None, ) except botocore.exceptions.ClientError as e: - if "IdempotentParameterMismatch" in e.message: + err_msg = to_native(e) + if "IdempotentParameterMismatch" in message: err_msg = ( - 'NAT Gateway does not support update and token has already been provided: ' + str(e) + 'NAT Gateway does not support update and token has already been provided: ' + err_msg ) - else: - err_msg = str(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 a4891391854..44c27a76058 100644 --- a/plugins/modules/ec2_vpc_nat_gateway_info.py +++ b/plugins/modules/ec2_vpc_nat_gateway_info.py @@ -88,6 +88,7 @@ pass # will be detected by imported HAS_BOTO3 from ansible.module_utils.basic import AnsibleModule +from ansible.module_utils._text import to_native from ansible_collections.amazon.aws.plugins.module_utils.ec2 import (ec2_argument_spec, get_aws_connection_info, boto3_conn, @@ -112,7 +113,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 2561a209283..09f1204a3eb 100644 --- a/plugins/modules/ec2_vpc_peering_info.py +++ b/plugins/modules/ec2_vpc_peering_info.py @@ -78,6 +78,7 @@ pass # will be picked up by imported HAS_BOTO3 from ansible.module_utils.basic import AnsibleModule +from ansible.module_utils._text import to_native from ansible_collections.amazon.aws.plugins.module_utils.ec2 import (boto3_tag_list_to_ansible_dict, ec2_argument_spec, boto3_conn, @@ -100,7 +101,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'] @@ -127,7 +128,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 a86e9542570..f2ca70e3c14 100644 --- a/plugins/modules/ec2_vpc_route_table_info.py +++ b/plugins/modules/ec2_vpc_route_table_info.py @@ -62,6 +62,7 @@ HAS_BOTO = False from ansible.module_utils.basic import AnsibleModule +from ansible.module_utils._text import to_native from ansible_collections.amazon.aws.plugins.module_utils.ec2 import AnsibleAWSError, connect_to_aws, ec2_argument_spec, get_aws_connection_info @@ -93,7 +94,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(msg=to_native(e)) 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 895a52d29d1..d2a9e433cca 100644 --- a/plugins/modules/ecs_taskdefinition.py +++ b/plugins/modules/ecs_taskdefinition.py @@ -218,7 +218,7 @@ from ansible_collections.amazon.aws.plugins.module_utils.aws.core import AnsibleAWSModule from ansible_collections.amazon.aws.plugins.module_utils.ec2 import camel_dict_to_snake_dict -from ansible.module_utils._text import to_text +from ansible.module_utils._text import to_text, to_native class EcsTaskManager: @@ -277,7 +277,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(msg=to_native(e), **camel_dict_to_snake_dict(e.response)) return response['taskDefinition'] diff --git a/plugins/modules/elasticache.py b/plugins/modules/elasticache.py index a59eadc11e9..8739873e7ec 100644 --- a/plugins/modules/elasticache.py +++ b/plugins/modules/elasticache.py @@ -133,6 +133,7 @@ from time import sleep from traceback import format_exc from ansible.module_utils.basic import AnsibleModule +from ansible.module_utils._text import to_native from ansible_collections.amazon.aws.plugins.module_utils.ec2 import (ec2_argument_spec, get_aws_connection_info, boto3_conn, @@ -233,7 +234,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(), + self.module.fail_json(msg=to_native(e), exception=format_exc(), **camel_dict_to_snake_dict(e.response)) self._refresh_data() @@ -261,7 +262,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(), + self.module.fail_json(msg=to_native(e), exception=format_exc(), **camel_dict_to_snake_dict(e.response)) cache_cluster_data = response['CacheCluster'] @@ -312,7 +313,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(), + self.module.fail_json(msg=to_native(e), exception=format_exc(), **camel_dict_to_snake_dict(e.response)) self._refresh_data() @@ -341,7 +342,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(), + self.module.fail_json(msg=to_native(e), exception=format_exc(), **camel_dict_to_snake_dict(e.response)) self._refresh_data() @@ -461,7 +462,7 @@ def _refresh_data(self, cache_cluster_data=None): self.status = 'gone' return else: - self.module.fail_json(msg=e.message, exception=format_exc(), + self.module.fail_json(msg=to_native(e), exception=format_exc(), **camel_dict_to_snake_dict(e.response)) cache_cluster_data = response['CacheClusters'][0] self.data = cache_cluster_data diff --git a/plugins/modules/elasticache_subnet_group.py b/plugins/modules/elasticache_subnet_group.py index ed56153c4f9..8bf18373523 100644 --- a/plugins/modules/elasticache_subnet_group.py +++ b/plugins/modules/elasticache_subnet_group.py @@ -70,6 +70,7 @@ HAS_BOTO = False from ansible.module_utils.basic import AnsibleModule +from ansible.module_utils._text import to_native from ansible_collections.amazon.aws.plugins.module_utils.ec2 import HAS_BOTO, ec2_argument_spec, get_aws_connection_info @@ -111,7 +112,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 b347941ee79..34c717ca13f 100644 --- a/plugins/modules/elb_application_lb_info.py +++ b/plugins/modules/elb_application_lb_info.py @@ -173,6 +173,7 @@ HAS_BOTO3 = False from ansible.module_utils.basic import AnsibleModule +from ansible.module_utils._text import to_native from ansible_collections.amazon.aws.plugins.module_utils.ec2 import (boto3_conn, boto3_tag_list_to_ansible_dict, camel_dict_to_snake_dict, @@ -186,7 +187,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(msg=to_native(e), exception=traceback.format_exc(), **camel_dict_to_snake_dict(e.response)) def get_listener_rules(connection, module, listener_arn): @@ -194,7 +195,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(msg=to_native(e), exception=traceback.format_exc(), **camel_dict_to_snake_dict(e.response)) def get_load_balancer_attributes(connection, module, load_balancer_arn): @@ -202,7 +203,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(msg=to_native(e), exception=traceback.format_exc(), **camel_dict_to_snake_dict(e.response)) # Replace '.' with '_' in attribute key names to make it more Ansibley for k, v in list(load_balancer_attributes.items()): @@ -217,7 +218,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(msg=to_native(e), exception=traceback.format_exc(), **camel_dict_to_snake_dict(e.response)) def list_load_balancers(connection, module): @@ -237,9 +238,9 @@ def list_load_balancers(connection, module): 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)) + module.fail_json(msg=to_native(e), exception=traceback.format_exc(), **camel_dict_to_snake_dict(e.response)) 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 5959ebaf3f0..50ed261c9b6 100644 --- a/plugins/modules/elb_classic_lb.py +++ b/plugins/modules/elb_classic_lb.py @@ -454,7 +454,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() @@ -815,7 +815,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 @@ -823,7 +823,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 6c3e335d485..7577042cec9 100644 --- a/plugins/modules/elb_target_group_info.py +++ b/plugins/modules/elb_target_group_info.py @@ -218,6 +218,7 @@ HAS_BOTO3 = False from ansible.module_utils.basic import AnsibleModule +from ansible.module_utils._text import to_native from ansible_collections.amazon.aws.plugins.module_utils.ec2 import (boto3_conn, boto3_tag_list_to_ansible_dict, camel_dict_to_snake_dict, @@ -231,7 +232,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(msg=to_native(e), exception=traceback.format_exc(), **camel_dict_to_snake_dict(e.response)) # Replace '.' with '_' in attribute key names to make it more Ansibley return dict((k.replace('.', '_'), v) @@ -243,7 +244,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(msg=to_native(e), exception=traceback.format_exc(), **camel_dict_to_snake_dict(e.response)) def get_target_group_targets_health(connection, module, target_group_arn): @@ -251,7 +252,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(msg=to_native(e), exception=traceback.format_exc(), **camel_dict_to_snake_dict(e.response)) def list_target_groups(connection, module): @@ -275,9 +276,9 @@ def list_target_groups(connection, module): 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)) + module.fail_json(msg=to_native(e), exception=traceback.format_exc(), **camel_dict_to_snake_dict(e.response)) 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 12dae087a70..a418c7425f1 100644 --- a/plugins/modules/iam_mfa_device_info.py +++ b/plugins/modules/iam_mfa_device_info.py @@ -70,6 +70,7 @@ HAS_BOTO3 = False from ansible.module_utils.basic import AnsibleModule +from ansible.module_utils._text import to_native from ansible_collections.amazon.aws.plugins.module_utils.ec2 import (HAS_BOTO3, boto3_conn, camel_dict_to_snake_dict, @@ -88,7 +89,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(msg=to_native(e), **camel_dict_to_snake_dict(e.response)) module.exit_json(changed=changed, **camel_dict_to_snake_dict(response)) diff --git a/plugins/modules/lambda.py b/plugins/modules/lambda.py index cad268c72ae..0ccb32fa6f0 100644 --- a/plugins/modules/lambda.py +++ b/plugins/modules/lambda.py @@ -253,7 +253,7 @@ def get_account_info(module, region=None, endpoint=None, **aws_connect_kwargs): arn, partition, service, reg, account_id, resource = iam_client.get_user()['User']['Arn'].split(':') except ClientError as e: if (e.response['Error']['Code'] == 'AccessDenied'): - except_msg = to_native(e.message) + except_msg = to_native(e) m = except_msg.search(r"arn:(aws(-([a-z\-]+))?):iam::([0-9]{12,32}):\w+/") account_id = m.group(4) partition = m.group(1) diff --git a/plugins/modules/rds.py b/plugins/modules/rds.py index 1ac4a1b15ad..b43b036c4e0 100644 --- a/plugins/modules/rds.py +++ b/plugins/modules/rds.py @@ -539,6 +539,7 @@ HAS_RDS2 = False from ansible.module_utils.basic import AnsibleModule +from ansible.module_utils._text import to_native from ansible_collections.amazon.aws.plugins.module_utils.ec2 import AWSRetry from ansible_collections.amazon.aws.plugins.module_utils.ec2 import HAS_BOTO, connect_to_aws, ec2_argument_spec, get_aws_connection_info @@ -987,7 +988,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) @@ -1014,7 +1015,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) @@ -1053,7 +1054,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 @@ -1066,7 +1067,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)) @@ -1103,7 +1104,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 @@ -1141,7 +1142,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 @@ -1166,7 +1167,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) @@ -1191,7 +1192,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) @@ -1222,7 +1223,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 b13e5eea086..4524f63b486 100644 --- a/plugins/modules/s3_logging.py +++ b/plugins/modules/s3_logging.py @@ -71,6 +71,7 @@ HAS_BOTO = False from ansible.module_utils.basic import AnsibleModule +from ansible.module_utils._text import to_native from ansible_collections.amazon.aws.plugins.module_utils.ec2 import AnsibleAWSError, ec2_argument_spec, get_aws_connection_info @@ -93,7 +94,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): @@ -104,14 +105,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) @@ -127,7 +128,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 1c87ed73ba8..ca37d1474f5 100644 --- a/plugins/modules/s3_website.py +++ b/plugins/modules/s3_website.py @@ -173,6 +173,7 @@ HAS_BOTO3 = False from ansible.module_utils.basic import AnsibleModule +from ansible.module_utils._text import to_native from ansible_collections.amazon.aws.plugins.module_utils.ec2 import (HAS_BOTO3, boto3_conn, camel_dict_to_snake_dict, @@ -229,7 +230,7 @@ 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(msg=to_native(e), **camel_dict_to_snake_dict(e.response)) try: website_config = client_connection.get_bucket_website(Bucket=bucket_name) @@ -237,14 +238,14 @@ def enable_or_update_bucket_as_website(client_connection, resource_connection, m if e.response['Error']['Code'] == 'NoSuchWebsiteConfiguration': website_config = None else: - module.fail_json(msg=e.message, **camel_dict_to_snake_dict(e.response)) + module.fail_json(msg=to_native(e), **camel_dict_to_snake_dict(e.response)) 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(msg=to_native(e), **camel_dict_to_snake_dict(e.response)) except ValueError as e: module.fail_json(msg=str(e)) else: @@ -257,13 +258,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(msg=to_native(e), **camel_dict_to_snake_dict(e.response)) 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(msg=to_native(e), **camel_dict_to_snake_dict(e.response)) except ValueError as e: module.fail_json(msg=str(e)) @@ -285,13 +286,13 @@ def disable_bucket_as_website(client_connection, module): 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)) + module.fail_json(msg=to_native(e), **camel_dict_to_snake_dict(e.response)) 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(msg=to_native(e), **camel_dict_to_snake_dict(e.response)) module.exit_json(changed=changed) From e6063996e6c6ec241d2a3475ca994bcfa6163511 Mon Sep 17 00:00:00 2001 From: Vincent Vinet Date: Tue, 28 Jul 2020 07:59:31 -0400 Subject: [PATCH 2/5] PR comment changes, use fail_json_aws and is_boto3_error_code --- plugins/modules/ec2_vpc_endpoint.py | 20 ++++++++------------ plugins/modules/ecs_taskdefinition.py | 3 +-- 2 files changed, 9 insertions(+), 14 deletions(-) diff --git a/plugins/modules/ec2_vpc_endpoint.py b/plugins/modules/ec2_vpc_endpoint.py index 7909c63037b..8a8675fcbea 100644 --- a/plugins/modules/ec2_vpc_endpoint.py +++ b/plugins/modules/ec2_vpc_endpoint.py @@ -197,6 +197,7 @@ HAS_BOTO3, camel_dict_to_snake_dict, ) +from ansible_collections.amazon.aws.plugins.module_utils.aws.core import is_boto3_error_code from ansible.module_utils.six import string_types @@ -296,18 +297,13 @@ 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: - message = to_native(e) - if "DryRunOperation" in message: - changed = True - result = 'Would have created VPC Endpoint if not in check mode' - elif "IdempotentParameterMismatch" in message: - module.fail_json(msg="IdempotentParameterMismatch - updates of endpoints are not allowed by the API") - elif "RouteAlreadyExists" in message: - module.fail_json(msg="RouteAlreadyExists for one of the route tables - update is not allowed by the API") - else: - module.fail_json(msg=message, 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'): + module.fail_json(msg="IdempotentParameterMismatch - updates of endpoints are not allowed by the API") + except is_boto3_error_code('RouteAlreadyExists'): + 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=to_native(e), exception=traceback.format_exc(), **camel_dict_to_snake_dict(e.response)) diff --git a/plugins/modules/ecs_taskdefinition.py b/plugins/modules/ecs_taskdefinition.py index d2a9e433cca..493787daee1 100644 --- a/plugins/modules/ecs_taskdefinition.py +++ b/plugins/modules/ecs_taskdefinition.py @@ -217,7 +217,6 @@ pass # caught by AnsibleAWSModule from ansible_collections.amazon.aws.plugins.module_utils.aws.core import AnsibleAWSModule -from ansible_collections.amazon.aws.plugins.module_utils.ec2 import camel_dict_to_snake_dict from ansible.module_utils._text import to_text, to_native @@ -277,7 +276,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=to_native(e), **camel_dict_to_snake_dict(e.response)) + self.module.fail_json_aws(e, msg="Failed to register task") return response['taskDefinition'] From f95132e32de7ae6e8d885b16b9c02f4d0001b2b2 Mon Sep 17 00:00:00 2001 From: Vincent Vinet Date: Fri, 14 Aug 2020 10:02:57 -0400 Subject: [PATCH 3/5] fix moved import --- plugins/modules/ec2_vpc_endpoint.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/modules/ec2_vpc_endpoint.py b/plugins/modules/ec2_vpc_endpoint.py index 043fbe39fb0..e92ac95362a 100644 --- a/plugins/modules/ec2_vpc_endpoint.py +++ b/plugins/modules/ec2_vpc_endpoint.py @@ -193,7 +193,7 @@ HAS_BOTO3, camel_dict_to_snake_dict, ) -from ansible_collections.amazon.aws.plugins.module_utils.aws.core import is_boto3_error_code +from ansible_collections.amazon.aws.plugins.module_utils.core import is_boto3_error_code from ansible.module_utils.six import string_types From dfad54414ef7b98d5c55c4959307e615d3dd3e80 Mon Sep 17 00:00:00 2001 From: Mark Chappell Date: Sat, 15 Aug 2020 13:06:02 +0200 Subject: [PATCH 4/5] Add missing import for is_boto3_error_code --- plugins/modules/ec2_vpc_endpoint.py | 1 + 1 file changed, 1 insertion(+) diff --git a/plugins/modules/ec2_vpc_endpoint.py b/plugins/modules/ec2_vpc_endpoint.py index d9c5737b6fb..72b2ad581e7 100644 --- a/plugins/modules/ec2_vpc_endpoint.py +++ b/plugins/modules/ec2_vpc_endpoint.py @@ -189,6 +189,7 @@ 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 From aaa3326ef502eb71ec42f92bb0d50a3278d4d9b6 Mon Sep 17 00:00:00 2001 From: Mark Chappell Date: Sat, 15 Aug 2020 13:20:00 +0200 Subject: [PATCH 5/5] Ignore linting warnings caused by is_boto3_error_code --- plugins/modules/ec2_vpc_endpoint.py | 6 +++--- plugins/modules/ec2_vpc_nat_gateway.py | 2 +- plugins/modules/elb_application_lb_info.py | 2 +- plugins/modules/elb_target_group_info.py | 2 +- plugins/modules/s3_website.py | 4 ++-- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/plugins/modules/ec2_vpc_endpoint.py b/plugins/modules/ec2_vpc_endpoint.py index 72b2ad581e7..3eaf2850e6e 100644 --- a/plugins/modules/ec2_vpc_endpoint.py +++ b/plugins/modules/ec2_vpc_endpoint.py @@ -294,9 +294,9 @@ def create_vpc_endpoint(client, module): 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'): + 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'): + 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=to_native(e), exception=traceback.format_exc(), @@ -320,7 +320,7 @@ def setup_removal(client, module): 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: + 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=to_native(e), exception=traceback.format_exc(), diff --git a/plugins/modules/ec2_vpc_nat_gateway.py b/plugins/modules/ec2_vpc_nat_gateway.py index 13362ef13d2..37dd9160084 100644 --- a/plugins/modules/ec2_vpc_nat_gateway.py +++ b/plugins/modules/ec2_vpc_nat_gateway.py @@ -707,7 +707,7 @@ def create(client, subnet_id, allocation_id, client_token=None, success = False changed = False result = None - except botocore.exceptions.ClientError as e: + except botocore.exceptions.ClientError as e: # pylint: disable=duplicate-except err_msg = to_native(e) success = False changed = False diff --git a/plugins/modules/elb_application_lb_info.py b/plugins/modules/elb_application_lb_info.py index 9c249c9d8b3..1ed3d4c7cd2 100644 --- a/plugins/modules/elb_application_lb_info.py +++ b/plugins/modules/elb_application_lb_info.py @@ -233,7 +233,7 @@ def list_load_balancers(connection, module): load_balancers = load_balancer_paginator.paginate(Names=names).build_full_result() except is_boto3_error_code('LoadBalancerNotFound'): module.exit_json(load_balancers=[]) - except ClientError as e: + 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. " + to_native(e), exception=traceback.format_exc()) diff --git a/plugins/modules/elb_target_group_info.py b/plugins/modules/elb_target_group_info.py index ecbc8fd144d..c444521d887 100644 --- a/plugins/modules/elb_target_group_info.py +++ b/plugins/modules/elb_target_group_info.py @@ -271,7 +271,7 @@ def list_target_groups(connection, module): target_groups = target_group_paginator.paginate(Names=names).build_full_result() except is_boto3_error_code('TargetGroupNotFound'): module.exit_json(target_groups=[]) - except ClientError as e: + except ClientError as e: # pylint: disable=duplicate-except module.fail_json_aws(e, msg="Failed to list target groups") except NoCredentialsError as e: module.fail_json(msg="AWS authentication problem. " + to_native(e), exception=traceback.format_exc()) diff --git a/plugins/modules/s3_website.py b/plugins/modules/s3_website.py index 1661c41f52b..a281f60f37e 100644 --- a/plugins/modules/s3_website.py +++ b/plugins/modules/s3_website.py @@ -228,7 +228,7 @@ def enable_or_update_bucket_as_website(client_connection, resource_connection, m website_config = client_connection.get_bucket_website(Bucket=bucket_name) except is_boto3_error_code('NoSuchWebsiteConfiguration'): website_config = None - except ClientError as e: + except ClientError as e: # pylint: disable=duplicate-except module.fail_json_aws(e, msg="Failed to get website configuration") if website_config is None: @@ -275,7 +275,7 @@ def disable_bucket_as_website(client_connection, module): client_connection.get_bucket_website(Bucket=bucket_name) except is_boto3_error_code('NoSuchWebsiteConfiguration'): module.exit_json(changed=changed) - except ClientError as e: + except ClientError as e: # pylint: disable=duplicate-except module.fail_json_aws(e, msg="Failed to get bucket website") try: