Skip to content

Commit

Permalink
AnsibleAWSModule add 'region' method (ansible#66988)
Browse files Browse the repository at this point in the history
* Add get_aws_region to module_utils.ec2 and region to AnsibleAWSModule

* Add example use

* Add changelog
  • Loading branch information
tremble authored Feb 21, 2020
1 parent 34800fe commit d74ed41
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 32 deletions.
2 changes: 2 additions & 0 deletions changelogs/fragments/66988-ansibleawsmodule-region.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
minor_changes:
- 'AnsibleAWSModule - Add a helper (region) so that modules which migrate to using module.client() can still access the region information'
7 changes: 6 additions & 1 deletion lib/ansible/module_utils/aws/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,8 @@

from ansible.module_utils.basic import AnsibleModule, missing_required_lib
from ansible.module_utils._text import to_native
from ansible.module_utils.ec2 import HAS_BOTO3, camel_dict_to_snake_dict, ec2_argument_spec, boto3_conn, get_aws_connection_info
from ansible.module_utils.ec2 import HAS_BOTO3, camel_dict_to_snake_dict, ec2_argument_spec, boto3_conn
from ansible.module_utils.ec2 import get_aws_connection_info, get_aws_region

# We will also export HAS_BOTO3 so end user modules can use it.
__all__ = ('AnsibleAWSModule', 'HAS_BOTO3', 'is_boto3_error_code')
Expand Down Expand Up @@ -189,6 +190,10 @@ def resource(self, service):
return boto3_conn(self, conn_type='resource', resource=service,
region=region, endpoint=ec2_url, **aws_connect_kwargs)

@property
def region(self, boto3=True):
return get_aws_region(self, boto3)

def fail_json_aws(self, exception, msg=None):
"""call fail_json with processed exception
Expand Down
60 changes: 34 additions & 26 deletions lib/ansible/module_utils/ec2.py
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,39 @@ def ec2_argument_spec():
return spec


def get_aws_region(module, boto3=False):
region = module.params.get('region')

if region:
return region

if 'AWS_REGION' in os.environ:
return os.environ['AWS_REGION']
if 'AWS_DEFAULT_REGION' in os.environ:
return os.environ['AWS_DEFAULT_REGION']
if 'EC2_REGION' in os.environ:
return os.environ['EC2_REGION']

if not boto3:
if not HAS_BOTO:
module.fail_json(msg=missing_required_lib('boto'), exception=BOTO_IMP_ERR)
# boto.config.get returns None if config not found
region = boto.config.get('Boto', 'aws_region')
if region:
return region
return boto.config.get('Boto', 'ec2_region')

if not HAS_BOTO3:
module.fail_json(msg=missing_required_lib('boto3'), exception=BOTO3_IMP_ERR)

# here we don't need to make an additional call, will default to 'us-east-1' if the below evaluates to None.
try:
profile_name = module.params.get('profile')
return botocore.session.Session(profile=profile_name).get_config_variable('region')
except botocore.exceptions.ProfileNotFound as e:
return None


def get_aws_connection_info(module, boto3=False):

# Check module args for credentials, then check environment vars
Expand All @@ -212,7 +245,7 @@ def get_aws_connection_info(module, boto3=False):
access_key = module.params.get('aws_access_key')
secret_key = module.params.get('aws_secret_key')
security_token = module.params.get('security_token')
region = module.params.get('region')
region = get_aws_region(module, boto3)
profile_name = module.params.get('profile')
validate_certs = module.params.get('validate_certs')
config = module.params.get('aws_config')
Expand Down Expand Up @@ -253,31 +286,6 @@ def get_aws_connection_info(module, boto3=False):
# in case secret_key came in as empty string
secret_key = None

if not region:
if 'AWS_REGION' in os.environ:
region = os.environ['AWS_REGION']
elif 'AWS_DEFAULT_REGION' in os.environ:
region = os.environ['AWS_DEFAULT_REGION']
elif 'EC2_REGION' in os.environ:
region = os.environ['EC2_REGION']
else:
if not boto3:
if HAS_BOTO:
# boto.config.get returns None if config not found
region = boto.config.get('Boto', 'aws_region')
if not region:
region = boto.config.get('Boto', 'ec2_region')
else:
module.fail_json(msg=missing_required_lib('boto'), exception=BOTO_IMP_ERR)
elif HAS_BOTO3:
# here we don't need to make an additional call, will default to 'us-east-1' if the below evaluates to None.
try:
region = botocore.session.Session(profile=profile_name).get_config_variable('region')
except botocore.exceptions.ProfileNotFound as e:
pass
else:
module.fail_json(msg=missing_required_lib('boto3'), exception=BOTO3_IMP_ERR)

if not security_token:
if os.environ.get('AWS_SECURITY_TOKEN'):
security_token = os.environ['AWS_SECURITY_TOKEN']
Expand Down
7 changes: 2 additions & 5 deletions lib/ansible/modules/cloud/amazon/ec2_vol_info.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@
pass # caught by AnsibleAWSModule

from ansible.module_utils.aws.core import AnsibleAWSModule
from ansible.module_utils.ec2 import AWSRetry, get_aws_connection_info
from ansible.module_utils.ec2 import AWSRetry
from ansible.module_utils.ec2 import boto3_tag_list_to_ansible_dict, ansible_dict_to_boto3_filter_list, camel_dict_to_snake_dict


Expand Down Expand Up @@ -119,12 +119,9 @@ def list_ec2_volumes(connection, module):
except ClientError as e:
module.fail_json_aws(e, msg="Failed to describe volumes.")

# We add region to the volume info so we need it here
region = get_aws_connection_info(module, boto3=True)[0]

for volume in all_volumes["Volumes"]:
volume = camel_dict_to_snake_dict(volume, ignore_list=['Tags'])
volume_dict_array.append(get_volume_info(volume, region))
volume_dict_array.append(get_volume_info(volume, module.region))
module.exit_json(volumes=volume_dict_array)


Expand Down

0 comments on commit d74ed41

Please sign in to comment.