lib/ansible/modules/cloud/alicloud/ali_slb_server.py [128:374]:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
        load_balancer_id: lb-abcd1234
        state: absent
        backend_servers:
          - i-abcd1234
          - i-abcd1234

'''
RETURN = '''
load_balancer_id:
    description: ID of the load balancer.
    returned: when success
    type: str
    sample: "lb-2zeyfm5a14c9ffxvxmvco"
"backend_servers":
    description: Details about the backened-servers that were added.
    returned: when success
    type: list
    sample: [
        {
            "health_status": "abnormal",
            "id": "i-2zeau2evvbnwufq0fa7q"
        },
        {
            "health_status": "abnormal",
            "id": "i-2zehasnejqr6g6agys5a"
        }
    ]
'''

from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.alicloud_ecs import ecs_argument_spec, slb_connect

try:
    from footmark.exception import SLBResponseError

    HAS_FOOTMARK = True
except ImportError:
    HAS_FOOTMARK = False


def parse_server_ids(servers):
    parse_server = []
    if servers:
        for s in servers:
            if "server_ids" in s:
                ids = s.pop("server_ids")
                for id in ids:
                    server = {"server_id": id}
                    server.update(s)
                    parse_server.append(server)
            else:
                parse_server.append(s)
    return parse_server


def get_backen_server_weight(server):
    """
    Retrieves instance information from an instance
    ID and returns it as a dictionary
    """
    return {'id': server.id, 'weight': server.weight}


def get_backen_server_status(server):
    """
    Retrieves instance information from an instance
    ID and returns it as a dictionary
    """
    return {'id': server.id, 'health_status': server.status}


def add_set_backend_servers(module, slb, load_balancer_id, backend_servers):
    """
    Add and/or Set backend servers to an slb

    :param module: Ansible module object
    :param slb: authenticated slb connection object
    :param load_balancer_id: load balancer id to add/set backend servers to
    :param backend_servers: backend severs information to add/set
    :return: returns changed state, current added backend servers and custom message.
    """

    changed = False
    server_id_param = 'server_id'
    backend_servers_to_set = []
    backend_servers_to_add = []
    result = []
    current_backend_servers = []
    changed_after_add = False
    changed_after_set = False

    try:

        load_balancer_info = slb.describe_load_balancer_attribute(load_balancer_id=load_balancer_id)

        # Verifying if server load balancer Object is present
        if load_balancer_info:
            existing_backend_servers = str(load_balancer_info.backend_servers['backend_server'])

            # Segregating existing backend servers from new backend servers from the provided backend servers
            for backend_server in backend_servers:

                backend_server_string = backend_server[server_id_param] + '\''
                if backend_server_string in existing_backend_servers:
                    backend_servers_to_set.append(backend_server)
                else:
                    backend_servers_to_add.append(backend_server)

                    # Adding new backend servers if provided
            if len(backend_servers_to_add) > 0:
                current_backend_servers.extend(slb.add_backend_servers(load_balancer_id=load_balancer_id, backend_servers=backend_servers_to_add))
                changed = True
                # Setting exisiting backend servers if provided
            if len(backend_servers_to_set) > 0:
                backen_servers = slb.set_backend_servers(load_balancer_id=load_balancer_id, backend_servers=backend_servers_to_set)
                changed = True
                # If backend server result after set action is available then clearing actual list
                # and adding new result to it.
                if len(backen_servers) > 0:
                    # Below operation clears list using slice operation
                    current_backend_servers[:] = []
                    current_backend_servers.extend(backen_servers)

            if changed_after_add or changed_after_set:
                changed = True

        else:
            module.fail_json(msg="Could not find provided load balancer instance")

    except SLBResponseError as ex:
        module.fail_json(msg='Unable to add backend servers, error: {0}'.format(ex))

    return changed, current_backend_servers


def remove_backend_servers(module, slb, load_balancer_id, backend_servers):
    """
    Remove backend servers from an slb

    :param module: Ansible module object
    :param slb: authenticated slb connection object
    :param load_balancer_id: load balancer id to remove backend servers from
    :param backend_servers: list of backend server ids to remove from slb
    :return: returns changed state, current added backend servers and custom message.
    """

    changed = False

    try:
        backend_servers = slb.remove_backend_servers(load_balancer_id=load_balancer_id, backend_server_ids=backend_servers)
        changed = True

    except SLBResponseError as ex:
        module.fail_json(msg='Unable to remove backend servers, error: {0}'.format(ex))

    return changed, backend_servers


def describe_backend_servers_health_status(module, slb, load_balancer_id=None, listener_ports=None):
    """
    Describe health status of added backend servers of an slb

    :param module: Ansible module object
    :param slb: authenticated slb connection object
    :param load_balancer_id: load balancer id to remove backend servers from
    :param listener_ports: list of ports to for which backend server health status is required
    :return: returns backend servers health status and custom message
    """

    backend_servers_health_status = []
    try:
        if listener_ports:
            for port in listener_ports:

                backend_server = slb.describe_backend_servers_health_status(load_balancer_id=load_balancer_id, port=port)
                backend_servers_health_status.extend(backend_server)
        else:
            backend_servers_health_status = slb.describe_backend_servers_health_status(load_balancer_id=load_balancer_id)

    except SLBResponseError as ex:
        module.fail_json(msg='Unable to describe backend servers health status, error: {0}'.format(ex))

    return backend_servers_health_status


def validate_backend_server_info(module, backend_servers, default_weight):
    """
    Validate backend server information provided by user for add, set and remove action

    :param module: Ansible module object
    :param backend_servers: backend severs information to validate (list of dictionaries or string)
    :param default_weight: assigns default weight, if provided, for a backend server to set/add
    """
    VALID_PARAMS = ['server_id', 'server_ids', 'weight', 'type']

    for backend_server in backend_servers:

        if not isinstance(backend_server, dict):
            module.fail_json(msg='Invalid backend_servers parameter type [%s] for state=present.' % type(backend_server))

        for k in backend_server:
            if k not in VALID_PARAMS:
                module.fail_json(msg='Invalid backend_server parameter {}'.format(k))

        if "server_id" not in backend_server and "server_ids" not in backend_server:
            module.fail_json(msg="'server_id' or 'server_ids': required field is set")

        # verifying weight parameter for non numeral string and limit validation
        if "weight" in backend_server:
            try:
                w = int(backend_server['weight'])
                if w < 0 or w > 100:
                    module.fail_json(msg="'weight': field value is invalid. Expect to [0-100].")
            except Exception as e:
                module.fail_json(msg="'weight': field value is invalid. Expect to positive integer [0-100].")


def get_verify_listener_ports(module, listener_ports=None):
    """
    Validate and get listener ports

    :param module: Ansible module object
    :param listener_ports: list of ports to for which backend server health status is required
    :return: formatted listener ports
    """

    if listener_ports:
        if len(listener_ports) > 0:
            for port in listener_ports:

                try:
                    port = int(port)
                except Exception as ex:
                    module.fail_json(msg='Invalid port value')
        else:
            listener_ports = None

    return listener_ports


def main():
    argument_spec = ecs_argument_spec()
    argument_spec.update(dict(
        state=dict(choices=['present', 'absent'], default='present', type='str'),
        backend_servers=dict(required=True, type='list', elements='dict', aliases=['servers']),
        load_balancer_id=dict(required=True, aliases=['lb_id'], type='str'),
    ))
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -



plugins/modules/ali_slb_server.py [111:357]:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
        load_balancer_id: lb-abcd1234
        state: absent
        backend_servers:
          - i-abcd1234
          - i-abcd1234

'''
RETURN = '''
load_balancer_id:
    description: ID of the load balancer.
    returned: when success
    type: str
    sample: "lb-2zeyfm5a14c9ffxvxmvco"
"backend_servers":
    description: Details about the backened-servers that were added.
    returned: when success
    type: list
    sample: [
        {
            "health_status": "abnormal",
            "id": "i-2zeau2evvbnwufq0fa7q"
        },
        {
            "health_status": "abnormal",
            "id": "i-2zehasnejqr6g6agys5a"
        }
    ]
'''

