lb_action.py 6.26 KB
#!/usr/bin/python
# -*- coding: UTF-8 -*-

""" 
修改腾讯云七层负载均衡器的权重

@see doc:  https://cloud.tencent.com/document/product/214/8978
  
"""

from qcloud.qcloud_api import QcloudApi
import time, sys, os
import json


"""
  作用:切换负载均衡器的权重
"""

def modify_clb_weight(SecretId, SecretKey, lb_id, ip_weight_dict={}, hostname_weight_dict={}, default_weight=0):
    """
    修改传统负载均衡器的权重
    @:param lb_id 负载均衡器的ID
    @:param ip_weight_dict 需要设置权重的后端IP-权重字典, 格式为 {'ip': weight }
    :return: True: 修改成功
    """
    # 1.获取传统型负载均衡器的后端列表
    # see details at: https://cloud.tencent.com/document/api/214/1259
    instance_weight = {}  # instance_id --> weight

    api = QcloudApi(secretId=SecretId, secretKey=SecretKey)
    lb_info = api.do_query(params={'Action': 'DescribeLoadBalancerBackends', 'loadBalancerId': lb_id}, req_url=QcloudApi.URLS_lb)
    for backend in lb_info['backendSet']:
        if ip_weight_dict:
            if backend['lanIp'] in ip_weight_dict.keys():
                # setup the instance_id --> weight
                instance_weight[backend['unInstanceId']] = ip_weight_dict[backend['lanIp']]
            else:
                instance_weight[backend['unInstanceId']] = default_weight
        elif hostname_weight_dict:
            if backend['instanceName'] in hostname_weight_dict.keys():
                # setup the instance_id --> weight
                instance_weight[backend['unInstanceId']] = hostname_weight_dict[backend['instanceName']]
            else:
                instance_weight[backend['unInstanceId']] = default_weight
        else:
            break

    # 2.检查至少有一个weight不为0
    if len(filter(lambda w: w != 0, instance_weight.values())) == 0:
        sys.exit(" instance weight: %s is all zero. please check again!" % instance_weight)

    # 3.修改权重: https://cloud.tencent.com/document/api/214/1264
    modify_params = {'Action': 'ModifyLoadBalancerBackends', 'loadBalancerId': lb_id}
    i = 1
    for ins_id, ins_weight in instance_weight.iteritems():
        modify_params['backends.%i.instanceId' % i] = ins_id
        modify_params['backends.%i.weight' % i] = ins_weight
        i = i + 1
    api = QcloudApi(secretId=SecretId, secretKey=SecretKey)
    rsp = api.do_query(params=modify_params, req_url=QcloudApi.URLS_lb)
    return rsp['code'] == 0


def modify_alb_weight(SecretId, SecretKey, lb_id, domain, ip_weight_dict={}, hostname_weight_dict={},default_weight=0):
    """
      修改应用型负载均衡器上服务器的权重
      @:param lb_id: 应用型负载均衡器ID
      @:param domain: 应用型负载均衡器的domain
      @:param ip_weight_dict: 需要设置权重的dict, 格式为 {'ip': weight }
     @return list
    """

    # 查询ALB的监听器信息
    # see qcloud api details at: https://cloud.tencent.com/document/product/214/8987
    instance_weight = {}  # instance_id --> weight
    instance_port = {}   # instance_id --> port
    listener_ids = {}   # all linsters
    hostname_ip_map = {}  # instance_name --> ip


    api = QcloudApi(secretId=SecretId, secretKey=SecretKey)
    lb_info = api.do_query(params={'Action': 'DescribeForwardLBBackends', 'loadBalancerId': lb_id}, req_url=QcloudApi.URLS_lb)

    # listener : [http , https]
    for listener in lb_info['data']:
        if listener.has_key('rules'):
            pass
        else:
            continue
        for rule in listener['rules']:
            if rule['domain'] == domain:  # domain match
                listener_ids[listener['listenerId']] = listener['protocolType']
                for backend in rule['backends']:
                    instance_port[backend['unInstanceId']] = backend['port']
                    if ip_weight_dict:
                        if backend['lanIp'] in ip_weight_dict.keys():
                            # setup the instance_id --> weight
                            instance_weight[backend['unInstanceId']] = ip_weight_dict[backend['lanIp']]
                            if hostname_ip_map.has_key(backend['instanceName']):
                                hostname_ip_map[backend['instanceName']].append(backend['lanIp'])
                            else:
                                hostname_ip_map[backend['instanceName']] = [backend['lanIp']]
                        else:
                            instance_weight[backend['unInstanceId']] = default_weight
                    elif hostname_weight_dict:
                        if backend['instanceName'] in hostname_weight_dict.keys():
                            # setup the instance_id --> weight
                            instance_weight[backend['unInstanceId']] = hostname_weight_dict[backend['instanceName']]
                        else:
                            instance_weight[backend['unInstanceId']] = default_weight
                    else:
                        break

    # 检查至少有一个weight
    if len(filter(lambda w: w != 0, instance_weight.values())) == 0:
        sys.exit(" instance weight: %s is all zero. please check again!" % instance_weight)

    # 修改七层负载均衡器的权重
    # see details at: https://cloud.tencent.com/document/product/214/8978
    return_code = []
    for lis_id in listener_ids.keys():
        params = {'Action': 'ModifyForwardSeventhBackends', 'loadBalancerId': lb_id,
                  'listenerId': lis_id, 'domain': domain}
        i = 1
        for ins_id, ins_weight in instance_weight.iteritems():
            params['backends.%i.instanceId' % i] = ins_id
            params['backends.%i.weight' % i] = ins_weight
            params['backends.%i.port' % i] = instance_port[ins_id]
            i = i + 1

        rsp = api.do_query(params, req_url=QcloudApi.URLS_lb)
        print(u"response code: %s . success change domain: %s for listener : %s. wait for 10s" % (rsp['code'], domain, listener_ids[lis_id]))
        return_code.append(rsp['code'])
        time.sleep(10)
    return return_code.count(0) == len(return_code)


def describe_lbs(SecretId, SecretKey):
    api = QcloudApi(secretId=SecretId, secretKey=SecretKey)
    lb_info = api.do_query(params={'Action': 'DescribeLoadBalancers', 'forward': -1, 'limit':100, 'withRs':1}, req_url=QcloudApi.URLS_lb)
    return lb_info['loadBalancerSet']