mirror of https://github.com/midoks/mdserver-web
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.
478 lines
12 KiB
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')
|
|
|