from ansible.module_utils.basic import AnsibleModule
from ansible_collections.alibaba.alicloud.plugins.module_utils.alicloud_ecs import ecs_argument_spec, slb_connect

try:
    from footmark.exception import SLBResponseError

    HAS_FOOTMARK = True
except ImportError:
    HAS_FOOTMARK = False


def parse_server_ids(servers):
    parse_server = []
    if servers:
        for s in servers:
            if "server_ids" in s:
                ids = s.pop("server_ids")
                for id in ids:
                    server = {"server_id": id}
                    server.update(s)
                    parse_server.append(server)
            else:
                parse_server.append(s)
    return parse_server


def get_backen_server_weight(server):
    """
    Retrieves instance information from an instance
    ID and returns it as a dictionary
    """
    return {'id': server.id, 'weight': server.weight}


def get_backen_server_status(server):
    """
    Retrieves instance information from an instance
    ID and returns it as a dictionary
    """
    return {'id': server.id, 'health_status': server.status}


def add_set_backend_servers(module, slb, load_balancer_id, backend_servers):
    """
    Add and/or Set backend servers to an slb

    :param module: Ansible module object
    :param slb: authenticated slb connection object
    :param load_balancer_id: load balancer id to add/set backend servers to
    :param backend_servers: backend severs information to add/set
    :return: returns changed state, current added backend servers and custom message.
    """

    changed = False
    server_id_param = 'server_id'
    backend_servers_to_set = []
    backend_servers_to_add = []
    result = []
    current_backend_servers = []
    changed_after_add = False
    changed_after_set = False

    try:

        load_balancer_info = slb.describe_load_balancer_attribute(load_balancer_id=load_balancer_id)

        # Verifying if server load balancer Object is present
        if load_balancer_info:
            existing_backend_servers = str(load_balancer_info.backend_servers['backend_server'])

            # Segregating existing backend servers from new backend servers from the provided backend servers
            for backend_server in backend_servers:

                backend_server_string = backend_server[server_id_param] + '\''
                if backend_server_string in existing_backend_servers:
                    backend_servers_to_set.append(backend_server)
                else:
                    backend_servers_to_add.append(backend_server)

                    # Adding new backend servers if provided
            if len(backend_servers_to_add) > 0:
                current_backend_servers.extend(slb.add_backend_servers(load_balancer_id=load_balancer_id, backend_servers=backend_servers_to_add))
                changed = True
                # Setting exisiting backend servers if provided
            if len(backend_servers_to_set) > 0:
                backen_servers = slb.set_backend_servers(load_balancer_id=load_balancer_id, backend_servers=backend_servers_to_set)
                changed = True
                # If backend server result after set action is available then clearing actual list
                # and adding new result to it.
                if len(backen_servers) > 0:
                    # Below operation clears list using slice operation
                    current_backend_servers[:] = []
                    current_backend_servers.extend(backen_servers)

            if changed_after_add or changed_after_set:
                changed = True

        else:
            module.fail_json(msg="Could not find provided load balancer instance")

    except SLBResponseError as ex:
        module.fail_json(msg='Unable to add backend servers, error: {0}'.format(ex))

    return changed, current_backend_servers


