From 627179b79ee304669c5dd46fc5d638f7e38b5830 Mon Sep 17 00:00:00 2001 From: Michael Schuett Date: Fri, 24 Jul 2015 17:48:44 -0400 Subject: [PATCH] ec2_search module This module lets you get information about any number of ec2 instances in your environment. It also has the option of creating hostnames based on the ip of your server. --- .../modules/extras/cloud/amazon/ec2_search.py | 152 ++++++++++++++++++ 1 file changed, 152 insertions(+) create mode 100644 lib/ansible/modules/extras/cloud/amazon/ec2_search.py diff --git a/lib/ansible/modules/extras/cloud/amazon/ec2_search.py b/lib/ansible/modules/extras/cloud/amazon/ec2_search.py new file mode 100644 index 0000000000..b6ce223b15 --- /dev/null +++ b/lib/ansible/modules/extras/cloud/amazon/ec2_search.py @@ -0,0 +1,152 @@ +#!/usr/bin/python +# +# This is a free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This Ansible library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this library. If not, see . + +DOCUMENTATION = ''' +--- +module: ec2_search +short_description: ask EC2 for information about other instances. +description: + - Only supports seatch for hostname by tags currently. Looking to add more later. +version_added: "1.9" +options: + key: + description: + - instance tag key in EC2 + required: false + default: Name + aliases: [] + value: + description: + - instance tag value in EC2 + required: false + default: null + aliases: [] + lookup: + description: + - What type of lookup to use when searching EC2 instance info. + required: false + default: tags + aliases: [] + region: + description: + - EC2 region that it should look for tags in + required: false + default: All Regions + aliases: [] +author: + - "Michael Schuett (@michaeljs1990)" +extends_documentation_fragment: aws +''' + +EXAMPLES = ''' +# Note: These examples do not set authentication details, see the AWS Guide for details. + +# Basic provisioning example +- ec2_search: + key: mykey + value: myvalue + +''' +try: + import boto + import boto.ec2 + HAS_BOTO = True +except ImportError: + HAS_BOTO = False + +def todict(obj, classkey=None): + if isinstance(obj, dict): + data = {} + for (k, v) in obj.items(): + data[k] = todict(v, classkey) + return data + elif hasattr(obj, "_ast"): + return todict(obj._ast()) + elif hasattr(obj, "__iter__"): + return [todict(v, classkey) for v in obj] + elif hasattr(obj, "__dict__"): + # This Class causes a recursive loop and at this time is not worth + # debugging. If it's useful later I'll look into it. + if not isinstance(obj, boto.ec2.blockdevicemapping.BlockDeviceType): + data = dict([(key, todict(value, classkey)) + for key, value in obj.__dict__.iteritems() + if not callable(value) and not key.startswith('_')]) + if classkey is not None and hasattr(obj, "__class__"): + data[classkey] = obj.__class__.__name__ + return data + else: + return obj + +def get_all_ec2_regions(module): + try: + regions = boto.ec2.regions() + except Exception, e: + module.fail_json('Boto authentication issue: %s' % e) + + return regions + +# Connect to ec2 region +def connect_to_region(region, module): + try: + conn = boto.ec2.connect_to_region(region.name) + except Exception, e: + print module.jsonify('error connecting to region: ' + region.name) + conn = None + # connect_to_region will fail "silently" by returning + # None if the region name is wrong or not supported + return conn + +def main(): + module = AnsibleModule( + argument_spec = dict( + key = dict(default='Name'), + value = dict(), + lookup = dict(default='tags'), + ignore_state = dict(default='terminated'), + region = dict(), + ) + ) + + if not HAS_BOTO: + module.fail_json(msg='boto required for this module') + + server_info = list() + + for region in get_all_ec2_regions(module): + conn = connect_to_region(region, module) + try: + # Run when looking up by tag names, only returning hostname currently + if module.params.get('lookup') == 'tags': + ec2_key = 'tag:' + module.params.get('key') + ec2_value = module.params.get('value') + reservations = conn.get_all_instances(filters={ec2_key : ec2_value}) + for instance in [i for r in reservations for i in r.instances]: + if instance.private_ip_address != None: + instance.hostname = 'ip-' + instance.private_ip_address.replace('.', '-') + if instance._state.name not in module.params.get('ignore_state') and : + server_info.append(todict(instance)) + except: + print module.jsonify('error getting instances from: ' + region.name) + + ansible_facts = {'info': server_info} + ec2_facts_result = dict(changed=True, ec2=ansible_facts) + + module.exit_json(**ec2_facts_result) + +# import module snippets +from ansible.module_utils.basic import * +from ansible.module_utils.ec2 import * + +main()