Commit fa6e8a60 authored by BH's avatar BH

20210106 调试后提交

parent f36206bd
...@@ -6,6 +6,7 @@ import re ...@@ -6,6 +6,7 @@ import re
import time import time
import traceback import traceback
from collections import namedtuple
import requests import requests
from concurrent.futures import ThreadPoolExecutor from concurrent.futures import ThreadPoolExecutor
...@@ -29,10 +30,12 @@ from plugin.remote import auto_install_bt, install_docker ...@@ -29,10 +30,12 @@ from plugin.remote import auto_install_bt, install_docker
import rsa import rsa
from plugin.utils import current_ip, network_ip, des_encrypt, des_descrypt, md5, is_domain, is_ipv4, KEY, new_keys from plugin.utils import current_ip, network_ip, des_encrypt, des_descrypt, md5, is_domain, is_ipv4, KEY, new_keys, \
timestamp
free_cache = {} free_cache = {}
token_cache = {} token_cache = {}
Token = namedtuple("Token", ['v', 't'])
def execute_add_proxy(ip): def execute_add_proxy(ip):
...@@ -65,7 +68,7 @@ class TPBasePluginHandler(TPBaseHandler): ...@@ -65,7 +68,7 @@ class TPBasePluginHandler(TPBaseHandler):
auto_install_bt(ip, username, password, site, webname, sub) auto_install_bt(ip, username, password, site, webname, sub)
@run_on_executor(executor='_remote_executor') @run_on_executor(executor='_remote_executor')
async def install_docker(self, host_id, ip, username, password): def install_docker(self, host_id, ip, username, password):
pubkey = self.rsa_pubkey(host_id) pubkey = self.rsa_pubkey(host_id)
with open('{}.pem'.format(ip), 'w+') as f: with open('{}.pem'.format(ip), 'w+') as f:
f.write(pubkey) f.write(pubkey)
...@@ -192,12 +195,13 @@ class UpdateHostHandler(TPBasePluginHandler): ...@@ -192,12 +195,13 @@ class UpdateHostHandler(TPBasePluginHandler):
def req_parse(self, required: tuple = ()): def req_parse(self, required: tuple = ()):
self.parse = reqparse.RequestParser() self.parse = reqparse.RequestParser()
# todo 验证错误
self.parse.add_argument("os_type", type=int, help='系统类型', required='host_id' in required, choices=[1, 2]) self.parse.add_argument("os_type", type=int, help='系统类型', required='host_id' in required, choices=[1, 2])
self.parse.add_argument("host_id", type=int, required='host_id' in required, default=0) self.parse.add_argument("host_id", type=int, required='host_id' in required, default=0)
self.parse.add_argument("status", type=int, help='服务器状态', default=0) self.parse.add_argument("status", type=int, help='服务器状态', default=0)
self.parse.add_argument("ip", type=str, help='远程服务器IP', required='ip' in required, trim=True) self.parse.add_argument("ip", type=str, help='远程服务器IP', required='ip' in required, default='')
self.parse.add_argument("username", type=str, help='服务器用户名', required='username' in required, trim=True) self.parse.add_argument("username", type=str, help='服务器用户名', required='username' in required, default='')
self.parse.add_argument("password", type=str, help='服务器密码', required='password' in required, trim=True) self.parse.add_argument("password", type=str, help='服务器密码', required='password' in required, default='')
self.parse.add_argument("name", type=str, help='服务器命名', default='') self.parse.add_argument("name", type=str, help='服务器命名', default='')
self.parse.add_argument("desc", type=str, help='服务器IP', default='') self.parse.add_argument("desc", type=str, help='服务器IP', default='')
self.parse.add_argument("mch_no", type=str, help='商户号', ) self.parse.add_argument("mch_no", type=str, help='商户号', )
...@@ -269,7 +273,7 @@ class UpdateHostHandler(TPBasePluginHandler): ...@@ -269,7 +273,7 @@ class UpdateHostHandler(TPBasePluginHandler):
@tornado.gen.coroutine @tornado.gen.coroutine
def put(self): def put(self):
# 增加 host_id # 增加 host_id
args = self.req_parse(('host_id',)) args = self.req_parse(('host_id', 'os_type', 'ip', 'username'))
ip, os_type, name, desc, username, password, status, host_id = args.ip, args.os_type, args.name, args.desc, args.username, args.password, args.status, args.host_id ip, os_type, name, desc, username, password, status, host_id = args.ip, args.os_type, args.name, args.desc, args.username, args.password, args.status, args.host_id
assets_num = self.generate_assets_num(ip, os_type) assets_num = self.generate_assets_num(ip, os_type)
...@@ -624,8 +628,8 @@ class BindPayAccountHandler(TPBasePluginHandler): ...@@ -624,8 +628,8 @@ class BindPayAccountHandler(TPBasePluginHandler):
item = item[0] item = item[0]
password = des_descrypt(item.get("password", "")).decode() password = des_descrypt(item.get("password", "")).decode()
await self.add_members(biz_id, host_id) self.install_docker(host_id, item['ip'], item['username'], password)
await self.install_docker(host_id, item['ip'], item['username'], password) # await self.add_members(biz_id, host_id)
async def put(self): async def put(self):
args = self.req_parse() args = self.req_parse()
...@@ -635,7 +639,8 @@ class BindPayAccountHandler(TPBasePluginHandler): ...@@ -635,7 +639,8 @@ class BindPayAccountHandler(TPBasePluginHandler):
self.finish_json(1001, "传入密码异常") self.finish_json(1001, "传入密码异常")
return return
item = self.plugin_query("tp_remote_account_host_bind", {"host_id": host_id, "mch_no": mch_no}, item = self.plugin_query("tp_remote_account_host_bind",
{"host_id": host_id, "mch_no": mch_no, "account": account},
['id', 'account', 'comp_id']) ['id', 'account', 'comp_id'])
# 云平台 mch_no 为可选 # 云平台 mch_no 为可选
if not item: if not item:
...@@ -645,7 +650,7 @@ class BindPayAccountHandler(TPBasePluginHandler): ...@@ -645,7 +650,7 @@ class BindPayAccountHandler(TPBasePluginHandler):
if not item: if not item:
self.finish_json(2002, "设备不存在") self.finish_json(2002, "设备不存在")
return return
item = item[0]
# 允许未绑定账户的主机进行修改 # 允许未绑定账户的主机进行修改
if item['account'] and account != item['account']: if item['account'] and account != item['account']:
self.finish_json(2002, "不允许修改绑定账户") self.finish_json(2002, "不允许修改绑定账户")
...@@ -820,8 +825,7 @@ class ShopBindHandler(TPBasePluginHandler): ...@@ -820,8 +825,7 @@ class ShopBindHandler(TPBasePluginHandler):
password = des_descrypt(items.get("password", "")).decode() password = des_descrypt(items.get("password", "")).decode()
await self.install_bt(items.get("ip", ""), items.get("username", ""), password, args.domain, args.name, await self.install_bt(items.get("ip", ""), items.get("username", ""), password, args.domain, args.name,
args.sub_domain) args.sub_domain)
# todo log.i("自动部署商城:{}".format(items.get("ip", "")))
log.i("自动部署商城:{}".format(""))
else: else:
self.finish_json(1002, "绑定商城信息失败") self.finish_json(1002, "绑定商城信息失败")
except: except:
...@@ -959,23 +963,25 @@ class TokenHandler(TPBasePluginHandler): ...@@ -959,23 +963,25 @@ class TokenHandler(TPBasePluginHandler):
try: try:
args = self.req_parse() args = self.req_parse()
agent = self.request.headers.get("User-agent") agent = self.request.headers.get("User-agent")
timestamp = int(time.time()) _t = timestamp()
log.i("token md5:{} \n".format(agent + args.ip + str(timestamp))) log.i("token md5:{} \n".format(agent + args.ip + str(_t)))
token = md5(agent + args.ip + str(timestamp)) token = md5(agent + args.ip + str(_t))
privkey = self.plugin_param('tp_remote_host_key', {"host_id": args.host_id}, "privkey") privkey = self.plugin_param('tp_remote_host_key', {"host_id": args.host_id}, "privkey")
if not privkey: if not privkey:
self.finish_json(1001, "host_id 未绑定账户", data=[]) self.finish_json(1001, "host_id 未绑定账户", data=[])
return return
ip = self.plugin_param("tp_remote_host", {"id": args.host_id}, "ip")
# RSA 私钥加密token信息
privkey = rsa.PrivateKey.load_pkcs1(privkey.encode()) privkey = rsa.PrivateKey.load_pkcs1(privkey.encode())
crypto_email_text = rsa.sign(token.encode(), privkey, 'SHA-1') crypto_email_text = rsa.sign(token.encode(), privkey, 'SHA-1')
msg = base64.b64encode(crypto_email_text).decode() msg = base64.b64encode(crypto_email_text).decode()
# 读取远程主机ip # 读取远程主机ip
url = "http://172.30.20.120:8080/token" url = "http://{}:8080/token".format(ip)
resp = requests.post(url, headers={"user-agent": agent}, resp = requests.post(url, headers={"user-agent": agent},
data={"ip": args.ip, "msg": msg, "timestamp": timestamp}) data={"ip": args.ip, "msg": msg, "timestamp": _t})
print(resp.text) print(resp.text)
if resp.text == 'ok': if resp.text == 'ok':
token_cache[args.ip] = token token_cache[args.ip] = Token(token, timestamp())
self.finish_json(0, "成功", data=[{"token": token}]) self.finish_json(0, "成功", data=[{"token": token}])
else: else:
self.finish_json(1001, "失败", data=[]) self.finish_json(1001, "失败", data=[])
...@@ -1002,26 +1008,26 @@ class GetVNCInfoHandler(TPBasePluginHandler): ...@@ -1002,26 +1008,26 @@ class GetVNCInfoHandler(TPBasePluginHandler):
return return
password = self.plugin_param("tp_remote_account_host_bind", {"host_id": host_id, "account": username}, password = self.plugin_param("tp_remote_account_host_bind", {"host_id": host_id, "account": username},
"password") "password")
if not password:
self.finish_json(1001, "无法获取绑定信息", data=[])
return
password = des_descrypt(password).decode() password = des_descrypt(password).decode()
ip = self.plugin_param("tp_remote_host", {"id": host_id, }, "ip") ip = self.plugin_param("tp_remote_host", {"id": host_id, }, "ip")
pubkey = self.plugin_param("tp_remote_host_key", {"host_id": host_id, }, "pubkey") pubkey = self.plugin_param("tp_remote_host_key", {"host_id": host_id, }, "pubkey")
log.i(pubkey) log.i(pubkey)
log.i(md5(pubkey.strip())) log.i(md5(pubkey.strip()))
# todo token的有效时常
token = token_cache.get(ip) token = token_cache.get(ip)
if not token: if not token or timestamp() - token.t > 600:
url = "http://127.0.0.1:7190/plugin/token" url = "http://127.0.0.1:7190/plugin/token"
# todo 获取发起请求ip
await self.request_api(url, json={"ip": ip, "host_id": host_id}) await self.request_api(url, json={"ip": ip, "host_id": host_id})
token = token_cache.get(ip) token = token_cache.get(ip)
# todo
# url = "http://{}:8000/login".format("127.0.0.1") # url = "http://{}:8000/login".format("127.0.0.1")
url = "http://{}:8080/login".format(ip) url = "http://{}:8080/login".format(ip)
log.i(md5(pubkey)[:8]) log.i(md5(pubkey)[:8])
body = base64.b64encode( body = base64.b64encode(
des_encrypt(json.dumps({"account": username, "password": password}), des_encrypt(json.dumps({"account": username, "password": password}),
key=md5(pubkey.strip())[:8])).decode() key=md5(pubkey.strip())[:8])).decode()
resp = requests.post(url, data={"body": body}, cookies={'token': token}) resp = requests.post(url, data={"body": body}, cookies={'token': token.v})
log.i(resp.text) log.i(resp.text)
# todo 添加账户密码信息 # todo 添加账户密码信息
url = "http://{}:8083/vnc.html".format(ip) url = "http://{}:8083/vnc.html".format(ip)
......
...@@ -236,7 +236,7 @@ class Argument(object): ...@@ -236,7 +236,7 @@ class Argument(object):
) )
self.handle_validation_error(ValueError(error_msg), bundle_errors) self.handle_validation_error(ValueError(error_msg), bundle_errors)
if not results: if not results or not results[0]:
if callable(self.default): if callable(self.default):
return self.default(), _not_found return self.default(), _not_found
else: else:
...@@ -310,10 +310,11 @@ class RequestParser(object): ...@@ -310,10 +310,11 @@ class RequestParser(object):
# A record of arguments not yet parsed; as each is found # A record of arguments not yet parsed; as each is found
# among self.args, it will be popped out # among self.args, it will be popped out
# todo 严格筛选处理 # 严格筛选处理
unparsed_arguments = dict(self.argument_class('').source(req)) if strict else {} unparsed_arguments = dict(self.argument_class('').source(req)) if strict else {}
errors = {} errors = {}
for arg in self.args: for arg in self.args:
# 可选类型返回
value, found = arg.parse(req, self.bundle_errors) value, found = arg.parse(req, self.bundle_errors)
if isinstance(value, ValueError): if isinstance(value, ValueError):
errors.update(found) errors.update(found)
......
...@@ -153,16 +153,34 @@ def auto_install_bt(ip, username, password, site, webname, sub="", host_id=0): ...@@ -153,16 +153,34 @@ def auto_install_bt(ip, username, password, site, webname, sub="", host_id=0):
transport.close() transport.close()
def install_docker(ip, username, password, pubkey): def yum_check_install(ssh, package):
ssh = create_ssh(ip, username, password) res = ssh_command(ssh, "yum list installed {}.*".format(package))
# todo yum 正在允许会阻塞进程 if "No matching Packages to list" in res:
log.i() return False
return True
def docker_init(ssh, ip):
"""
docker 环境初始化
:param ssh:
:param ip:
:return:
"""
# 判断是否安装docker
if not yum_check_install(ssh, "docker"):
res = ssh_command(ssh, "yum install -y docker") res = ssh_command(ssh, "yum install -y docker")
if "Complete!" in res or "already installed" in res or '完毕!' in res: # if "Complete!" not in res and '完毕!' not in res:
update_docker_info(ip, 0, "完成 docker 安装") update_docker_info(ip, 0, "完成 docker 安装")
res = ssh_command(ssh, "systemctl start docker") res = ssh_command(ssh, "systemctl start docker")
if not res: if not res:
update_docker_info(ip, 0, "启动 docker 服务") update_docker_info(ip, 0, "启动 docker 服务")
def install_docker(ip, username, password, pubkey):
ssh = create_ssh(ip, username, password)
docker_init(ssh, ip)
# 生成 rsa 公私钥,保存 # 生成 rsa 公私钥,保存
res = ssh_command(ssh, "mkdir -p /root/build") res = ssh_command(ssh, "mkdir -p /root/build")
temp_file = '/tmp/{}.pem'.format(int(time.time())) temp_file = '/tmp/{}.pem'.format(int(time.time()))
......
# coding: utf-8 # coding: utf-8
import re import re
import socket import socket
import time
import requests import requests
import binascii import binascii
...@@ -79,5 +80,9 @@ def new_keys(): ...@@ -79,5 +80,9 @@ def new_keys():
return pubkey.save_pkcs1().decode(), privkey.save_pkcs1().decode() return pubkey.save_pkcs1().decode(), privkey.save_pkcs1().decode()
def timestamp():
return int(time.time())
if __name__ == '__main__': if __name__ == '__main__':
print(new_keys()) print(new_keys())
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