def remove_backend_servers(module, slb, load_balancer_id, backend_servers):
    """
    Remove backend servers from an slb

    :param module: Ansible module object
    :param slb: authenticated slb connection object
    :param load_balancer_id: load balancer id to remove backend servers from
    :param backend_servers: list of backend server ids to remove from slb
    :return: returns changed state, current added backend servers and custom message.
    """

    changed = False

    try:
        backend_servers = slb.remove_backend_servers(load_balancer_id=load_balancer_id, backend_server_ids=backend_servers)
        changed = True

    except SLBResponseError as ex:
        module.fail_json(msg='Unable to remove backend servers, error: {0}'.format(ex))

    return changed, backend_servers


def describe_backend_servers_health_status(module, slb, load_balancer_id=None, listener_ports=None):
    """
    Describe health status of added backend servers of an slb

    :param module: Ansible module object
    :param slb: authenticated slb connection object
    :param load_balancer_id: load balancer id to remove backend servers from
    :param listener_ports: list of ports to for which backend server health status is required
    :return: returns backend servers health status and custom message
    """

    backend_servers_health_status = []
    try:
        if listener_ports:
            for port in listener_ports:

                backend_server = slb.describe_backend_servers_health_status(load_balancer_id=load_balancer_id, port=port)
                backend_servers_health_status.extend(backend_server)
        else:
            backend_servers_health_status = slb.describe_backend_servers_health_status(load_balancer_id=load_balancer_id)

    except SLBResponseError as ex:
        module.fail_json(msg='Unable to describe backend servers health status, error: {0}'.format(ex))

    return backend_servers_health_status


def validate_backend_server_info(module, backend_servers, default_weight):
    """
    Validate backend server information provided by user for add, set and remove action

    :param module: Ansible module object
    :param backend_servers: backend severs information to validate (list of dictionaries or string)
    :param default_weight: assigns default weight, if provided, for a backend server to set/add
    """
    VALID_PARAMS = ['server_id', 'server_ids', 'weight', 'type']

    for backend_server in backend_servers:

        if not isinstance(backend_server, dict):
            module.fail_json(msg='Invalid backend_servers parameter type [%s] for state=present.' % type(backend_server))

        for k in backend_server:
            if k not in VALID_PARAMS:
                module.fail_json(msg='Invalid backend_server parameter {}'.format(k))

        if "server_id" not in backend_server and "server_ids" not in backend_server:
            module.fail_json(msg="'server_id' or 'server_ids': required field is set")

        # verifying weight parameter for non numeral string and limit validation
        if "weight" in backend_server:
            try:
                w = int(backend_server['weight'])
                if w < 0 or w > 100:
                    module.fail_json(msg="'weight': field value is invalid. Expect to [0-100].")
            except Exception as e:
                module.fail_json(msg="'weight': field value is invalid. Expect to positive integer [0-100].")


def get_verify_listener_ports(module, listener_ports=None):
    """
    Validate and get listener ports

    :param module: Ansible module object
    :param listener_ports: list of ports to for which backend server health status is required
    :return: formatted listener ports
    """

    if listener_ports:
        if len(listener_ports) > 0:
            for port in listener_ports:

                try:
                    port = int(port)
                except Exception as ex:
                    module.fail_json(msg='Invalid port value')
        else:
            listener_ports = None

    return listener_ports


def main():
    argument_spec = ecs_argument_spec()
    argument_spec.update(dict(
        state=dict(choices=['present', 'absent'], default='present', type='str'),
        backend_servers=dict(required=True, type='list', elements='dict', aliases=['servers']),
        load_balancer_id=dict(required=True, aliases=['lb_id'], type='str'),
    ))
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -



