mirror of https://github.com/ansible/ansible.git
[cloud] New a lookup plugin for AWS account attributes (#33025)
* Add a lookup plugin for AWS account attributes * PEP8 * Use config system instead of hard coding logic for environment variables * simplify logic * Return a flattened dict to make using easier * Reformat return examplepull/34053/head
parent
a3d65056db
commit
58adf1750e
@ -0,0 +1,165 @@
|
||||
# (c) 2017 Ansible Project
|
||||
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||
from __future__ import (absolute_import, division, print_function)
|
||||
__metaclass__ = type
|
||||
|
||||
DOCUMENTATION = """
|
||||
lookup: aws_account_attribute
|
||||
author:
|
||||
- Sloane Hertel <shertel@redhat.com>
|
||||
version_added: "2.5"
|
||||
requirements:
|
||||
- boto3
|
||||
- botocore
|
||||
short_description: Look up AWS account attributes.
|
||||
description:
|
||||
- Describes attributes of your AWS account. You can specify one of the listed
|
||||
attribute choices or omit it to see all attributes.
|
||||
options:
|
||||
attribute:
|
||||
description: The attribute for which to get the value(s).
|
||||
default: null
|
||||
choices:
|
||||
- supported-platforms
|
||||
- default-vpc
|
||||
- max-instances
|
||||
- vpc-max-security-groups-per-interface
|
||||
- max-elastic-ips
|
||||
- vpc-max-elastic-ips
|
||||
- has-ec2-classic
|
||||
boto_profile:
|
||||
description: The boto profile to use to create the connection.
|
||||
default: null
|
||||
env:
|
||||
- name: AWS_PROFILE
|
||||
- name: AWS_DEFAULT_PROFILE
|
||||
aws_access_key:
|
||||
description: The AWS access key to use.
|
||||
default: null
|
||||
env:
|
||||
- name: AWS_ACCESS_KEY_ID
|
||||
- name: AWS_ACCESS_KEY
|
||||
- name: EC2_ACCESS_KEY
|
||||
aws_secret_key:
|
||||
description: The AWS secret key that corresponds to the access key.
|
||||
default: null
|
||||
env:
|
||||
- name: AWS_SECRET_ACCESS_KEY
|
||||
- name: AWS_SECRET_KEY
|
||||
- name: EC2_SECRET_KEY
|
||||
aws_security_token:
|
||||
description: The AWS security token if using temporary access and secret keys.
|
||||
default: null
|
||||
env:
|
||||
- name: AWS_SECURITY_TOKEN
|
||||
- name: AWS_SESSION_TOKEN
|
||||
- name: EC2_SECURITY_TOKEN
|
||||
region:
|
||||
description: The region for which to create the connection.
|
||||
default: null
|
||||
env:
|
||||
- name: AWS_REGION
|
||||
- name: EC2_REGION
|
||||
"""
|
||||
|
||||
EXAMPLES = """
|
||||
vars:
|
||||
has_ec2_classic: "{{ lookup('aws_account_attribute', attribute='has-ec2-classic') }}"
|
||||
# true | false
|
||||
|
||||
default_vpc_id: "{{ lookup('aws_account_attribute', attribute='default-vpc') }}"
|
||||
# vpc-xxxxxxxx | none
|
||||
|
||||
account_details: "{{ lookup('aws_account_attribute', wantlist='true') }}"
|
||||
# {'default-vpc': ['vpc-xxxxxxxx'], 'max-elastic-ips': ['5'], 'max-instances': ['20'],
|
||||
# 'supported-platforms': ['VPC', 'EC2'], 'vpc-max-elastic-ips': ['5'], 'vpc-max-security-groups-per-interface': ['5']}
|
||||
|
||||
"""
|
||||
|
||||
RETURN = """
|
||||
_raw:
|
||||
description:
|
||||
Returns a boolean when I(attribute) is check_ec2_classic. Otherwise returns the value(s) of the attribute
|
||||
(or all attributes if one is not specified).
|
||||
"""
|
||||
|
||||
from ansible.errors import AnsibleError
|
||||
|
||||
try:
|
||||
import boto3
|
||||
import botocore
|
||||
except ImportError:
|
||||
raise AnsibleError("The lookup aws_account_attribute requires boto3 and botocore.")
|
||||
|
||||
from ansible.plugins import AnsiblePlugin
|
||||
from ansible.plugins.lookup import LookupBase
|
||||
from ansible.module_utils.ec2 import boto3_conn, get_aws_connection_info
|
||||
from ansible.module_utils._text import to_native
|
||||
from ansible.module_utils.six import string_types
|
||||
import os
|
||||
|
||||
|
||||
def _boto3_conn(region, credentials):
|
||||
if 'boto_profile' in credentials:
|
||||
boto_profile = credentials.pop('boto_profile')
|
||||
else:
|
||||
boto_profile = None
|
||||
|
||||
try:
|
||||
connection = boto3.session.Session(profile_name=boto_profile).client('ec2', region, **credentials)
|
||||
except (botocore.exceptions.ProfileNotFound, botocore.exceptions.PartialCredentialsError) as e:
|
||||
if boto_profile:
|
||||
try:
|
||||
connection = boto3.session.Session(profile_name=boto_profile).client('ec2', region)
|
||||
except (botocore.exceptions.ProfileNotFound, botocore.exceptions.PartialCredentialsError) as e:
|
||||
raise AnsibleError("Insufficient credentials found.")
|
||||
else:
|
||||
raise AnsibleError("Insufficient credentials found.")
|
||||
return connection
|
||||
|
||||
|
||||
def _get_credentials(options):
|
||||
credentials = {}
|
||||
credentials['boto_profile'] = options['boto_profile']
|
||||
credentials['aws_secret_access_key'] = options['aws_access_key']
|
||||
credentials['aws_access_key_id'] = options['aws_secret_key']
|
||||
credentials['aws_session_token'] = options['aws_security_token']
|
||||
|
||||
return credentials
|
||||
|
||||
|
||||
class LookupModule(LookupBase):
|
||||
def run(self, terms, variables, **kwargs):
|
||||
|
||||
self.set_options(var_options=variables, direct=kwargs)
|
||||
boto_credentials = _get_credentials(self._options)
|
||||
|
||||
region = self._options['region']
|
||||
client = _boto3_conn(region, boto_credentials)
|
||||
|
||||
attribute = kwargs.get('attribute')
|
||||
params = {'AttributeNames': []}
|
||||
check_ec2_classic = False
|
||||
if 'has-ec2-classic' == attribute:
|
||||
check_ec2_classic = True
|
||||
params['AttributeNames'] = ['supported-platforms']
|
||||
elif attribute:
|
||||
params['AttributeNames'] = [attribute]
|
||||
|
||||
try:
|
||||
response = client.describe_account_attributes(**params)['AccountAttributes']
|
||||
except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e:
|
||||
raise AnsibleError("Failed to describe account attributes: %s" % to_native(e))
|
||||
|
||||
if check_ec2_classic:
|
||||
attr = response[0]
|
||||
return any(value['AttributeValue'] == 'EC2' for value in attr['AttributeValues'])
|
||||
|
||||
if attribute:
|
||||
attr = response[0]
|
||||
return [value['AttributeValue'] for value in attr['AttributeValues']]
|
||||
|
||||
flattened = {}
|
||||
for k_v_dict in response:
|
||||
flattened[k_v_dict['AttributeName']] = [value['AttributeValue'] for value in k_v_dict['AttributeValues']]
|
||||
return flattened
|
Loading…
Reference in New Issue