lib/ansible/modules/cloud/alicloud/ali_slb_lb.py (376 lines of code) (raw):

#!/usr/bin/python # -*- coding: utf-8 -*- # Copyright (c) 2017-present Alibaba Group Holding Limited. He Guimin <heguimin36@163.com.com> # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) # # 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 http://www.gnu.org/licenses/. from __future__ import (absolute_import, division, print_function) __metaclass__ = type ANSIBLE_METADATA = {'metadata_version': '1.1', 'status': ['preview'], 'supported_by': 'community'} DOCUMENTATION = ''' --- module: ali_slb_lb short_description: Create, Delete, Enable or Disable Server Load Balancer. description: - Create, Delete, Start or Stop Server Load Balancer. - Modify Load Balancer internet charge type and bandwidth options: state: description: - The state of the instance after operating. default: 'present' choices: ['present', 'absent', 'running', 'stopped'] type: str load_balancer_name: description: - The name of the server load balancer, which is a string of 1 to 80 characters. It can contain numerals, "_", "/", "." or "-". - This is used to ensure idempotence. aliases: ['name', 'lb_name'] required: True type: str load_balancer_id: description: - This parameter is required when user wants to perform edit operation in Load Balancer aliases: ['id'] type: str is_internet: description: - Load balancer network type whether is internet. type: bool default: False vswitch_id: description: - The ID of the VSwitch to which the SLB instance belongs. aliases: ['subnet_id'] type: str internet_charge_type: description: - The charge type of internet. It will be ignored when C(is_internet=False) default: 'PayByTraffic' choices: ['PayByBandwidth', 'PayByTraffic'] type: str master_zone_id: description: - The ID of the primary zone. By default, the SLB cluster in the primary zone is used to distribute traffic. type: str slave_zone_id: description: - The ID of the backup zone. The backup zone takes over the traffic distribution only when the SLB cluster in the primary zone fails. type: str bandwidth: description: - Bandwidth peak of the public network instance charged per fixed bandwidth. It allow 1~5000 in Mbps. - It will be ignored when C(internet_charge_type=PayByTraffic) default: 1 type: int load_balancer_spec: description: - The specification of the Server Load Balancer instance. If no value is specified, a shared-performance instance is created. - There are some region limitations for load_balancer_spec. See U(https://www.alibabacloud.com/help/doc-detail/27577.htm) for details choices: ['slb.s1.small', 'slb.s2.small', 'slb.s2.medium', 'slb.s3.small', 'slb.s3.medium', 'slb.s3.large'] aliases: ['spec', 'lb_spec'] type: str multi_ok: description: - By default the module will not create another Load Balancer if there is another Load Balancer with the same I(name). Specify this as true if you want duplicate Load Balancers created. default: False type: bool tags: description: - A hash/dictionaries of slb tags. C({"key":"value"}) type: dict purge_tags: description: - Delete existing tags on the slb that are not specified in the task. If True, it means you have to specify all the desired tags on each task affecting a slb. default: False type: bool notes: - The change in internet charge type will take effect from the early morning of the next day. It can not be changed twice in one day, otherwise, a error "Operation.NotAllowed" will appear. requirements: - "python >= 3.6" - "footmark >= 1.16.0" extends_documentation_fragment: - alicloud author: - "He Guimin (@xiaozhu36)" ''' EXAMPLES = ''' # Note: These examples do not set authentication details, see the Alibaba Cloud Guide for details. - name: Create a server load balancer ali_slb_lb: name: 'from-ansible' is_internet: True internet_charge_type: 'PayByTraffic' spec: 'slb.s1.small' state: present - name: Stop a server load balancer ali_slb_lb: name: 'from-ansible' state: stopped - name: Start a server load balancer ali_slb_lb: name: 'from-ansible' state: running - name: Modify server load balancer internet charge type and bandwidth ali_slb_lb: name: 'from-ansible' internet_charge_type: 'PayByBandwidth' bandwidth: 5 ''' RETURN = ''' load_balancer: description: - info about the server load balancer that was created or deleted. returned: on present type: complex contains: address: description: The IP address of the loal balancer returned: always type: str sample: "47.94.26.126" address_ipversion: description: The IP address version. IPV4 or IPV6. returned: always type: str sample: "ipv4" address_type: description: The load balancer internet type returned: always type: str sample: "internet" backend_servers: description: The load balancer's backend servers returned: always type: complex contains: server_id: description: The backend server id returned: always type: str sample: "i-vqunci342" weight: description: The backend server weight returned: always type: int sample: 100 description: description: The backend server description returned: always type: str sample: "" type: description: The backend server type, ecs or eni returned: always type: str sample: "ecs" bandwidth: description: The load balancer internet bandwidth returned: always type: int sample: 5 create_time: description: The time of the load balancer was created returned: always type: str sample: "2019-01-02T02:37:41Z" end_time: description: The time of the load balancer will be released returned: always type: str sample: "2999-09-08T16:00:00Z" id: description: The ID of the load balancer was created. Same as load_balancer_id. returned: always type: str sample: "lb-2zea9ohgtf" internet_charge_type: description: The load balancer internet charge type returned: always type: str sample: "PayByTraffic" listeners: description: The listeners of the load balancer. returned: always type: complex contains: listener_port: description: The front-end port of the listener that is used to receive incoming traffic and distribute the traffic to the backend servers. returned: always type: int sample: 22 listener_protocol: description: The frontend protocol used by the SLB instance. returned: always type: str sample: tcp listener_forward: description: Whether to enable listener forwarding. returned: always type: str sample: "" forward_port: description: The destination listening port. It must be an existing HTTPS listening port. returned: always type: int sample: 20 load_balancer_id: description: The ID of the load balancer was created. returned: always type: str sample: "lb-2zea9ohgtf" load_balancer_name: description: The name of the load balancer was created. returned: always type: str sample: "ansible-ali_slb_lb" load_balancer_status: description: The load balancer current status. returned: always type: str sample: "active" master_zone_id: description: The ID of the primary zone. returned: always type: str sample: "cn-beijing-a" name: description: The name of the load balancer was created. returned: always type: str sample: "ansible-ali_slb_lb" network_type: description: The network type of the load balancer was created. returned: always type: str sample: "classic" pay_type: description: The load balancer instance charge type. returned: always type: str sample: "PostPaid" resource_group_id: description: The resource group of the load balancer belongs. returned: always type: str sample: "rg-acfmwvvtg5owavy" slave_zone_id: description: The ID of the backup zone returned: always type: str sample: "cn-beijing-d" tags: description: The load balancer tags returned: always type: dict sample: {} vpc_id: description: The vpc of the load balancer belongs. returned: always type: str sample: "vpc-fn3nc3" vswitch_id: description: The vswitch of the load balancer belongs. returned: always type: str sample: "vsw-c3nc3r" ''' import time from ansible.module_utils.basic import AnsibleModule from ansible.module_utils.alicloud_ecs import ecs_argument_spec, slb_connect HAS_FOOTMARK = False try: from footmark.exception import SLBResponseError HAS_FOOTMARK = True except ImportError: HAS_FOOTMARK = False def main(): argument_spec = ecs_argument_spec() argument_spec.update(dict( internet_charge_type=dict(type='str', choices=['PayByBandwidth', 'PayByTraffic'], default='PayByTraffic'), state=dict(type='str', choices=['present', 'absent', 'running', 'stopped'], default='present'), load_balancer_name=dict(type='str', required=True, aliases=['name', 'lb_name']), load_balancer_id=dict(type='str', aliases=['id']), is_internet=dict(type='bool', default=False), bandwidth=dict(type='int', default=1), vswitch_id=dict(type='str', aliases=['subnet_id']), master_zone_id=dict(type='str'), slave_zone_id=dict(type='str'), load_balancer_spec=dict(type='str', aliases=['spec', 'lb_spec'], choices=['slb.s1.small', 'slb.s2.small', 'slb.s2.medium', 'slb.s3.small', 'slb.s3.medium', 'slb.s3.large']), multi_ok=dict(type='bool', default=False), tags=dict(type='dict'), purge_tags=dict(type='bool', default=False) )) module = AnsibleModule(argument_spec=argument_spec) if HAS_FOOTMARK is False: module.fail_json(msg='footmark required for the module ali_slb_lb.') slb = slb_connect(module) state = module.params['state'] name = module.params['load_balancer_name'] load_balancer_id = module.params['load_balancer_id'] is_internet = module.params['is_internet'] internet_charge_type = str(module.params['internet_charge_type']).lower() changed = False matching = None filters = {} if name: filters['load_balancer_name'] = name if load_balancer_id: filters['load_balancer_id'] = load_balancer_id if not module.params['multi_ok']: try: matching_slbs = slb.describe_load_balancers(**filters) if len(matching_slbs) == 1: matching = matching_slbs[0] elif len(matching_slbs) > 1: module.fail_json(msg='Currently there are {0} Load Balancers that have the same name {1}. ' 'If you would like to create anyway ' 'please pass True to the multi_ok param.'.format(len(matching_slbs), name)) except Exception as e: module.fail_json(msg="Failed to describe Load Balancers: {0}".format(e)) if state == "absent": if matching: try: changed = matching.delete() except Exception as e: module.fail_json(msg="Failed to delete Load Balancers: {0}".format(e)) module.exit_json(changed=changed, load_balancer={}) if state == "present": if not matching: params = module.params params['internet_charge_type'] = internet_charge_type params['client_token'] = "Ansible-Alicloud-%s-%s" % (hash(str(module.params)), str(time.time())) address_type = "intranet" if is_internet: address_type = "internet" params['address_type'] = address_type try: matching = slb.create_load_balancer(**params) changed = True except Exception as e: module.fail_json(msg="Failed to create Load Balancer: {0}".format(e)) if not matching: module.fail_json(msg="The specified load balancer {0} is not exist. Please check your name and try again.".format(name)) if not internet_charge_type: internet_charge_type = str(matching.internet_charge_type).lower() bandwidth = module.params['bandwidth'] if not bandwidth: bandwidth = matching.bandwidth try: if matching.modify_spec(internet_charge_type=internet_charge_type, bandwidth=bandwidth): changed = True matching = matching.get() except Exception as e: module.fail_json(msg="Failed to modify Load Balancer spec: {0}".format(e)) status = "active" if state == "stopped": status = "inactive" try: if matching.set_status(status): changed = True except Exception as e: module.fail_json(msg="Failed to modify Load Balancer status: {0}".format(e)) tags = module.params['tags'] if module.params['purge_tags']: if not tags: tags = matching.tags try: if matching.remove_tags(tags): changed = True module.exit_json(changed=changed, load_balancer=matching.get().read()) except Exception as e: module.fail_json(msg="{0}".format(e)) if tags: try: if matching.add_tags(tags): changed = True except Exception as e: module.fail_json(msg="{0}".format(e)) module.exit_json(changed=changed, load_balancer=matching.get().read()) if __name__ == "__main__": main()