Commit c2f9c745 authored by tarak.li's avatar tarak.li

自动出金二期,商城自动部署

parent bbb77cf6
...@@ -292,17 +292,23 @@ controllers = [ ...@@ -292,17 +292,23 @@ controllers = [
# 绑定支付宝账户 # 绑定支付宝账户
(r'/plugin/bind_pay_account', plugin.BindPayAccountHandler), (r'/plugin/bind_pay_account', plugin.BindPayAccountHandler),
# 账户状态 # 账户状态
(r'/micro_remote/plugin/account_status', plugin.AccountStatusHandler), (r'/plugin/account_status', plugin.AccountStatusHandler),
# 主机监控状态
(r'/plugin/host_monitor', plugin.HostMonitorHandler),
# 账户账户密码获取 # 账户账户密码获取
(r'/plugin/account_info', plugin.AccountInfoHandler),
(r'/micro_remote/plugin/account_info', plugin.AccountInfoHandler), # 商城狀態查詢
(r'/plugin/shop_info', plugin.ShopInfoHandler),
# 商城綁定接口
(r'/plugin/shop_bind', plugin.ShopBindHandler),
# 密码修改
(r'/plugin/password_update', plugin.PasswordUpdateHandler),
# 下载地址获取接口
(r'/plugin/bat_download_url', plugin.BatDownloadHandler),
# websocket for real-time information # websocket for real-time information
# ws-client call 'http://ip:7190/ws/action/' # ws-client call 'http://ip:7190/ws/action/'
(r'/ws/(.*)', ws.WebSocketHandler), (r'/ws/(.*)', ws.WebSocketHandler),
(r'/.*', index.CatchAllHandler), (r'/.*', index.CatchAllHandler),
] ]
......
...@@ -15,6 +15,7 @@ from concurrent.futures import ThreadPoolExecutor ...@@ -15,6 +15,7 @@ from concurrent.futures import ThreadPoolExecutor
from tornado.escape import json_decode, json_encode from tornado.escape import json_decode, json_encode
from tornado.concurrent import run_on_executor from tornado.concurrent import run_on_executor
import tornado.web import tornado.web
from app.base.core_server import core_service_async_enc
from app.base.controller import TPBaseHandler from app.base.controller import TPBaseHandler
from app.base.logger import * from app.base.logger import *
from app.const import * from app.const import *
...@@ -25,9 +26,6 @@ from pyDes import des, CBC, PAD_PKCS5 ...@@ -25,9 +26,6 @@ from pyDes import des, CBC, PAD_PKCS5
import math import math
# todo 间歇性 ERROR:tornado.application:Uncaught exception
def current_ip(): def current_ip():
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.connect(("8.8.8.8", 80)) s.connect(("8.8.8.8", 80))
...@@ -161,10 +159,8 @@ class TPBasePluginHandler(TPBaseHandler): ...@@ -161,10 +159,8 @@ class TPBasePluginHandler(TPBaseHandler):
@run_on_executor @run_on_executor
def request_api(self, url, data=None, json=None, method="post"): def request_api(self, url, data=None, json=None, method="post"):
_user = {'id': 1, 'type': 1, 'auth_type': 2, 'username': 'admin', 'surname': 'admin', 'ldap_dn': '', _user = {'id': 1, 'type': 1, 'auth_type': 2, 'username': 'admin', 'surname': 'admin', 'ldap_dn': '',
'role_id': 1, 'role_id': 1, 'state': 1, 'fail_count': 0, 'lock_time': 0, 'email': '', 'create_time': 0,
'state': 1, 'fail_count': 0, 'lock_time': 0, 'email': '929749555@qq.com', 'create_time': 1583104533, 'last_login': 0, 'last_ip': '', 'last_chpass': 0, 'mobile': '', 'qq': '',
'last_login': 1583788567, 'last_ip': '172.30.10.106', 'last_chpass': 1583104533, 'mobile': '',
'qq': '',
'wechat': '', 'desc': '', 'role': '系统管理员', 'privilege': 4294967295, '_is_login': True} 'wechat': '', 'desc': '', 'role': '系统管理员', 'privilege': 4294967295, '_is_login': True}
self._s_id = "tp_1583808860_5c0a3c718114f429" self._s_id = "tp_1583808860_5c0a3c718114f429"
self.set_session('user', _user, 12 * 60 * 60) self.set_session('user', _user, 12 * 60 * 60)
...@@ -224,7 +220,7 @@ class UpdateHostHandler(TPBasePluginHandler): ...@@ -224,7 +220,7 @@ class UpdateHostHandler(TPBasePluginHandler):
{"id": -1, "os_type": os_type, "ip": ip, "router_ip": "", "router_port": 0, "name": name, "cid": assets_num, {"id": -1, "os_type": os_type, "ip": ip, "router_ip": "", "router_port": 0, "name": name, "cid": assets_num,
"desc": desc}).encode()} "desc": desc}).encode()}
# 带信息先插入 # 带信息先插入
resp = yield self.request_api(url, args) resp = yield self.request_api(url, args)
# {"code": 0, "message": "", "data": 7} # {"code": 0, "message": "", "data": 7}
if resp.get("code") == 8: if resp.get("code") == 8:
...@@ -254,8 +250,9 @@ class UpdateHostHandler(TPBasePluginHandler): ...@@ -254,8 +250,9 @@ class UpdateHostHandler(TPBasePluginHandler):
# acc_id = resp.get("data") # acc_id = resp.get("data")
password = des_encrypt(password).decode()
args = {"host_id": host_id, "name": name, "ip": ip, "remark": desc, "username": username, args = {"host_id": host_id, "name": name, "ip": ip, "remark": desc, "username": username,
"password": "", "assets_num": assets_num, "os_type": os_type, "status": status} "password": password, "assets_num": assets_num, "os_type": os_type, "status": status}
err, info = plugin.add_remote_host(self, args) err, info = plugin.add_remote_host(self, args)
if err == TPE_OK: if err == TPE_OK:
...@@ -303,10 +300,7 @@ class UpdateHostHandler(TPBasePluginHandler): ...@@ -303,10 +300,7 @@ class UpdateHostHandler(TPBasePluginHandler):
# 带信息带先插入 # 带信息带先插入
resp = yield self.request_api(url, args) resp = yield self.request_api(url, args)
# {"code": 0, "message": "", "data": 7} # {"code": 0, "message": "", "data": 7}
if resp.get("code") == 8: if resp.get("code") != 0:
self.finish_json(1003, "已存在主机,不可重复添加")
return
elif resp.get("code") != 0:
self.finish_json(1003, "修改主机异常") self.finish_json(1003, "修改主机异常")
return return
...@@ -333,7 +327,8 @@ class UpdateHostHandler(TPBasePluginHandler): ...@@ -333,7 +327,8 @@ class UpdateHostHandler(TPBasePluginHandler):
self.finish_json(1004, "添加服务器账户异常") self.finish_json(1004, "添加服务器账户异常")
return return
args = {"os_type": os_type, "ip": ip, "username": username, "password": "", "name": name, "remark": desc, password = des_encrypt(password).decode()
args = {"os_type": os_type, "ip": ip, "username": username, "password": password, "name": name, "remark": desc,
"id": host_id, "assets_num": assets_num, "status": status} "id": host_id, "assets_num": assets_num, "status": status}
# 调用更新接口 # 调用更新接口
...@@ -371,8 +366,7 @@ class GetHostListHandler(TPBasePluginHandler): ...@@ -371,8 +366,7 @@ class GetHostListHandler(TPBasePluginHandler):
sql_limit['page_index'] = page_index - 1 if page_index - 1 > 0 else 0 sql_limit['page_index'] = page_index - 1 if page_index - 1 > 0 else 0
sql_limit['per_page'] = page_size sql_limit['per_page'] = page_size
err, total_count, index, row_data = \ err, total_count, index, row_data = plugin.get_host_list(sql_limit, os_type, ip, name, status)
plugin.get_host_list(sql_limit, os_type, ip, name, status)
ret = dict() ret = dict()
ret['page_index'] = index ret['page_index'] = index
ret['total'] = total_count ret['total'] = total_count
...@@ -381,6 +375,7 @@ class GetHostListHandler(TPBasePluginHandler): ...@@ -381,6 +375,7 @@ class GetHostListHandler(TPBasePluginHandler):
host_ids = [str(item['id']) for item in row_data if item['id']] host_ids = [str(item['id']) for item in row_data if item['id']]
bind = plugin.get_bind_info(host_ids) bind = plugin.get_bind_info(host_ids)
shop_bind = plugin.get_shop_bind_info(host_ids)
for item in row_data: for item in row_data:
item['desc'] = item.pop("remark", "") item['desc'] = item.pop("remark", "")
item['host_id'] = item.pop("id", 0) item['host_id'] = item.pop("id", 0)
...@@ -389,6 +384,9 @@ class GetHostListHandler(TPBasePluginHandler): ...@@ -389,6 +384,9 @@ class GetHostListHandler(TPBasePluginHandler):
# 绑定详情 # 绑定详情
# bind = plugin.get_bind_info([item['host_id']]) # bind = plugin.get_bind_info([item['host_id']])
item['bind'] = [info for info in bind if int(info.get("host_id", 0)) == int(item.get("host_id", 0))] item['bind'] = [info for info in bind if int(info.get("host_id", 0)) == int(item.get("host_id", 0))]
if item['os_type'] == 2:
item['bind'] = [info for info in shop_bind if
int(info.get("host_id", 0)) == int(item.get("host_id", 0))]
pg = {"dataCount": total_count, "pageIndex": page_index, "pageSize": page_size, pg = {"dataCount": total_count, "pageIndex": page_index, "pageSize": page_size,
"pageTotal": math.ceil(total_count / page_size)} "pageTotal": math.ceil(total_count / page_size)}
...@@ -568,6 +566,7 @@ class BindPayAccountHandler(TPBasePluginHandler): ...@@ -568,6 +566,7 @@ class BindPayAccountHandler(TPBasePluginHandler):
if not host_id: if not host_id:
if int(host_assigned) == 1: if int(host_assigned) == 1:
# 查询已分配过的主机 # 查询已分配过的主机
# todo 自動分配,正常監聽的主機
host_id = self.query("remote_account_host_bind", "host_id", {"mch_no": mch_no}) host_id = self.query("remote_account_host_bind", "host_id", {"mch_no": mch_no})
# 自动分配功能 # 自动分配功能
if not host_id: if not host_id:
...@@ -592,6 +591,7 @@ class BindPayAccountHandler(TPBasePluginHandler): ...@@ -592,6 +591,7 @@ class BindPayAccountHandler(TPBasePluginHandler):
resp = await self.request_api(url, json=data, method="put") resp = await self.request_api(url, json=data, method="put")
# host_id = resp.get("data", 0) # host_id = resp.get("data", 0)
# todo 未監聽主機不允許綁定支付寶
if not host_id: if not host_id:
self.finish_json(1010, "无法找到对应主机信息") self.finish_json(1010, "无法找到对应主机信息")
return return
...@@ -706,10 +706,6 @@ class AccountStatusHandler(TPBasePluginHandler): ...@@ -706,10 +706,6 @@ class AccountStatusHandler(TPBasePluginHandler):
class AccountInfoHandler(TPBasePluginHandler): class AccountInfoHandler(TPBasePluginHandler):
def key(self, timestamp):
key = '{}{}'.format(KEY, timestamp)
return
async def post(self): async def post(self):
prop = self.get_payload() prop = self.get_payload()
info = prop.get("info") or "" info = prop.get("info") or ""
...@@ -736,3 +732,234 @@ class AccountInfoHandler(TPBasePluginHandler): ...@@ -736,3 +732,234 @@ class AccountInfoHandler(TPBasePluginHandler):
self.finish_json(0, data=[{"info": data, "timestamp": timestamp}]) self.finish_json(0, data=[{"info": data, "timestamp": timestamp}])
else: else:
self.finish_json(1001, "传递参数错误") self.finish_json(1001, "传递参数错误")
class ShopInfoHandler(TPBasePluginHandler):
async def get(self):
try:
host_id = self.get_argument("host_id", 0)
try:
host_id = int(host_id)
except:
self.finish_json(1001, "提交参数异常,请检查请求参数")
return
if not host_id:
self.finish_json(1001, "缺少必填项")
return
items = plugin.query_one("remote_shop_bind", ['name', 'domain', 'url', 'status'], {"host_id": host_id})
if items:
self.finish_json(0, data=[items])
else:
self.finish_json(0, data=[{}])
except:
info = traceback.format_exc()
log.e("设备详情,异常信息:{}".format(info))
async def post(self):
try:
props = self.get_payload()
host_id = props.get("host_id") or 0
try:
host_id = int(host_id)
except:
self.finish_json(1001, "提交参数异常,请检查请求参数")
return
if not host_id:
self.finish_json(1001, "缺少必填项")
return
items = plugin.query_one("remote_shop_bind", ['name', 'domain', 'url', 'status'], {"host_id": host_id})
if items:
self.finish_json(0, data=[items])
else:
self.finish_json(0, data=[{}])
except:
info = traceback.format_exc()
log.e("设备详情,异常信息:{}".format(info))
class ShopBindHandler(TPBasePluginHandler):
async def post(self):
try:
props = self.get_payload()
host_id = props.get("host_id") or 0
name = props.get("name") or ""
domain = props.get("domain") or ""
try:
host_id = int(host_id)
except:
self.finish_json(1001, "提交参数异常,请检查请求参数")
return
if not name or not domain:
self.finish_json(1001, "缺少必填项")
return
items = plugin.query_one("remote_shop_bind", ['name', 'domain', 'url', 'status'], {"host_id": host_id})
if items:
self.finish_json(1003, "已存在绑定商城,不可重复绑定")
return
items = plugin.query_one("host", ['os_type'], {"id": host_id})
if not items:
self.finish_json(1003, "绑定主机不存在")
return
if items.get("os_type", 0) != 2:
self.finish_json(1003, "仅支持Linux主机进行绑定")
return
args = {"host_id": host_id, "name": name, "domain": domain, "status": 0}
err, info = plugin.add_shop_bind(self, args)
if err == TPE_OK:
self.finish_json(0, "成功")
else:
self.finish_json(1002, "绑定商城信息失败")
# todo 调用商城自动部署
except:
info = traceback.format_exc()
log.e("设备详情,异常信息:{}".format(info))
async def put(self):
try:
props = self.get_payload()
host_id = props.get("host_id") or 0
name = props.get("name") or ""
domain = props.get("domain") or ""
try:
host_id = int(host_id)
except:
self.finish_json(1001, "提交参数异常,请检查请求参数")
return
if not host_id or not name or not domain:
self.finish_json(1001, "缺少必填项")
return
items = plugin.query_one("remote_shop_bind", ['name', 'domain', 'url', 'status'], {"host_id": host_id})
status = items.get("status", 0)
# todo 实时判断商城状态
if status == 1:
self.finish_json(1021, "运行中商城,不可变更")
return
plugin.update("tp_remote_shop_bind", {"name": name, "domain": domain}, {"host_id": host_id})
# todo 变更状态脚本
self.finish_json(0)
except:
info = traceback.format_exc()
log.e("设备详情,异常信息:{}".format(info))
class PasswordUpdateHandler(TPBasePluginHandler):
@tornado.gen.coroutine
def post(self):
try:
props = self.get_payload()
old_pwd = props.get("old_pwd") or ""
pwd = props.get("pwd") or ""
type = props.get("type") or ""
host_id = props.get("host_id") or ""
account = props.get("account") or ""
try:
host_id = int(host_id)
except:
self.finish_json(1001, "提交参数异常,请检查请求参数")
return
if not old_pwd or not pwd or not type or not host_id or not account:
self.finish_json(1001, "缺少必填项")
return
if type != 'alipay' and type != 'host':
self.finish_json(1001, "不支持的修改类型")
return
items = plugin.query_one("host", ['os_type'], {"id": host_id})
if not items:
self.finish_json(1003, "绑定主机不存在")
return
if items.get("os_type", 0) != 2:
self.finish_json(1003, "仅支持Linux主机进行绑定")
return
if type == 'alipay':
items = plugin.query_one("remote_account_host_bind", ['password'],
{"host_id": host_id, "account": account})
password = items.get("password", "")
if password != des_encrypt(old_pwd).decode():
self.finish_json(1003, "密码验证失败,请确认原密码")
return
des_password = des_encrypt(pwd).decode()
err = plugin.update("tp_remote_account_host_bind", {"password": des_password, },
{"host_id": host_id, "account": account})
if err == TPE_OK:
self.finish_json(0, "成功")
return
else:
items = plugin.query_one("remote_host", ['password'], {"id": host_id, "username": account})
password = items.get("password", "")
if password and password != des_encrypt(old_pwd).decode():
self.finish_json(1003, "密码验证失败,请确认原密码")
return
code, ret_data = yield core_service_async_enc(pwd)
if code != TPE_OK or not ret_data:
self.finish_json(1003, "无法加密存储私钥")
return
err = plugin.update("tp_acc", {"password": ret_data, }, {"host_id": host_id, "account": account})
err = plugin.update("tp_remote_host", {"password": des_encrypt(pwd).decode(), },
{"id": host_id, "account": account})
if err == TPE_OK:
self.finish_json(0, "成功")
return
except:
info = traceback.format_exc()
log.e("设备详情,异常信息:{}".format(info))
class HostMonitorHandler(TPBasePluginHandler):
async def post(self):
try:
props = self.get_payload()
ip = props.get("ip") or ""
status = props.get("status") or 0
if not ip or not status:
self.finish_json(1001, "缺少必填项")
return
items = plugin.query_one("remote_host", ['id', ], {"ip": ip})
if not items:
self.finish_json(1002, "未发现对应主机")
return
err = plugin.update("tp_remote_host", {"status": status}, {"ip": ip, })
if err == TPE_OK:
self.finish_json(0, "成功")
else:
self.finish_json(1002, "更新主机状态失败")
except:
info = traceback.format_exc()
log.e("设备详情,异常信息:{}".format(info))
class BatDownloadHandler(TPBasePluginHandler):
async def get(self):
try:
self.finish_json(0, "成功", data=[{"url": "http://121.196.33.88:5566/download/bat"}])
except:
info = traceback.format_exc()
log.e("设备详情,异常信息:{}".format(info))
...@@ -66,6 +66,25 @@ def get_bind_info(host_id): ...@@ -66,6 +66,25 @@ def get_bind_info(host_id):
return bind return bind
def get_shop_bind_info(host_id):
s = SQL(get_db())
s.select_from('remote_shop_bind',
['host_id', 'name', 'domain', 'url', 'status', 'username', 'password',
'remark', 'create_time'], alt_name='a')
# 判断
if host_id:
s.where('a.host_id in ({host_ids})'.format(host_ids=','.join(host_id)))
err = s.query()
if err != TPE_OK:
return err, None
bind = s.recorder
for item in bind:
item['password'] = "******"
return bind
def get_account_info(host_id, mch_no): def get_account_info(host_id, mch_no):
s = SQL(get_db()) s = SQL(get_db())
s.select_from('remote_account_host_bind', s.select_from('remote_account_host_bind',
...@@ -394,3 +413,30 @@ def update(table: str, fields: dict, where: dict): ...@@ -394,3 +413,30 @@ def update(table: str, fields: dict, where: dict):
return TPE_DATABASE return TPE_DATABASE
return TPE_OK return TPE_OK
def add_shop_bind(handler, args):
db = get_db()
_time_now = tp_timestamp_utc_now()
operator = handler.get_current_user()
sql = 'INSERT INTO `tp_remote_shop_bind` (host_id, name, domain, url, status, username, password, remark, create_time, create_by, update_time, update_by) VALUES ' \
'({host_id}, "{name}", "{domain}", "{url}", {status}, "{username}", "{password}", "{remark}", "{create_time}", "{create_by}", "{update_time}", "{update_by}");' \
''.format(host_id=args.get("host_id", 0), name=args.get("name", ""), domain=args.get("domain", ""),
url=args.get("url", ""), status=args.get("status", 0), username=args.get("username", ""),
password=args.get("password", ""), remark=args.get("remark", ""), create_time=_time_now,
create_by=operator['id'], update_time=_time_now, update_by=operator['id'], )
db_ret = db.exec(sql)
if not db_ret:
return TPE_DATABASE, 0
_id = db.last_insert_id()
# acc_name = '{}@{}'.format(args['username'], args['host_ip'])
# if len(args['router_ip']) > 0:
# acc_name += '(由{}:{}路由)'.format(args['router_ip'], args['router_port'])
# syslog.sys_log(operator, handler.request.remote_ip, TPE_OK, "创建账号:{}".format(acc_name))
# 更新主机相关账号数量
return TPE_OK, _id
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment