Commit fa6e8a60 authored by BH's avatar BH

20210106 调试后提交

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