mirror of
https://github.com/ansible-collections/community.general.git
synced 2025-05-02 23:31:25 -07:00
Unclear how useful it is to still be catching BotoServerError exceptions generally, especially when we are now hopefully handling most instances of throttling, but kept it as it was already in the code. Moved to main as catching BotoServerErrors inside individual functions will bypass any AWSRetry.backoff decorator. Move additional imports to top. Use python2.6 formatting A bit of cleanup on imports Make one more string interpolation Python 2.6 compatible.
270 lines
8.5 KiB
Python
270 lines
8.5 KiB
Python
#!/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 <http://www.gnu.org/licenses/>.
|
|
|
|
ANSIBLE_METADATA = {'status': ['preview'],
|
|
'supported_by': 'community',
|
|
'version': '1.0'}
|
|
|
|
DOCUMENTATION = '''
|
|
---
|
|
module: ec2_elb_facts
|
|
short_description: Gather facts about EC2 Elastic Load Balancers in AWS
|
|
description:
|
|
- Gather facts about EC2 Elastic Load Balancers in AWS
|
|
version_added: "2.0"
|
|
author:
|
|
- "Michael Schultz (github.com/mjschultz)"
|
|
- "Fernando Jose Pando (@nand0p)"
|
|
options:
|
|
names:
|
|
description:
|
|
- List of ELB names to gather facts about. Pass this option to gather facts about a set of ELBs, otherwise, all ELBs are returned.
|
|
required: false
|
|
default: null
|
|
aliases: ['elb_ids', 'ec2_elbs']
|
|
extends_documentation_fragment:
|
|
- aws
|
|
- ec2
|
|
'''
|
|
|
|
EXAMPLES = '''
|
|
# Note: These examples do not set authentication details, see the AWS Guide for details.
|
|
# Output format tries to match ec2_elb_lb module input parameters
|
|
|
|
# Gather facts about all ELBs
|
|
- action:
|
|
module: ec2_elb_facts
|
|
register: elb_facts
|
|
|
|
- action:
|
|
module: debug
|
|
msg: "{{ item.dns_name }}"
|
|
with_items: "{{ elb_facts.elbs }}"
|
|
|
|
# Gather facts about a particular ELB
|
|
- action:
|
|
module: ec2_elb_facts
|
|
names: frontend-prod-elb
|
|
register: elb_facts
|
|
|
|
- action:
|
|
module: debug
|
|
msg: "{{ elb_facts.elbs.0.dns_name }}"
|
|
|
|
# Gather facts about a set of ELBs
|
|
- action:
|
|
module: ec2_elb_facts
|
|
names:
|
|
- frontend-prod-elb
|
|
- backend-prod-elb
|
|
register: elb_facts
|
|
|
|
- action:
|
|
module: debug
|
|
msg: "{{ item.dns_name }}"
|
|
with_items: "{{ elb_facts.elbs }}"
|
|
|
|
'''
|
|
|
|
import traceback
|
|
|
|
from ansible.module_utils.basic import AnsibleModule
|
|
from ansible.module_utils.ec2 import (
|
|
AWSRetry,
|
|
connect_to_aws,
|
|
ec2_argument_spec,
|
|
get_aws_connection_info,
|
|
)
|
|
|
|
try:
|
|
import boto.ec2.elb
|
|
from boto.ec2.tag import Tag
|
|
from boto.exception import BotoServerError
|
|
HAS_BOTO = True
|
|
except ImportError:
|
|
HAS_BOTO = False
|
|
|
|
|
|
class ElbInformation(object):
|
|
"""Handles ELB information."""
|
|
|
|
def __init__(self,
|
|
module,
|
|
names,
|
|
region,
|
|
**aws_connect_params):
|
|
|
|
self.module = module
|
|
self.names = names
|
|
self.region = region
|
|
self.aws_connect_params = aws_connect_params
|
|
self.connection = self._get_elb_connection()
|
|
|
|
def _get_tags(self, elbname):
|
|
params = {'LoadBalancerNames.member.1': elbname}
|
|
elb_tags = self.connection.get_list('DescribeTags', params, [('member', Tag)])
|
|
return dict((tag.Key, tag.Value) for tag in elb_tags if hasattr(tag, 'Key'))
|
|
|
|
@AWSRetry.backoff(tries=5, delay=5, backoff=2.0)
|
|
def _get_elb_connection(self):
|
|
return connect_to_aws(boto.ec2.elb, self.region, **self.aws_connect_params)
|
|
|
|
def _get_elb_listeners(self, listeners):
|
|
listener_list = []
|
|
|
|
for listener in listeners:
|
|
listener_dict = {
|
|
'load_balancer_port': listener[0],
|
|
'instance_port': listener[1],
|
|
'protocol': listener[2],
|
|
}
|
|
|
|
try:
|
|
ssl_certificate_id = listener[4]
|
|
except IndexError:
|
|
pass
|
|
else:
|
|
if ssl_certificate_id:
|
|
listener_dict['ssl_certificate_id'] = ssl_certificate_id
|
|
|
|
listener_list.append(listener_dict)
|
|
|
|
return listener_list
|
|
|
|
def _get_health_check(self, health_check):
|
|
protocol, port_path = health_check.target.split(':')
|
|
try:
|
|
port, path = port_path.split('/', 1)
|
|
path = '/{0}'.format(path)
|
|
except ValueError:
|
|
port = port_path
|
|
path = None
|
|
|
|
health_check_dict = {
|
|
'ping_protocol': protocol.lower(),
|
|
'ping_port': int(port),
|
|
'response_timeout': health_check.timeout,
|
|
'interval': health_check.interval,
|
|
'unhealthy_threshold': health_check.unhealthy_threshold,
|
|
'healthy_threshold': health_check.healthy_threshold,
|
|
}
|
|
|
|
if path:
|
|
health_check_dict['ping_path'] = path
|
|
return health_check_dict
|
|
|
|
@AWSRetry.backoff(tries=5, delay=5, backoff=2.0)
|
|
def _get_elb_info(self, elb):
|
|
elb_info = {
|
|
'name': elb.name,
|
|
'zones': elb.availability_zones,
|
|
'dns_name': elb.dns_name,
|
|
'canonical_hosted_zone_name': elb.canonical_hosted_zone_name,
|
|
'canonical_hosted_zone_name_id': elb.canonical_hosted_zone_name_id,
|
|
'hosted_zone_name': elb.canonical_hosted_zone_name,
|
|
'hosted_zone_id': elb.canonical_hosted_zone_name_id,
|
|
'instances': [instance.id for instance in elb.instances],
|
|
'listeners': self._get_elb_listeners(elb.listeners),
|
|
'scheme': elb.scheme,
|
|
'security_groups': elb.security_groups,
|
|
'health_check': self._get_health_check(elb.health_check),
|
|
'subnets': elb.subnets,
|
|
'instances_inservice': [],
|
|
'instances_inservice_count': 0,
|
|
'instances_outofservice': [],
|
|
'instances_outofservice_count': 0,
|
|
'instances_inservice_percent': 0.0,
|
|
'tags': self._get_tags(elb.name)
|
|
}
|
|
|
|
if elb.vpc_id:
|
|
elb_info['vpc_id'] = elb.vpc_id
|
|
|
|
if elb.instances:
|
|
instance_health = self.connection.describe_instance_health(elb.name)
|
|
elb_info['instances_inservice'] = [inst.instance_id for inst in instance_health if inst.state == 'InService']
|
|
elb_info['instances_inservice_count'] = len(elb_info['instances_inservice'])
|
|
elb_info['instances_outofservice'] = [inst.instance_id for inst in instance_health if inst.state == 'OutOfService']
|
|
elb_info['instances_outofservice_count'] = len(elb_info['instances_outofservice'])
|
|
try:
|
|
elb_info['instances_inservice_percent'] = (
|
|
float(elb_info['instances_inservice_count']) /
|
|
float(elb_info['instances_inservice_count'] + elb_info['instances_outofservice_count'])
|
|
) * 100.
|
|
except ZeroDivisionError:
|
|
elb_info['instances_inservice_percent'] = 0.
|
|
return elb_info
|
|
|
|
|
|
def list_elbs(self):
|
|
elb_array, token = [], None
|
|
|
|
while True:
|
|
all_elbs = AWSRetry.backoff(tries=5, delay=5, backoff=2.0)(self.connection.get_all_load_balancers)(marker=token)
|
|
token = all_elbs.next_token
|
|
|
|
if all_elbs:
|
|
if self.names:
|
|
for existing_lb in all_elbs:
|
|
if existing_lb.name in self.names:
|
|
elb_array.append(existing_lb)
|
|
else:
|
|
elb_array.extend(all_elbs)
|
|
else:
|
|
break
|
|
|
|
if token is None:
|
|
break
|
|
|
|
return list(map(self._get_elb_info, elb_array))
|
|
|
|
|
|
def main():
|
|
argument_spec = ec2_argument_spec()
|
|
argument_spec.update(dict(
|
|
names={'default': [], 'type': 'list'}
|
|
)
|
|
)
|
|
module = AnsibleModule(argument_spec=argument_spec,
|
|
supports_check_mode=True)
|
|
|
|
if not HAS_BOTO:
|
|
module.fail_json(msg='boto required for this module')
|
|
|
|
try:
|
|
|
|
region, ec2_url, aws_connect_params = get_aws_connection_info(module)
|
|
|
|
if not region:
|
|
module.fail_json(msg="region must be specified")
|
|
|
|
names = module.params['names']
|
|
elb_information = ElbInformation(module,
|
|
names,
|
|
region,
|
|
**aws_connect_params)
|
|
|
|
ec2_facts_result = dict(changed=False,
|
|
elbs=elb_information.list_elbs())
|
|
|
|
except BotoServerError as err:
|
|
self.module.fail_json(msg="{0}: {1}".format(err.error_code, err.error_message),
|
|
exception=traceback.format_exc())
|
|
|
|
module.exit_json(**ec2_facts_result)
|
|
|
|
|
|
if __name__ == '__main__':
|
|
main()
|