From f8d027b1ba2acaec4383362b50272c748505a321 Mon Sep 17 00:00:00 2001 From: Rob Date: Thu, 15 Jun 2017 02:22:50 +1000 Subject: [PATCH] [cloud] New module elb_target_group_facts (#24583) --- .../cloud/amazon/elb_target_group_facts.py | 274 ++++++++++++++++++ 1 file changed, 274 insertions(+) create mode 100644 lib/ansible/modules/cloud/amazon/elb_target_group_facts.py diff --git a/lib/ansible/modules/cloud/amazon/elb_target_group_facts.py b/lib/ansible/modules/cloud/amazon/elb_target_group_facts.py new file mode 100644 index 00000000000000..f27d90f0e24f09 --- /dev/null +++ b/lib/ansible/modules/cloud/amazon/elb_target_group_facts.py @@ -0,0 +1,274 @@ +#!/usr/bin/python +# This file is part of Ansible +# +# Ansible is 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. +# +# Ansible 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 Ansible. If not, see . + +ANSIBLE_METADATA = {'metadata_version': '1.0', + 'status': ['preview'], + 'supported_by': 'community'} + +DOCUMENTATION = ''' +--- +module: elb_target_group_facts +short_description: Gather facts about ELB target groups in AWS +description: + - Gather facts about ELB target groups in AWS +version_added: "2.4" +author: Rob White (@wimnat) +options: + load_balancer_arn: + description: + - The Amazon Resource Name (ARN) of the load balancer. + required: false + target_group_arns: + description: + - The Amazon Resource Names (ARN) of the target groups. + required: false + names: + description: + - The names of the target groups. + required: false + +extends_documentation_fragment: + - aws + - ec2 +''' + +EXAMPLES = ''' +# Note: These examples do not set authentication details, see the AWS Guide for details. + +# Gather facts about all target groups +- elb_target_group_facts: + +# Gather facts about the target group attached to a particular ELB +- elb_target_group_facts: + load_balancer_arn: "arn:aws:elasticloadbalancing:ap-southeast-2:001122334455:loadbalancer/app/my-elb/aabbccddeeff" + +# Gather facts about a target groups named 'tg1' and 'tg2' +- elb_target_group_facts: + names: + - tg1 + - tg2 + +''' + +RETURN = ''' +target_groups: + description: a list of target groups + returned: always + type: complex + contains: + deregistration_delay_timeout_seconds: + description: The amount time for Elastic Load Balancing to wait before changing the state of a deregistering target from draining to unused. + returned: always + type: int + sample: 300 + health_check_interval_seconds: + description: The approximate amount of time, in seconds, between health checks of an individual target. + returned: always + type: int + sample: 30 + health_check_path: + description: The destination for the health check request. + returned: always + type: string + sample: /index.html + health_check_port: + description: The port to use to connect with the target. + returned: always + type: string + sample: traffic-port + health_check_protocol: + description: The protocol to use to connect with the target. + returned: always + type: string + sample: HTTP + health_check_timeout_seconds: + description: The amount of time, in seconds, during which no response means a failed health check. + returned: always + type: int + sample: 5 + healthy_threshold_count: + description: The number of consecutive health checks successes required before considering an unhealthy target healthy. + returned: always + type: int + sample: 5 + load_balancer_arns: + description: The Amazon Resource Names (ARN) of the load balancers that route traffic to this target group. + returned: always + type: list + sample: [] + matcher: + description: The HTTP codes to use when checking for a successful response from a target. + returned: always + type: dict + sample: { + "http_code": "200" + } + port: + description: The port on which the targets are listening. + returned: always + type: int + sample: 80 + protocol: + description: The protocol to use for routing traffic to the targets. + returned: always + type: string + sample: HTTP + stickiness_enabled: + description: Indicates whether sticky sessions are enabled. + returned: always + type: bool + sample: true + stickiness_lb_cookie_duration_seconds: + description: Indicates whether sticky sessions are enabled. + returned: always + type: int + sample: 86400 + stickiness_type: + description: The type of sticky sessions. + returned: always + type: string + sample: lb_cookie + tags: + description: The tags attached to the target group. + returned: always + type: dict + sample: "{ + 'Tag': 'Example' + }" + target_group_arn: + description: The Amazon Resource Name (ARN) of the target group. + returned: always + type: string + sample: "arn:aws:elasticloadbalancing:ap-southeast-2:01234567890:targetgroup/mytargetgroup/aabbccddee0044332211" + target_group_name: + description: The name of the target group. + returned: always + type: string + sample: mytargetgroup + unhealthy_threshold_count: + description: The number of consecutive health check failures required before considering the target unhealthy. + returned: always + type: int + sample: 2 + vpc_id: + description: The ID of the VPC for the targets. + returned: always + type: string + sample: vpc-0123456 +''' + +import traceback +from ansible.module_utils.basic import AnsibleModule +from ansible.module_utils.ec2 import (boto3_conn, boto3_tag_list_to_ansible_dict, camel_dict_to_snake_dict, + ec2_argument_spec, get_aws_connection_info) + +try: + import boto3 + from botocore.exceptions import ClientError, NoCredentialsError + HAS_BOTO3 = True +except ImportError: + HAS_BOTO3 = False + + +def get_target_group_attributes(connection, module, target_group_arn): + + try: + target_group_attributes = boto3_tag_list_to_ansible_dict(connection.describe_target_group_attributes(TargetGroupArn=target_group_arn)['Attributes']) + except ClientError as e: + module.fail_json(msg=e.message, exception=traceback.format_exc(), **camel_dict_to_snake_dict(e.response)) + + # Replace '.' with '_' in attribute key names to make it more Ansibley + for k, v in target_group_attributes.items(): + target_group_attributes[k.replace('.', '_')] = v + del target_group_attributes[k] + + return target_group_attributes + + +def get_target_group_tags(connection, module, target_group_arn): + + try: + return boto3_tag_list_to_ansible_dict(connection.describe_tags(ResourceArns=[target_group_arn])['TagDescriptions'][0]['Tags']) + except ClientError as e: + module.fail_json(msg=e.message, exception=traceback.format_exc(), **camel_dict_to_snake_dict(e.response)) + + +def list_target_groups(connection, module): + + load_balancer_arn = module.params.get("load_balancer_arn") + target_group_arns = module.params.get("target_group_arns") + names = module.params.get("names") + + try: + target_group_paginator = connection.get_paginator('describe_target_groups') + if not load_balancer_arn and not target_group_arns and not names: + target_groups = target_group_paginator.paginate().build_full_result() + if load_balancer_arn: + target_groups = target_group_paginator.paginate(LoadBalancerArn=load_balancer_arn).build_full_result() + if target_group_arns: + target_groups = target_group_paginator.paginate(TargetGroupArns=target_group_arns).build_full_result() + if names: + target_groups = target_group_paginator.paginate(Names=names).build_full_result() + except ClientError as e: + if e.response['Error']['Code'] == 'TargetGroupNotFound': + module.exit_json(target_groups=[]) + else: + module.fail_json(msg=e.message, exception=traceback.format_exc(), **camel_dict_to_snake_dict(e.response)) + except NoCredentialsError as e: + module.fail_json(msg="AWS authentication problem. " + e.message, exception=traceback.format_exc()) + + # Get the attributes and tags for each target group + for target_group in target_groups['TargetGroups']: + target_group.update(get_target_group_attributes(connection, module, target_group['TargetGroupArn'])) + target_group['tags'] = get_target_group_tags(connection, module, target_group['TargetGroupArn']) + + # Turn the boto3 result in to ansible_friendly_snaked_names + snaked_target_groups = [camel_dict_to_snake_dict(target_group) for target_group in target_groups['TargetGroups']] + + module.exit_json(target_groups=snaked_target_groups) + + +def main(): + + argument_spec = ec2_argument_spec() + argument_spec.update( + dict( + load_balancer_arn=dict(type='str'), + target_group_arns=dict(type='list'), + names=dict(type='list') + ) + ) + + module = AnsibleModule(argument_spec=argument_spec, + mutually_exclusive=['load_balancer_arn', 'target_group_arns', 'names'], + supports_check_mode=True + ) + + if not HAS_BOTO3: + module.fail_json(msg='boto3 required for this module') + + region, ec2_url, aws_connect_params = get_aws_connection_info(module, boto3=True) + + if region: + connection = boto3_conn(module, conn_type='client', resource='elbv2', region=region, endpoint=ec2_url, **aws_connect_params) + else: + module.fail_json(msg="region must be specified") + + list_target_groups(connection, module) + + +if __name__ == '__main__': + main()