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()