Move profile and region checking to module_utils.ec2 (#31921)

* Move profile and region checking to module_utils.ec2

Remove ProfileNotFound checking from individual modules

There are plenty of `if not region:` checks that could be removed,
once more thorough testing of this change has occured

The ec2_asg, iam_managed_policy and ec2_vpc_subnet_facts modules
would also benefit from this change but as they do not have tests
and are marked stableinterface, they do not get this change.
This commit is contained in:
Will Thames 2017-11-08 04:56:17 +10:00 committed by Sloane Hertel
commit c93ddf5473
11 changed files with 37 additions and 65 deletions

View file

@ -129,13 +129,14 @@ To connect to AWS, you should use `get_aws_connection_info` and then `boto3_conn
These functions handle some of the more esoteric connection options, such as security tokens and
boto profiles.
Some boto services require that the region is specified. You should check for the region parameter
if required.
#### boto
An example of connecting to ec2:
Some boto services require that the region is specified. You should check for the region parameter
if required.
```python
region, ec2_url, aws_connect_params = get_aws_connection_info(module)
if region:
@ -153,13 +154,12 @@ An example of connecting to ec2 is shown below. Note that there is no `NoAuthHa
exception handling like in boto. Instead, an `AuthFailure` exception will be thrown when you use
'connection'. To ensure that authorization, parameter validation and permissions errors are all
caught, you should catch `ClientError` and `BotoCoreError` exceptions with every boto3 connection call.
See exception handling. module_utils.ec2 checks for missing profiles or a region not set when it needs to be,
so you don't have to.
```python
region, ec2_url, aws_connect_params = get_aws_connection_info(module, boto3=True)
if region:
connection = boto3_conn(module, conn_type='client', resource='ec2', region=region, endpoint=ec2_url, **aws_connect_params)
else:
module.fail_json(msg="region must be specified")
connection = boto3_conn(module, conn_type='client', resource='ec2', region=region, endpoint=ec2_url, **aws_connect_params)
```
### Exception Handling for boto

View file

@ -315,12 +315,9 @@ def main():
if not HAS_BOTO3:
module.fail_json('boto3 and botocore are required by this module')
try:
region, ec2_url, aws_connect_kwargs = get_aws_connection_info(module, boto3=True)
client = boto3_conn(module, conn_type='client', resource='acm',
region=region, endpoint=ec2_url, **aws_connect_kwargs)
except (botocore.exceptions.NoCredentialsError, botocore.exceptions.ProfileNotFound) as e:
module.fail_json(msg="Can't authorize connection - " + str(e))
region, ec2_url, aws_connect_kwargs = get_aws_connection_info(module, boto3=True)
client = boto3_conn(module, conn_type='client', resource='acm',
region=region, endpoint=ec2_url, **aws_connect_kwargs)
certificates = get_certificates(client, module, name=module.params['name'], statuses=module.params['statuses'])
module.exit_json(certificates=certificates)

View file

@ -671,10 +671,7 @@ def main():
if s3_url:
for key in ['validate_certs', 'security_token', 'profile_name']:
aws_connect_kwargs.pop(key, None)
try:
s3 = get_s3_connection(module, aws_connect_kwargs, location, rgw, s3_url)
except botocore.exceptions.ProfileNotFound as e:
module.fail_json(msg=to_native(e))
s3 = get_s3_connection(module, aws_connect_kwargs, location, rgw, s3_url)
validate = not ignore_nonexistent_bucket

View file

@ -90,16 +90,8 @@ def main():
# Set up connection
region, ec2_url, aws_connect_params = get_aws_connection_info(module, boto3=HAS_BOTO3)
# Set up connection
if region:
try:
connection = boto3_conn(module, conn_type='client', resource='s3', region=region, endpoint=ec2_url,
**aws_connect_params)
except (botocore.exceptions.NoCredentialsError, botocore.exceptions.ProfileNotFound) as e:
module.fail_json(msg=e.message, exception=traceback.format_exc(), **camel_dict_to_snake_dict(e.response))
else:
module.fail_json(msg="AWS region must be specified (like: us-east-1)")
connection = boto3_conn(module, conn_type='client', resource='s3', region=region, endpoint=ec2_url,
**aws_connect_params)
# Gather results
result['buckets'] = get_bucket_list(module, connection)

View file

@ -395,19 +395,11 @@ class CloudWatchEventRuleManager(object):
def get_cloudwatchevents_client(module):
"""Returns a boto3 client for accessing CloudWatch Events"""
try:
region, ec2_url, aws_conn_kwargs = get_aws_connection_info(module,
boto3=True)
if not region:
module.fail_json(msg="Region must be specified as a parameter, in \
EC2_REGION or AWS_REGION environment variables \
or in boto configuration file")
return boto3_conn(module, conn_type='client',
resource='events',
region=region, endpoint=ec2_url,
**aws_conn_kwargs)
except botocore.exceptions.ProfileNotFound as e:
module.fail_json(msg=str(e))
region, ec2_url, aws_conn_kwargs = get_aws_connection_info(module, boto3=True)
return boto3_conn(module, conn_type='client',
resource='events',
region=region, endpoint=ec2_url,
**aws_conn_kwargs)
def main():

View file

@ -680,11 +680,8 @@ def main():
changed = False
region, ec2_url, aws_connect_params = get_aws_connection_info(module, boto3=True)
if not region:
module.fail_json(msg="The AWS region must be specified as an "
"environment variable or in the AWS credentials "
"profile.")
client = boto3_conn(module, conn_type='client', resource='ec2', endpoint=ec2_url, region=region, **aws_connect_params)
client = boto3_conn(module, conn_type='client', resource='ec2',
endpoint=ec2_url, region=region, **aws_connect_params)
if not has_rule_description_attr(client):
all_rules = rules if rules else [] + rules_egress if rules_egress else []

View file

@ -113,7 +113,7 @@ from ansible.module_utils._text import to_native
try:
import boto3
from botocore.exceptions import ClientError, NoCredentialsError, ProfileNotFound, NoRegionError, WaiterError
from botocore.exceptions import ClientError, WaiterError
HAS_BOTO3 = True
except ImportError:
HAS_BOTO3 = False
@ -174,12 +174,8 @@ def main():
module.fail_json(msg='botocore and boto3 are required.')
region, ec2_url, aws_connect_kwargs = get_aws_connection_info(module, boto3=True)
if not region:
module.fail_json(msg="Region must be provided.")
try:
client = boto3_conn(module, conn_type='client', resource='ec2', region=region, endpoint=ec2_url, **aws_connect_kwargs)
except (NoCredentialsError, ProfileNotFound) as e:
module.fail_json(msg="Can't authorize connection - %s" % to_native(e))
client = boto3_conn(module, conn_type='client', resource='ec2',
region=region, endpoint=ec2_url, **aws_connect_kwargs)
copy_snapshot(module, client)

View file

@ -321,13 +321,9 @@ def main():
if not HAS_BOTO3:
module.fail_json(msg='boto3 is required.')
try:
region, ec2_url, aws_connect_kwargs = get_aws_connection_info(module, boto3=True)
if not region:
module.fail_json(msg="Region must be specified as a parameter, in EC2_REGION or AWS_REGION environment variables or in boto configuration file")
ecs = boto3_conn(module, conn_type='client', resource='ecs', region=region, endpoint=ec2_url, **aws_connect_kwargs)
except botocore.exceptions.ProfileNotFound as e:
module.fail_json(msg=str(e))
region, ec2_url, aws_connect_kwargs = get_aws_connection_info(module, boto3=True)
ecs = boto3_conn(module, conn_type='client', resource='ecs',
region=region, endpoint=ec2_url, **aws_connect_kwargs)
ecs_td = ecs.describe_task_definition(taskDefinition=module.params['task_definition'])['taskDefinition']
ecs_td_snake = {}