Simple Linux Panel
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 
mdserver-web/plugins/op_load_balance/index.py

478 lines
12 KiB

# coding:utf-8
import sys
import io
import os
import time
import subprocess
import json
import re
web_dir = os.getcwd() + "/web"
if os.path.exists(web_dir):
sys.path.append(web_dir)
os.chdir(web_dir)
import core.mw as mw
app_debug = False
if mw.isAppleSystem():
app_debug = True
def getPluginName():
return 'op_load_balance'
def getPluginDir():
return mw.getPluginDir() + '/' + getPluginName()
def getServerDir():
return mw.getServerDir() + '/' + getPluginName()
def getArgs():
args = sys.argv[2:]
tmp = {}
args_len = len(args)
if args_len == 1:
t = args[0].strip('{').strip('}')
if t.strip() == '':
tmp = []
else:
t = t.split(':')
tmp[t[0]] = t[1]
tmp[t[0]] = t[1]
elif args_len > 1:
for i in range(len(args)):
t = args[i].split(':')
tmp[t[0]] = t[1]
return tmp
def checkArgs(data, ck=[]):
for i in range(len(ck)):
if not ck[i] in data:
return (False, mw.returnJson(False, '参数:(' + ck[i] + ')没有!'))
return (True, mw.returnJson(True, 'ok'))
def getConf():
path = getServerDir() + "/cfg.json"
if not os.path.exists(path):
mw.writeFile(path, '[]')
c = mw.readFile(path)
return json.loads(c)
def writeConf(data):
path = getServerDir() + "/cfg.json"
mw.writeFile(path, json.dumps(data))
def contentReplace(content):
service_path = mw.getServerDir()
content = content.replace('{$ROOT_PATH}', mw.getFatherDir())
content = content.replace('{$SERVER_PATH}', service_path)
content = content.replace('{$APP_PATH}', app_path)
return content
def restartWeb():
mw.opWeb('stop')
mw.opWeb('start')
def loadBalanceConf():
path = mw.getServerDir() + '/web_conf/nginx/vhost/load_balance.conf'
return path
def initDreplace():
dst_conf_tpl = getPluginDir() + '/conf/load_balance.conf'
dst_conf = loadBalanceConf()
if not os.path.exists(dst_conf):
con = mw.readFile(dst_conf_tpl)
mw.writeFile(dst_conf, con)
def status():
if not mw.getWebStatus():
return 'stop'
dst_conf = loadBalanceConf()
if not os.path.exists(dst_conf):
return 'stop'
return 'start'
def start():
initDreplace()
restartWeb()
return 'ok'
def stop():
dst_conf = loadBalanceConf()
os.remove(dst_conf)
deleteLoadBalanceAllCfg()
restartWeb()
return 'ok'
def restart():
restartWeb()
return 'ok'
def reload():
restartWeb()
return 'ok'
def installPreInspection():
check_op = mw.getServerDir() + "/openresty"
if not os.path.exists(check_op):
return "请先安装OpenResty"
return 'ok'
def deleteLoadBalanceAllCfg():
cfg = getConf()
upstream_dir = mw.getServerDir() + '/web_conf/nginx/upstream'
lua_dir = mw.getServerDir() + '/web_conf/nginx/lua/init_worker_by_lua_file'
rewrite_dir = mw.getServerDir() + '/web_conf/nginx/rewrite'
vhost_dir = mw.getServerDir() + '/web_conf/nginx/vhost'
for conf in cfg:
upstream_file = upstream_dir + '/' + conf['upstream_name'] + '.conf'
if os.path.exists(upstream_file):
os.remove(upstream_file)
lua_file = lua_dir + '/' + conf['upstream_name'] + '.lua'
if os.path.exists(lua_file):
os.remove(lua_file)
rewrite_file = rewrite_dir + '/' + conf['domain'] + '.conf'
mw.writeFile(rewrite_file, '')
path = vhost_dir + '/' + conf['domain'] + '.conf'
content = mw.readFile(path)
content = re.sub('include ' + upstream_file + ';' + "\n", '', content)
mw.writeFile(path, content)
mw.opLuaInitWorkerFile()
def makeConfServerList(data):
slist = ''
for x in data:
slist += 'server '
slist += x['ip'] + ':' + x['port']
if x['state'] == '0':
slist += ' down;\n\t'
continue
if x['state'] == '2':
slist += ' backup;\n\t'
continue
slist += ' weight=' + x['weight']
slist += ' max_fails=' + x['max_fails']
slist += ' fail_timeout=' + x['fail_timeout'] + "s;\n\t"
return slist
def makeLoadBalanceAllCfg(row):
# 生成所有配置
cfg = getConf()
upstream_dir = mw.getServerDir() + '/web_conf/nginx/upstream'
rewrite_dir = mw.getServerDir() + '/web_conf/nginx/rewrite'
vhost_dir = mw.getServerDir() + '/web_conf/nginx/vhost'
upstream_tpl = getPluginDir() + '/conf/upstream.tpl.conf'
rewrite_tpl = getPluginDir() + '/conf/rewrite.tpl.conf'
if not os.path.exists(upstream_dir):
os.makedirs(upstream_dir)
conf = cfg[row]
# replace vhost start
vhost_file = vhost_dir + '/' + conf['domain'] + '.conf'
vcontent = mw.readFile(vhost_file)
vhost_find_str = 'upstream/' + conf['upstream_name'] + '.conf'
vhead = 'include ' + mw.getServerDir() + '/web_conf/nginx/' + \
vhost_find_str + ';'
vpos = vcontent.find(vhost_find_str)
if vpos < 0:
vcontent = vhead + "\n" + vcontent
mw.writeFile(vhost_file, vcontent)
# replace vhost end
# make upstream start
upstream_file = upstream_dir + '/' + conf['upstream_name'] + '.conf'
content = ''
if len(conf['node_list']) > 0:
content = mw.readFile(upstream_tpl)
slist = makeConfServerList(conf['node_list'])
content = content.replace('{$NODE_SERVER_LIST}', slist)
content = content.replace('{$UPSTREAM_NAME}', conf['upstream_name'])
if conf['node_algo'] != 'polling':
content = content.replace('{$NODE_ALGO}', conf['node_algo'] + ';')
else:
content = content.replace('{$NODE_ALGO}', '')
mw.writeFile(upstream_file, content)
# make upstream end
# make rewrite start
rewrite_file = rewrite_dir + '/' + conf['domain'] + '.conf'
rcontent = ''
if len(conf['node_list']) > 0:
rcontent = mw.readFile(rewrite_tpl)
rcontent = rcontent.replace('{$UPSTREAM_NAME}', conf['upstream_name'])
mw.writeFile(rewrite_file, rcontent)
# make rewrite end
# health check start
lua_dir = mw.getServerDir() + '/web_conf/nginx/lua/init_worker_by_lua_file'
lua_init_worker_file = lua_dir + '/' + conf['upstream_name'] + '.lua'
if conf['node_health_check'] == 'ok':
lua_dir_tpl = getPluginDir() + '/lua/health_check.lua.tpl'
content = mw.readFile(lua_dir_tpl)
content = content.replace('{$UPSTREAM_NAME}', conf['upstream_name'])
content = content.replace('{$DOMAIN}', conf['domain'])
mw.writeFile(lua_init_worker_file, content)
else:
if os.path.exists(lua_init_worker_file):
os.remove(lua_init_worker_file)
mw.opLuaInitWorkerFile()
# health check end
return True
def add_load_balance(args):
data = checkArgs(
args, ['domain', 'upstream_name', 'node_algo', 'node_list', 'node_health_check'])
if not data[0]:
return data[1]
domain_json = args['domain']
tmp = json.loads(domain_json)
domain = tmp['domain']
cfg = getConf()
cfg_len = len(cfg)
tmp = {}
tmp['domain'] = domain
tmp['data'] = args['domain']
tmp['upstream_name'] = args['upstream_name']
tmp['node_algo'] = args['node_algo']
tmp['node_list'] = args['node_list']
tmp['node_health_check'] = args['node_health_check']
cfg.append(tmp)
writeConf(cfg)
import site_api
sobj = site_api.site_api()
domain_path = mw.getWwwDir() + '/' + domain
ps = '负载均衡[' + domain + ']'
data = sobj.add(domain_json, '80', ps, domain_path, '00')
makeLoadBalanceAllCfg(cfg_len)
mw.restartWeb()
return mw.returnJson(True, '添加成功', data)
def edit_load_balance(args):
data = checkArgs(
args, ['row', 'node_algo', 'node_list', 'node_health_check'])
if not data[0]:
return data[1]
row = int(args['row'])
cfg = getConf()
tmp = cfg[row]
tmp['node_algo'] = args['node_algo']
tmp['node_list'] = args['node_list']
tmp['node_health_check'] = args['node_health_check']
cfg[row] = tmp
writeConf(cfg)
makeLoadBalanceAllCfg(row)
mw.restartWeb()
return mw.returnJson(True, '修改成功', data)
def loadBalanceList():
cfg = getConf()
return mw.returnJson(True, 'ok', cfg)
def loadBalanceDelete():
args = getArgs()
data = checkArgs(args, ['row'])
if not data[0]:
return data[1]
row = int(args['row'])
cfg = getConf()
data = cfg[row]
import site_api
sobj = site_api.site_api()
sid = mw.M('sites').where('name=?', (data['domain'],)).getField('id')
if type(sid) == list:
del(cfg[row])
writeConf(cfg)
return mw.returnJson(False, '已经删除了!')
status = sobj.delete(sid, data['domain'], 1)
status_data = json.loads(status)
if status_data['status']:
del(cfg[row])
writeConf(cfg)
upstream_dir = mw.getServerDir() + '/web_conf/nginx/upstream'
rewrite_dir = mw.getServerDir() + '/web_conf/nginx/rewrite'
upstream_file = upstream_dir + '/' + data['upstream_name'] + '.conf'
if os.path.exists(upstream_file):
os.remove(upstream_file)
rewrite_file = rewrite_dir + '/' + data['domain'] + '.conf'
if os.path.exists(rewrite_file):
mw.writeFile(rewrite_file, '')
return mw.returnJson(status_data['status'], status_data['msg'])
def http_get(url):
ret = re.search(r'https://', url)
if ret:
try:
from gevent import monkey
monkey.patch_ssl()
import requests
ret = requests.get(url=str(url), verify=False, timeout=10)
status = [200, 301, 302, 404, 403]
if ret.status_code in status:
return True
else:
return False
except:
return False
else:
try:
if sys.version_info[0] == 2:
import urllib2
rec = urllib2.urlopen(url, timeout=3)
else:
import urllib.request
rec = urllib.request.urlopen(url, timeout=3)
status = [200, 301, 302, 404, 403]
if rec.getcode() in status:
return True
return False
except:
return False
def checkUrl():
args = getArgs()
data = checkArgs(args, ['ip', 'port', 'path'])
if not data[0]:
return data[1]
ip = args['ip']
port = args['port']
path = args['path']
if port == '443':
url = 'https://' + str(ip) + ':' + str(port) + str(path.strip())
else:
url = 'http://' + str(ip) + ':' + str(port) + str(path.strip())
ret = http_get(url)
if not ret:
return mw.returnJson(False, '访问节点[%s]失败' % url)
return mw.returnJson(True, '访问节点[%s]成功' % url)
def getHealthStatus():
args = getArgs()
data = checkArgs(args, ['row'])
if not data[0]:
return data[1]
row = int(args['row'])
cfg = getConf()
data = cfg[row]
url = 'http://' + data['domain'] + \
'/upstream_status_' + data['upstream_name']
url_data = mw.httpGet(url)
return mw.returnJson(True, 'ok', json.loads(url_data))
def getLogs():
args = getArgs()
data = checkArgs(args, ['domain'])
if not data[0]:
return data[1]
domain = args['domain']
logs = mw.getLogsDir() + '/' + domain + '.log'
return logs
if __name__ == "__main__":
func = sys.argv[1]
if func == 'status':
print(status())
elif func == 'start':
print(start())
elif func == 'stop':
print(stop())
elif func == 'restart':
print(restart())
elif func == 'reload':
print(reload())
elif func == 'install_pre_inspection':
print(installPreInspection())
elif func == 'add_load_balance':
print(addLoadBalance())
elif func == 'load_balance_list':
print(loadBalanceList())
elif func == 'load_balance_delete':
print(loadBalanceDelete())
elif func == 'check_url':
print(checkUrl())
elif func == 'get_logs':
print(getLogs())
elif func == 'get_health_status':
print(getHealthStatus())
else:
print('error')