amazon: extract copies of boto_exception to module_utils.ec2 (#20403)

* amazon: extract boto_exception to ec2 module

This function was copy/pasted throughout several Amazon modules. This
causes a consistency problem, since some improvements to message
formatting were applied to some modules but not others. Now all modules
use the same, improved function.

* Rebase and make requested changes

* Rebase and make requested changes
This commit is contained in:
David M. Lee 2017-08-23 10:40:32 -05:00 committed by Ryan Brown
parent 587ab33415
commit 1d4ca0fd51
10 changed files with 36 additions and 92 deletions

View file

@ -126,6 +126,23 @@ def _boto3_conn(conn_type=None, resource=None, region=None, endpoint=None, **par
boto3_inventory_conn = _boto3_conn boto3_inventory_conn = _boto3_conn
def boto_exception(err):
"""
Extracts the error message from a boto exception.
:param err: Exception from boto
:return: Error message
"""
if hasattr(err, 'error_message'):
error = err.error_message
elif hasattr(err, 'message'):
error = str(err.message) + ' ' + str(err) + ' - ' + str(type(err))
else:
error = '%s: %s' % (Exception, err)
return error
def aws_common_argument_spec(): def aws_common_argument_spec():
return dict( return dict(
ec2_url=dict(), ec2_url=dict(),

View file

@ -352,6 +352,21 @@ Ansible format, this function will convert the keys to snake_case.
Converts a an Ansible list of filters to a boto3 friendly list of dicts. This is useful for any Converts a an Ansible list of filters to a boto3 friendly list of dicts. This is useful for any
boto3 `_facts` modules. boto3 `_facts` modules.
### boto_exception
Pass an exception returned from boto or boto3, and this function will consistently get the message from the exception.
```
import traceback
from ansible.module_utils.ec2 import boto_exception
try:
...
except boto.exception.BotoServerError as err:
error_msg = boto_exception(err)
module.fail_json(msg=error_msg, exception=traceback.format_exc())
```
#### boto3_tag_list_to_ansible_dict #### boto3_tag_list_to_ansible_dict
Converts a boto3 tag list to an Ansible dict. Boto3 returns tags as a list of dicts containing keys Converts a boto3 tag list to an Ansible dict. Boto3 returns tags as a list of dicts containing keys

View file

@ -104,6 +104,7 @@ statement_label = {
# import module snippets # import module snippets
from ansible.module_utils.basic import AnsibleModule from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.ec2 import boto_exception
# import a class, we'll use a fully qualified path # import a class, we'll use a fully qualified path
import ansible.module_utils.ec2 import ansible.module_utils.ec2
@ -117,16 +118,6 @@ try:
except ImportError: except ImportError:
HAS_BOTO3 = False HAS_BOTO3 = False
def boto_exception(err):
'''generic error message handler'''
if hasattr(err, 'error_message'):
error = err.error_message
elif hasattr(err, 'message'):
error = str(err.message) + ' ' + str(err) + ' - ' + str(type(err))
else:
error = '%s: %s' % (Exception, err)
return error
def get_arn_from_kms_alias(kms, aliasname): def get_arn_from_kms_alias(kms, aliasname):
ret = kms.list_aliases() ret = kms.list_aliases()

View file

@ -245,22 +245,11 @@ except ImportError:
import ansible.module_utils.ec2 import ansible.module_utils.ec2
# import a class, otherwise we'll use a fully qualified path # import a class, otherwise we'll use a fully qualified path
from ansible.module_utils.ec2 import AWSRetry from ansible.module_utils.ec2 import AWSRetry, boto_exception
from ansible.module_utils.basic import AnsibleModule from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils._text import to_bytes from ansible.module_utils._text import to_bytes
def boto_exception(err):
'''generic error message handler'''
if hasattr(err, 'error_message'):
error = err.error_message
elif hasattr(err, 'message'):
error = err.message + ' ' + str(err) + ' - ' + str(type(err))
else:
error = '%s: %s' % (Exception, err)
return error
def get_stack_events(cfn, stack_name): def get_stack_events(cfn, stack_name):
'''This event data was never correct, it worked as a side effect. So the v2.3 format is different.''' '''This event data was never correct, it worked as a side effect. So the v2.3 format is different.'''

View file

@ -109,16 +109,6 @@ try:
except ImportError: except ImportError:
HAS_BOTO=False HAS_BOTO=False
def boto_exception(err):
'''generic error message handler'''
if hasattr(err, 'error_message'):
error = err.error_message
elif hasattr(err, 'message'):
error = err.message
else:
error = '%s: %s' % (Exception, err)
return error
def vpc_exists(module, vpc, name, cidr_block, multi): def vpc_exists(module, vpc, name, cidr_block, multi):
"""Returns None or a vpc object depending on the existence of a VPC. When supplied """Returns None or a vpc object depending on the existence of a VPC. When supplied

View file

@ -141,18 +141,6 @@ except ImportError:
HAS_BOTO3 = False HAS_BOTO3 = False
def boto_exception(err):
'''boto error message handler'''
if hasattr(err, 'error_message'):
error = err.error_message
elif hasattr(err, 'message'):
error = err.message
else:
error = '%s: %s' % (Exception, err)
return error
def build_kwargs(registry_id): def build_kwargs(registry_id):
""" """
Builds a kwargs dict which may contain the optional registryId. Builds a kwargs dict which may contain the optional registryId.

View file

@ -172,17 +172,6 @@ try:
except ImportError: except ImportError:
HAS_BOTO = False HAS_BOTO = False
def boto_exception(err):
'''generic error message handler'''
if hasattr(err, 'error_message'):
error = err.error_message
elif hasattr(err, 'message'):
error = err.message
else:
error = '%s: %s' % (Exception, err)
return error
def _paginate(func, attr): def _paginate(func, attr):
''' '''

View file

@ -120,18 +120,6 @@ except ImportError:
HAS_BOTO = False HAS_BOTO = False
def boto_exception(err):
'''generic error message handler'''
if hasattr(err, 'error_message'):
error = err.error_message
elif hasattr(err, 'message'):
error = err.message
else:
error = '%s: %s' % (Exception, err)
return error
def cert_meta(iam, name): def cert_meta(iam, name):
certificate = iam.get_server_certificate(name).get_server_certificate_result.server_certificate certificate = iam.get_server_certificate(name).get_server_certificate_result.server_certificate
ocert = certificate.certificate_body ocert = certificate.certificate_body

View file

@ -129,22 +129,10 @@ except ImportError:
HAS_BOTO = False HAS_BOTO = False
from ansible.module_utils.basic import AnsibleModule from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.ec2 import connect_to_aws, ec2_argument_spec, get_aws_connection_info from ansible.module_utils.ec2 import connect_to_aws, ec2_argument_spec, get_aws_connection_info, boto_exception
from ansible.module_utils.six import string_types from ansible.module_utils.six import string_types
def boto_exception(err):
'''generic error message handler'''
if hasattr(err, 'error_message'):
error = err.error_message
elif hasattr(err, 'message'):
error = err.message
else:
error = '%s: %s' % (Exception, err)
return error
def user_action(module, iam, name, policy_name, skip, pdoc, state): def user_action(module, iam, name, policy_name, skip, pdoc, state):
policy_match = False policy_match = False
changed = False changed = False

View file

@ -207,7 +207,7 @@ from dateutil import tz
# import module snippets # import module snippets
from ansible.module_utils.basic import AnsibleModule from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.ec2 import camel_dict_to_snake_dict, ec2_argument_spec, boto3_conn, get_aws_connection_info, HAS_BOTO3 from ansible.module_utils.ec2 import camel_dict_to_snake_dict, ec2_argument_spec, boto3_conn, get_aws_connection_info, HAS_BOTO3, boto_exception
try: try:
@ -217,17 +217,6 @@ except ImportError:
pass pass
def boto_exception(err):
'''generic error message handler'''
if hasattr(err, 'error_message'):
error = err.error_message
elif hasattr(err, 'message'):
error = str(err.message) + ' ' + str(err) + ' - ' + str(type(err))
else:
error = '%s: %s' % (Exception, err)
return error
# the following function, calculate_multipart_etag, is from tlastowka # the following function, calculate_multipart_etag, is from tlastowka
# on github and is used under its (compatible) GPL license. So this # on github and is used under its (compatible) GPL license. So this
# license applies to the following function. # license applies to the following function.