Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Python 3 compatibility error handling: use to_native(e) instead of str(e) or e.me… #26

Merged
merged 7 commits into from
Aug 15, 2020
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions plugins/modules/dynamodb_ttl.py
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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))

Expand Down
3 changes: 2 additions & 1 deletion plugins/modules/ec2_customer_gateway.py
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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):
Expand Down
3 changes: 2 additions & 1 deletion plugins/modules/ec2_instance_info.py
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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 = []
Expand Down
3 changes: 2 additions & 1 deletion plugins/modules/ec2_lc_info.py
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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']:
Expand Down
21 changes: 12 additions & 9 deletions plugins/modules/ec2_vpc_endpoint.py
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We have a helper function (is_boto3_error_code) which I think would be better here:

from ansible_collections.amazon.aws.plugins.module_utils.aws.core import is_boto3_error_code
    except is_boto3_error_code('DryRunOperation'):
        changed = True
        result = 'Would have created VPC Endpoint if not in check mode'
    except is_boto3_error_core('IdempotentParameterMismatch'):
        ...
    except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError as e):
        module.fail_json(msg=to_native(e), exception=traceback.format_exc(),

This avoids an additional level of nesting.

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
Expand All @@ -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

Expand Down Expand Up @@ -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")
Expand Down
3 changes: 2 additions & 1 deletion plugins/modules/ec2_vpc_endpoint_info.py
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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])


Expand Down
8 changes: 4 additions & 4 deletions plugins/modules/ec2_vpc_nat_gateway.py
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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
Expand Down
3 changes: 2 additions & 1 deletion plugins/modules/ec2_vpc_nat_gateway_info.py
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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
Expand Down
5 changes: 3 additions & 2 deletions plugins/modules/ec2_vpc_peering_info.py
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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']

Expand All @@ -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")
Expand Down
3 changes: 2 additions & 1 deletion plugins/modules/ec2_vpc_route_table_info.py
Original file line number Diff line number Diff line change
Expand Up @@ -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


Expand Down Expand Up @@ -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))
Expand Down
4 changes: 2 additions & 2 deletions plugins/modules/ecs_taskdefinition.py
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down Expand Up @@ -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))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This module is using AnsibleAWSModule, which means we have a 'fail' method which is much easier to use and avoids the need to for the extra import.

Suggested change
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']

Expand Down
11 changes: 6 additions & 5 deletions plugins/modules/elasticache.py
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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()
Expand Down Expand Up @@ -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']
Expand Down Expand Up @@ -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()
Expand Down Expand Up @@ -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()
Expand Down Expand Up @@ -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
Expand Down
3 changes: 2 additions & 1 deletion plugins/modules/elasticache_subnet_group.py
Original file line number Diff line number Diff line change
Expand Up @@ -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


Expand Down Expand Up @@ -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
Expand Down
13 changes: 7 additions & 6 deletions plugins/modules/elb_application_lb_info.py
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -186,23 +187,23 @@ 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):

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):

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()):
Expand All @@ -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):
Expand All @@ -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
Expand Down
Loading