Authored by chunhua.zhang

Merge branch 'master' of git.yoho.cn:ops/yoho-ansible-roles

1 -#!/usr/bin/python  
2 -# -*- coding: UTF-8 -*-  
3 -  
4 -"""  
5 -修改腾讯云七层负载均衡器的权重  
6 -  
7 -@see doc: https://cloud.tencent.com/document/product/214/8978  
8 -  
9 -"""  
10 -  
11 -from qcloud.qcloud_api import QcloudApi  
12 -from yansible.inventory_reader import InventoryReader  
13 -import time, sys, os  
14 -  
15 -  
16 -  
17 -  
18 -"""  
19 - 作用:切换负载均衡器的流量  
20 - 依赖: inventory 文件  
21 -  
22 - demo:  
23 -  
24 -  
25 -lbswitch = LBSwitch(secretId="AKID6dwppIHPO5qPv5GK", secretKey="ACJkH9mg0DBsQaW",  
26 - az1_lb_id="lb-dyh6eucn", az2_lb_id="lb-capto5b5", az3_lb_id="lb-capto5b5", az1_innerlb_id="lb-c26tgo5r")  
27 -  
28 -# 全部流量切换到AZ1  
29 -ret = lbswitch.all_to_az1()  
30 -  
31 -# 全部流量切换到AZ2  
32 -ret = lbswitch.all_to_az2()  
33 -  
34 -"""  
35 -  
36 -  
37 -class LBSwitch:  
38 - def __init__(self, secretId, secretKey, az1_lb_id, az2_lb_id, az3_lb_id, az1_innerlb_id):  
39 - self.SecretId = secretId  
40 - self.SecretKey = secretKey  
41 - self.az1_lb_id = az1_lb_id  
42 - self.az2_lb_id = az2_lb_id  
43 - self.az3_lb_id = az3_lb_id  
44 - self.az1_innerlb_id = az1_innerlb_id  
45 -  
46 - def all_to_az1(self):  
47 - """  
48 - 所有流量切换到az1  
49 - :return:  
50 - """  
51 - inventory_reader = InventoryReader()  
52 - az1_nginxs = inventory_reader.get_inventory_ifo("az1", 'java-nginx')  
53 - print "get all java nginx: %s for az: %s" % (az1_nginxs, "az1")  
54 -  
55 - az1_nginx_weight = {}  
56 - for az1_nginx in az1_nginxs:  
57 - az1_nginx_weight[az1_nginx] = 10  
58 -  
59 - # az2 公网流量切换到az1  
60 - ret_az2 = self.modify_alb_weight(lb_id=self.az2_lb_id, domain="*.yoho.cn", ip_weight_dict=az1_nginx_weight)  
61 - print("switch all incoming request from az2 to az1 result: %s" % ret_az2)  
62 -  
63 - # az1 公网流量、内部流量切换到az1  
64 - ret_az1 = self.modify_clb_weight(lb_id=self.az1_lb_id, ip_weight_dict=az1_nginx_weight)  
65 - ret_az1_inner = self.modify_alb_weight(lb_id=self.az1_innerlb_id, domain="*.yoho.yohoops.org",  
66 - ip_weight_dict=az1_nginx_weight)  
67 - print("switch all incoming request from az1 to az1 result: %s inner result: %s" % (ret_az1, ret_az1_inner))  
68 -  
69 - return ret_az1 and ret_az1_inner and ret_az2  
70 -  
71 -  
72 -  
73 - def all_to_az2(self):  
74 - """  
75 - 所有流量切换到AZ2  
76 - :return:  
77 - """  
78 - inventory_reader = InventoryReader()  
79 - az2_nginx = inventory_reader.get_inventory_ifo("az2", 'java-nginx')  
80 - az2_nginx_weight = {}  
81 - for nginx in az2_nginx:  
82 - az2_nginx_weight[nginx] = 10  
83 -  
84 - # az2 公网流量切换到az2  
85 - ret_az2 = self.modify_alb_weight(lb_id=self.az2_lb_id, domain="*.yoho.cn", ip_weight_dict=az2_nginx_weight)  
86 - print("switch all incoming request from az2 to az2 result: %s" % ret_az2)  
87 -  
88 - # az1 公网流量、内部流量切换到az2  
89 - ret_az1 = self.modify_clb_weight(lb_id=self.az1_lb_id, ip_weight_dict=az2_nginx_weight)  
90 - ret_az1_inner = self.modify_alb_weight(lb_id=self.az1_innerlb_id, domain="*.yoho.yohoops.org", ip_weight_dict=az2_nginx_weight)  
91 - print("switch all incoming request from az1 to az2 result: %s inner lb:%s" % (ret_az1, ret_az1_inner))  
92 -  
93 - return ret_az1 and ret_az2 and ret_az1_inner  
94 -  
95 -  
96 -  
97 - def modify_clb_weight(self, lb_id, ip_weight_dict):  
98 - """  
99 - 修改传统负载均衡器的权重  
100 - @:param lb_id 负载均衡器的ID  
101 - @:param ip_weight_dict 需要设置权重的后端IP-权重字典, 格式为 {'ip': weight }  
102 - :return: True: 修改成功  
103 - """  
104 - # 1.获取传统型负载均衡器的后端列表  
105 - # see details at: https://cloud.tencent.com/document/api/214/1259  
106 - instance_weight = {} # instance_id --> weight  
107 -  
108 - api = QcloudApi(secretId=self.SecretId, secretKey=self.SecretKey)  
109 - lb_info = api.do_query(params={'Action': 'DescribeLoadBalancerBackends', 'loadBalancerId': lb_id}, req_url=QcloudApi.URLS_lb)  
110 - for backend in lb_info['backendSet']:  
111 - if backend['lanIp'] in ip_weight_dict.keys():  
112 - # setup the instance_id --> weight  
113 - instance_weight[backend['unInstanceId']] = ip_weight_dict[backend['lanIp']]  
114 - else:  
115 - instance_weight[backend['unInstanceId']] = 0  
116 -  
117 - # 2.检查至少有一个weight不为0  
118 - if len(filter(lambda w: w != 0, instance_weight.values())) == 0:  
119 - sys.exit(" instance weight: %s is all zero. please check again!" % instance_weight)  
120 -  
121 - # 3.修改权重: https://cloud.tencent.com/document/api/214/1264  
122 - modify_params = {'Action': 'ModifyLoadBalancerBackends', 'loadBalancerId': lb_id}  
123 - i = 1  
124 - for ins_id, ins_weight in instance_weight.iteritems():  
125 - modify_params['backends.%i.instanceId' % i] = ins_id  
126 - modify_params['backends.%i.weight' % i] = ins_weight  
127 - i = i + 1  
128 - api = QcloudApi(secretId=self.SecretId, secretKey=self.SecretKey)  
129 - rsp = api.do_query(params=modify_params, req_url=QcloudApi.URLS_lb)  
130 - return rsp['code'] == 0  
131 -  
132 - def modify_alb_weight(self, lb_id, domain, ip_weight_dict):  
133 - """  
134 - 修改应用型负载均衡器上服务器的权重  
135 - @:param lb_id: 应用型负载均衡器ID  
136 - @:param domain: 应用型负载均衡器的domain  
137 - @:param ip_weight_dict: 需要设置权重的dict, 格式为 {'ip': weight }  
138 - @return list  
139 - """  
140 -  
141 - # 查询ALB的监听器信息  
142 - # see qcloud api details at: https://cloud.tencent.com/document/product/214/8987  
143 - instance_weight = {} # instance_id --> weight  
144 - instance_port = {} # instance_id --> port  
145 - listener_ids = {} # all linsters  
146 -  
147 - api = QcloudApi(secretId=self.SecretId, secretKey=self.SecretKey)  
148 - lb_info = api.do_query(params={'Action': 'DescribeForwardLBBackends', 'loadBalancerId': lb_id}, req_url=QcloudApi.URLS_lb)  
149 -  
150 - # listener : [http , https]  
151 - for listener in lb_info['data']:  
152 - for rule in listener['rules']:  
153 - if rule['domain'] == domain: # domain match  
154 - listener_ids[listener['listenerId']] = listener['protocolType']  
155 - for backend in rule['backends']:  
156 - instance_port[backend['unInstanceId']] = backend['port']  
157 - if backend['lanIp'] in ip_weight_dict.keys():  
158 - # setup the instance_id --> weight  
159 - instance_weight[backend['unInstanceId']] = ip_weight_dict[backend['lanIp']]  
160 - else:  
161 - instance_weight[backend['unInstanceId']] = 0  
162 -  
163 - # 检查至少有一个weight  
164 - if len(filter(lambda w: w != 0, instance_weight.values())) == 0:  
165 - sys.exit(" instance weight: %s is all zero. please check again!" % instance_weight)  
166 -  
167 - # 修改七层负载均衡器的权重  
168 - # see details at: https://cloud.tencent.com/document/product/214/8978  
169 - return_code = []  
170 - for lis_id in listener_ids.keys():  
171 - params = {'Action': 'ModifyForwardSeventhBackends', 'loadBalancerId': lb_id,  
172 - 'listenerId': lis_id, 'domain': domain}  
173 - i = 1  
174 - for ins_id, ins_weight in instance_weight.iteritems():  
175 - params['backends.%i.instanceId' % i] = ins_id  
176 - params['backends.%i.weight' % i] = ins_weight  
177 - params['backends.%i.port' % i] = instance_port[ins_id]  
178 - i = i + 1  
179 -  
180 - rsp = api.do_query(params, req_url=QcloudApi.URLS_lb)  
181 - print(u"response code: %s . success change domain: %s for listener : %s. wait for 10s" % (rsp['code'], domain, listener_ids[lis_id]))  
182 - return_code.append(rsp['code'])  
183 - time.sleep(10)  
184 - return return_code.count(0) == len(return_code)  
185 -  
186 -  
187 -  
188 -  
189 -