Commit 2d39fb27 authored by tarak.li's avatar tarak.li

优化代码,场景测试

parent c2f9c745
......@@ -312,12 +312,17 @@ class AppConfig(BaseAppConfig):
self.set_default('database::mysql-user', 'teleport', 'mysql-user=teleport')
self.set_default('database::mysql-password', 'password', 'mysql-password=password')
self.set_default('plugin::core_host', '127.0.0.1', 'core_host=127.0.0.1')
self.set_default('plugin::consul', '127.0.0.1', 'consul=http://172.30.10.128:6010')
self.set_default('plugin::release_ip', '127.0.0.1', 'release_ip=127.0.0.1')
self.set_default('plugin::server', '127.0.0.1', 'server=127.0.0.1')
def _on_get_save_info(self):
return [
{'common': ['ip', 'port', 'log-file', 'log-level', 'debug-mode', 'core-server-rpc']},
{'database': ['type', 'sqlite-file', 'mysql-host', 'mysql-port', 'mysql-db', 'mysql-prefix', 'mysql-user',
'mysql-password']},
{"plugin": ["core_host", "consul"]}
{"plugin": ["core_host", "consul", "release_ip", "server"]}
]
def _on_load(self, cfg_parser):
......@@ -400,6 +405,14 @@ class AppConfig(BaseAppConfig):
if _tmp_str is not None:
self.set_kv('plugin::consul', _tmp_str)
_tmp_str = _sec.get('release_ip', None)
if _tmp_str is not None:
self.set_kv('plugin::release_ip', _tmp_str)
_tmp_str = _sec.get('server', None)
if _tmp_str is not None:
self.set_kv('plugin::server', _tmp_str)
_log_file, ok = self.get_str('common::log-file')
if ok and _log_file:
self.log_path = os.path.abspath(os.path.dirname(_log_file))
......
......@@ -33,6 +33,8 @@ class DatabaseInit:
self._create_syslog()
self._create_record()
self._create_record_audit()
self._create_remonte_host()
self._create_bind_remote_host()
self._make_builtin_data(sysadmin, email, password)
except:
log.e('[db] can not create and initialize database.\n')
......@@ -819,12 +821,86 @@ class DatabaseInit:
'CREATE TABLE `{}record_audit` ({});'.format(self.db.table_prefix, ','.join(f))
)
def _create_remonte_host(self):
f = list()
# id: 自增主键
f.append('`id` bigint(20) PRIMARY KEY {}'.format(self.db.auto_increment))
f.append('`app_id` varchar(20) DEFAULT NULL')
# 资产编号
f.append('`assets_num` varchar(20) DEFAULT ""')
# 主机系统 1:windows 2 linux
f.append('`os_type` tinyint(6) DEFAULT 1')
# 主机地址
f.append('`ip` varchar(20) DEFAULT ""')
# 主机状态 '0:断开 1:正常',
f.append('`status` tinyint(6) DEFAULT 0')
# 账号
f.append('`username` varchar(100) DEFAULT ""')
# 密码
f.append('`password` varchar(500) DEFAULT ""')
# 名称
f.append('`name` varchar(100) DEFAULT ""')
# 备注
f.append('`remark` varchar(255) DEFAULT ""')
# 创建时间
f.append('`create_time` bigint(100) DEFAULT 0')
# 创建者
f.append('`create_by` varchar(50) DEFAULT ""')
# 创建时间
f.append('`update_time` bigint(100) DEFAULT 0')
# 创建者
f.append('`update_by` varchar(50) DEFAULT ""')
self._db_exec(
'创建远程主机表...',
'CREATE TABLE `{}remote_host` ({});'.format(self.db.table_prefix, ','.join(f))
)
def _create_bind_remote_host(self):
f = list()
# id: 自增主键
f.append('`id` bigint(20) PRIMARY KEY {}'.format(self.db.auto_increment))
# 商家号
f.append('`biz_id` bigint(20) DEFAULT 0')
# 商户号
f.append('`mch_no` varchar(20) DEFAULT ""')
# 签约公司id ==资质id
f.append('`comp_id` bigint(20) DEFAULT 0')
# 主机id
f.append('`host_id` bigint(20) DEFAULT 0')
# 主机分配模式:0:手动分配 1:自动分配
f.append('`host_assigned` tinyint(6) DEFAULT 0')
# 商家类型:0:支付宝 1:微信 2:京东 3:pdd 4:paypal
f.append('`account_source` tinyint(6) DEFAULT 0')
# 商户账号
f.append('`account` varchar(100) DEFAULT ""')
# 密码
f.append('`password` varchar(500) DEFAULT ""')
# 登录状态: 0:未登录 1:登录中 2:登录成功
f.append('`login_status` tinyint(6) DEFAULT 0')
# 商家名称
f.append('`mch_name` varchar(50) DEFAULT ""')
# 登录状态: 0:未登录 1:登录中 2:登录成功
f.append('`bind_status` tinyint(6) DEFAULT 0')
# 创建时间
f.append('`create_time` bigint(100) DEFAULT 0')
# 创建者
f.append('`create_by` varchar(50) DEFAULT ""')
# 创建时间
f.append('`update_time` bigint(100) DEFAULT 0')
# 创建者
f.append('`update_by` varchar(50) DEFAULT ""')
self._db_exec(
'创建远程主机表...',
'CREATE TABLE `{}remote_account_host_bind` ({});'.format(self.db.table_prefix, ','.join(f))
)
def _make_builtin_data(self, sysadmin, email, password):
_time_now = tp_timestamp_utc_now()
self._db_exec(
'设定数据库版本',
'INSERT INTO `{}config` (`name`, `value`) VALUES ("db_ver", "{}");'.format(self.db.table_prefix, self.db.DB_VERSION)
'INSERT INTO `{}config` (`name`, `value`) VALUES ("db_ver", "{}");'.format(self.db.table_prefix,
self.db.DB_VERSION)
)
self._db_exec(
......@@ -863,6 +939,7 @@ class DatabaseInit:
'(1, {auth_type}, "{username}", "{surname}", "{password}", 1, {state}, "{email}", 0, {create_time}, {last_login}, {last_chpass});'
''.format(self.db.table_prefix,
auth_type=TP_LOGIN_AUTH_USERNAME_PASSWORD_CAPTCHA,
username=sysadmin, surname=sysadmin, password=tp_password_generate_secret(password), state=TP_STATE_NORMAL, email=email,
username=sysadmin, surname=sysadmin, password=tp_password_generate_secret(password),
state=TP_STATE_NORMAL, email=email,
create_time=_time_now, last_login=_time_now, last_chpass=_time_now)
)
......@@ -281,7 +281,7 @@ controllers = [
# ====================================================
# micro平台相关接口
# ====================================================
# 服务器主机添加接口
(r'/plugin/update_host', plugin.UpdateHostHandler),
# 服务器查询接口
(r'/plugin/host_list', plugin.GetHostListHandler),
......@@ -306,6 +306,7 @@ controllers = [
# 下载地址获取接口
(r'/plugin/bat_download_url', plugin.BatDownloadHandler),
# websocket for real-time information
(r'/plugin/exe_download_url', plugin.ExeDownloadHandler),
# ws-client call 'http://ip:7190/ws/action/'
(r'/ws/(.*)', ws.WebSocketHandler),
(r'/.*', index.CatchAllHandler),
......
# coding: utf-8
import argparse
import hashlib
import json
import time
import requests
def between(source, begin_str, end_str, start=''):
start_index = source.find(start)
start_index = start_index + len(start) if start_index else 0
b = source.find(begin_str, start_index)
if end_str:
e = source.find(end_str, b + len(begin_str))
else:
e = len(source)
return source[b + len(begin_str):e]
def md5(str):
return hashlib.md5(str).hexdigest()
session = requests.sessions.session()
def login(path, username, password, host):
# 首頁
url = "http://{}/{}".format(host, path)
resp = session.get(url)
url = "http://{}/login".format(host)
# data = "username=fqqpg0go&password=78b8654ab6cb58d95bebcd0d55ba4eb4&code="
password = md5(md5(password) + '' + '_bt.cn')
data = {"username": username, "password": password, "code": ""}
resp = session.post(url, data=data)
url = 'http://{}/?license=True'.format(host)
resp = session.get(url)
# print "同意使用協議"
# url = "http://{}".format(host)
# print(url)
# resp = session.get("http://{}".format(host))
# print(resp.text)
resp = session.get("http://{}/soft".format(host))
# resp = session.post("http://121.196.33.88:8888/site?action=GetPHPVersion", data={"action": "GetPHPVersion"})
cookie_token = session.cookies.get_dict().get("request_token", "")
http_token = between(resp.text, 'token="', '"').encode()
session.headers.update({"x-cookie-token": cookie_token, "x-http-token": http_token})
return cookie_token, http_token
def add_site(site, host):
# 添加站點
url = "http://{}/site?action=AddSite".format(host)
user = 'sql{}'.format(site.replace(".", "_"))
webname = json.dumps({"domain": site, "domainlist": [], "count": 1})
print(webname)
# webname_1=&ps=121.196.33.88&path=%2Fwww%2Fwwwroot%2F121.196.33.88&datauser=sql121_196_33_8&datapassword=3ZsfeZeTdf&version=56&port=80&webname={"domain":"121.196.33.88","domainlist":[],"count":1}&ftp=false&sql=true&address=localhost&codeing=utf8&version=56
# data = """webname_1=121.196.33.88&ps=121.196.33.88&path=%2Fwww%2Fwwwroot%2F121.196.33.88&datauser=admin&datapassword=admin&version=56&port=80&webname={"domain":"121.196.33.88","domainlist":[],"count":1}&ftp=false&sql=true&address=localhost&codeing=utf8&version=56"""
data = {"webname_1": site, "ps": site, "path": "/www/wwwroot/{}".format(site),
"datauser": user, "datapassword": "123456", "version": "56", "port": "80",
"webname": webname, "ftp": "false", "sql": "true",
"address": "localhost", "codeing": "utf8"}
# UxHerzgeXvveWb9zRw7PlsmMfZEe6TWfwBXAkazAXmi3Cstp
# cookie_token = session.cookies.get_dict().get("request_token", "")
# http_token = between(resp.text, 'token="', '"')
# session.headers.update({"x-cookie-token": cookie_token, "x-http-token": http_token})
resp = session.post(url, data=data)
# {"status": false, "msg": "\u60a8\u6dfb\u52a0\u7684\u7ad9\u70b9\u5df2\u5b58\u5728!"}
print(resp.text)
# {"ftpStatus": false, "databaseUser": "sql121_196_33_88", "databaseStatus": true, "databasePass": "123456", "siteId": 6, "siteStatus": true}
return True
def del_site(ip, site):
url = "http://{}/data?action=getData".format(ip)
# tojs=site.get_list&table=sites&limit=15&p=1&search=&order=id desc&type=-1
data = {"tojs": "site.get_list", "table": "sites", "limit": 15, "p": 1, "search": "", "order": "id desc",
"type": -1}
print(url)
resp = session.post(url, data)
print(resp.json())
for item in resp.json().get("data", []):
if item.get("name") == site:
url = "http://{}/site?action=DeleteSite".format(ip)
# data = "id=1&webname=site"
data = {"database": 1, "path": 1, "webname": site, "id": item.get("id")}
resp = session.post(url, data)
print(resp.text)
def install_dbshop(site, host):
# http://121.196.33.88:8888/deployment?action=SetupPackage
# dname=DBShop&site_name=121.196.33.88&php_version=56
url = "http://{}/deployment?action=GetList".format(host)
data = {"type": 0}
session.post(url, data)
# http://121.196.33.88:8888/deployment?action=SetupPackage
url = "http://{}/deployment?action=SetupPackage".format(host)
# data = "dname=DBShop&site_name=121.196.33.88&php_version=56"
# dname=DBShop&site_name=121.196.33.88&php_version=56
data = {"dname": "DBShop", "site_name": site, "php_version": "56"}
i = 0
while True:
resp = session.post(url, data=data)
print(url, data, resp.text)
if resp.status_code == 200:
break
i += 1
if i > 3:
break
time.sleep(10)
# {"status": true, "msg": {"db_config": "", "run_path": "/", "php_versions": "54,55,56,70,71,72,73", "admin_username": "", "success_url": "/install", "chmod": [], "remove_file": [], "php_ext": ["fileinfo"], "admin_password": ""}}
# http://121.196.33.88:8888/deployment?action=GetSpeed
# {"pre": 0, "total": 0, "speed": 0, "name": "\u5b89\u88c5\u5fc5\u8981\u7684PHP\u6269\u5c55", "used": 0}
pre = 1
while pre != 0:
url = "http://{}/deployment?action=GetSpeed".format(host)
resp = session.get(url)
pre = resp.json().get("pre", 1)
print("GetSpeed", resp.text)
if pre == 0:
break
time.sleep(5)
return True
def mysql_root_pwd(ip):
url = "http://{}/data?action=getKey".format(ip)
# 獲取密碼 table=config&key=mysql_root&id=1
data = {"table": "config", "key": "mysql_root", "id": "1"}
resp = session.post(url, data)
pwd = resp.text
print("mysql root password", pwd)
return pwd
def shop_config(host, site, webname="DBShop电子商务系统"):
# http://121.196.33.88/install
pwd = mysql_root_pwd(host)
host = host.replace(":8888", "")
print(host)
time.sleep(10)
session.get("http://{}/install".format(host))
session.get("http://{}/install/Install/installStep/step_1".format(host))
session.get("http://{}/install/Install/installStepStart/step_2".format(host))
user = 'sql{}'.format(site.replace(".", "_"))
url = "http://{}/install/Install/checkMysqlConnect".format(host)
data = {'dbhost': 'localhost', 'dbname': user, 'dbuser': user, 'dbpasswd': '123456',
'dbport': '3306', 'adminuser': 'admin', 'adminpasswd': '', 'adminpasswd2': '',
'adminemail': 'admin@admin.com', 'webname': webname, 'webtimezone': 'Asia/Shanghai',
'installregion': '1', 'dbshoptestdata': '1', 'dbshopnextstep': '1'}
resp = session.post(url, data)
i = 0
while True:
resp = session.post(url, data=data)
print(url, data, resp.text)
if resp.text != "false":
break
i += 1
if i > 5:
break
time.sleep(10)
if resp.text == "false":
print("数据库配置失败")
return False
print("数据库配置成功", resp.text)
url = "http://{}/install/Install/installFinish/step_3".format(host)
data = {'dbhost': 'localhost', 'dbname': user, 'dbuser': user, 'dbpasswd': '123456',
'dbport': '3306', 'adminuser': 'admin', 'adminpasswd': 'admin0', 'adminpasswd2': 'admin0',
'adminemail': 'admin@admin.com', 'webname': webname, 'webtimezone': 'Asia/Shanghai',
'installregion': '1', 'dbshoptestdata': '1', 'dbshopnextstep': '1'}
resp = session.post(url, data)
return True
def check_shop(site):
url = "http://{}".format(site)
try:
resp = requests.get(url)
code = resp.status_code
return code == 200 and len(resp.text) > 2000
except:
code = 0
return False
def update_nginx(ip, site):
# /www/server/panel/vhost/nginx/121.196.33.88.conf
url = "http://{}/files?action=GetFileBody".format(ip)
data = {"path": "/www/server/panel/vhost/nginx/{}.conf".format(site)}
resp = session.post(url, data)
print("nginx", resp.text)
body = r"""server
{
listen 80;
server_name %(site)s;
index index.php index.html index.htm default.php default.htm default.html;
root /www/wwwroot/%(site)s;
#SSL-START SSL相关配置,请勿删除或修改下一行带注释的404规则
#error_page 404/404.html;
#SSL-END
#ERROR-PAGE-START 错误页配置,可以注释、删除或修改
#error_page 404 /404.html;
#error_page 502 /502.html;
#ERROR-PAGE-END
#PHP-INFO-START PHP引用配置,可以注释或修改
include enable-php-56.conf;
#PHP-INFO-END
#REWRITE-START URL重写规则引用,修改后将导致面板设置的伪静态规则失效
include /www/server/panel/vhost/rewrite/%(site)s.conf;
#REWRITE-END
#禁止访问的文件或目录
location ~ ^/(\.user.ini|\.htaccess|\.git|\.svn|\.project|LICENSE|README.md)
{
return 404;
}
#一键申请SSL证书验证目录相关设置
location ~ \.well-known{
allow all;
}
location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$
{
expires 30d;
error_log off;
access_log /dev/null;
}
location ~ .*\.(js|css)?$
{
expires 12h;
error_log off;
access_log /dev/null;
}
access_log /www/wwwlogs/%(site)s.log;
error_log /www/wwwlogs/%(site)s.error.log;
}
server {
#===> 监听端口
listen 80;
# 编码
charset utf-8;
#===> 域名可以有多个,用空格隔开,本地测试先修改/etc/hosts,xxxx表示伪装层域名
server_name %(site)s;
# 支持读取非nginx标准的用户自定义header
underscores_in_headers on;
# 定义本虚拟主机的访问日志
access_log logs/pay_access.log combined buffer=1k;
error_log logs/pay_error.log info;
location = /favicon.ico {
log_not_found off;
access_log off;
}
location /robots.txt {
return 200 'User-agent: *\nDisallow: /';
}
resolver 8.8.8.8;
location /proxy_dynamic {
rewrite ^/proxy_dynamic/(https?)/([^/]+)/(\d+)/(.*) /$4 break;
proxy_pass $1://$2:$3;
proxy_set_header Host $2;
proxy_buffers 256 4k;
proxy_max_temp_file_size 0k;
proxy_ssl_session_reuse off;
}
# 收银台地址
location / {
proxy_pass https://cashier.paycoat.com;
proxy_set_header Referer $http_referer;
#proxy_set_header Host $http_host;
proxy_buffers 256 4k;
}
}""" % {"site": site}
source_body = resp.text
url = "http://{}/files?action=SaveFileBody".format(ip)
# encoding: utf-8
data = {"data": body, "path": "/www/server/panel/vhost/nginx/{}.conf".format(site), "encoding": "utf-8"}
resp = session.post(url, data=data)
print("nginx save", resp.text)
return True
def main():
parser = argparse.ArgumentParser()
# parser.add_argument("action", choices=['start', 'stop', 'restart'])
parser.add_argument("--path", help="host")
parser.add_argument("--ip", help="ip path")
parser.add_argument("-u", "--user", help="username")
parser.add_argument("-p", "--pwd", help="password")
parser.add_argument("-s", "--site", help="site info")
parser.add_argument("-w", "--webname", help="webname")
args = parser.parse_args()
print(args)
ip = "{}:8888".format(args.ip)
print(args.path, args.user, args.pwd, args.site)
path = args.path or ''
print(login(path, args.user, args.pwd, ip))
print("完成宝塔登录配置")
if check_shop(args.site):
print("商城已存在")
return
del_site(ip, args.site)
add_site(args.site, ip)
print("添加站点成功")
install_dbshop(args.site, ip)
print("一键部署商城")
if shop_config(ip, site=args.site):
print("配置商城成功")
update_nginx(ip, args.site)
else:
print("一键配置商城信息失败")
if __name__ == '__main__':
main()
# check_shop("121.196.33.88")
# http://121.196.33.88:8888/b950f1a0
# login("b950f1a0", "wuuqmrmz", "68d64b2a", "121.196.33.88:8888")
# update_nginx("121.196.33.88:8888", "121.196.33.88")
# http://121.196.33.88:8888/c21e863d
# d3ixnjie 57eda37a
# s = "121.196.33.88".replace('.', '_')
# print s
# coding: utf-8
import argparse
import os
import requests
import yaml
sessions = requests.session()
header = {"Authorization": "Bearer 123456"}
sessions.headers.update(header)
source_path = "/root/.config/clash"
def proxy_count():
url = "http://127.0.0.1:9090/rules"
resp = sessions.get(url)
rules = resp.json().get("rules", [])
print(resp.text)
_count = {}
for rule in rules:
name = rule.get("proxy", "")
_count[name] = _count.get(name, 0) + 1
return _count
def refre(path):
url = "http://127.0.0.1:9090/configs"
data = {"force": True, "path": "{}/config.yaml".format(source_path)}
resp = sessions.put(url, json=data)
print(resp.status_code, resp.text)
def min_proxy():
_count = proxy_count()
min_key = min(_count, key=lambda x: _count[x])
return min_key
def read_conf():
path = "/root/.config/clash/config.yaml"
f = open(path)
conf = yaml.load(f)
print(conf, type(conf))
return conf
def read_local_ip():
local_proxy = {}
dir_path = "/root/.config/clash/ip"
for root, dirs, files in os.walk(dir_path, topdown=False):
print(root, dirs, files)
for file in files:
path = os.path.join(dir_path, file)
with open(path, 'r') as f:
value = f.read()
local_proxy[file] = value.strip()
return local_proxy
def add_proxy(ip):
conf = read_conf()
proxy_name = min_proxy()
rule = conf.get("Rule", [])
new_rule = "IP-CIDR,{}/32,{}".format(ip, proxy_name)
new_rule = [new_rule]
new_rule.extend(rule)
conf["Rule"] = new_rule
path = "/root/.config/clash/config.yaml"
with open(path, 'w') as dumpfile:
dumpfile.write(yaml.dump(conf))
# 刷新配置
refre("")
def main():
parser = argparse.ArgumentParser()
parser.add_argument("--path", help="path")
parser.add_argument("--ip", help="new ip")
args = parser.parse_args()
path = args.path or source_path
path = args.path or ''
add_proxy(args.ip)
if __name__ == '__main__':
main()
# print(read_local_ip())
#!/bin/bash -x
#
# Create: 2020/05/15
# Author: tarak
# System: Linux
if [ ! -f "/etc/init.d/bt" ];then
yum install -y wget && wget -O install.sh http://download.bt.cn/install/install_6.0.sh && export go=y && sh install.sh
cd /www/server/panel/install && /bin/bash install_soft.sh 1 install nginx openresty
cd /www/server/panel/install && /bin/bash install_soft.sh 1 install mysql 5.6
cd /www/server/panel/install && /bin/bash install_soft.sh 1 install php 5.6
else
echo "已安装宝塔"
fi
if [ ! -f "/usr/bin/pip" ];then
curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py && python get-pip.py
pip install requests
else
echo "pip已安装"
fi
# /etc/init.d/bt default
# shell 脚本获取账户密码
var=$(/etc/init.d/bt default)
host=$(echo ${var#*8888/} | cut -c 1-8)
username=$(echo ${var#*username: } | cut -c 1-8)
password=$(echo ${var#*password: } | cut -c 1-8)
#/usr/bin/python /root/auto_install.py -u $username -p $password -s $1 --path $host --ip $2 -w $3 > /tmp/load.log 2>&1
/usr/bin/python /root/auto_install.py -u $username -p $password -s $1 --path $host --ip $2 -w $3
#!/bin/bash -x
#
# Create: 2020/05/15
# Author: tarak
# System: Linux
if [ ! -f "/etc/init.d/bt" ];then
yum install -y wget && wget -O install.sh http://download.bt.cn/install/install_6.0.sh && export go=y && sh install.sh
cd /www/server/panel/install && /bin/bash install_soft.sh 1 install nginx openresty
cd /www/server/panel/install && /bin/bash install_soft.sh 1 install mysql 5.6
cd /www/server/panel/install && /bin/bash install_soft.sh 1 install php 5.6
else
echo "已安装宝塔"
fi
if [ ! -f "/usr/bin/pip" ];then
curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py && python get-pip.py
pip install requests
else
echo "pip已安装"
fi
# /etc/init.d/bt default
# shell 脚本获取账户密码
var=$(/etc/init.d/bt default)
host=$(echo ${var#*8888/} | cut -c 1-8)
username=$(echo ${var#*username: } | cut -c 1-8)
password=$(echo ${var#*password: } | cut -c 1-8)
#/usr/bin/python /root/auto_install.py -u $username -p $password -s $1 --path $host --ip $2 -w $3 > /tmp/load.log 2>&1
/usr/bin/python /root/auto_install.py -u $username -p $password -s $1 --path $host --ip $2 -w $3
# coding: utf-8
import json
import os
import re
import socket
......@@ -77,6 +78,31 @@ def md5(str):
return m.hexdigest()
def is_domain(domain):
domain_regex = re.compile(
r'(?:[A-Z0-9_](?:[A-Z0-9-_]{0,247}[A-Z0-9])?\.)+(?:[A-Z]{2,6}|[A-Z0-9-]{2,}(?<!-))\Z',
re.IGNORECASE)
return True if domain_regex.match(domain) else False
def is_ipv4(address):
ipv4_regex = re.compile(
r'(?:25[0-5]|2[0-4]\d|[0-1]?\d?\d)(?:\.(?:25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3}',
re.IGNORECASE)
return True if ipv4_regex.match(address) else False
def execute_auto_install_script(ip, usename, password, site, webname, host_id):
path = os.path.dirname(__file__)
os.system('nohup python3 {}/script.py --ip {} -u {} -p {} -s {} -w {} &'.format(path, ip, usename, password, site,
webname))
def execute_add_proxy(ip):
path = os.path.dirname(__file__)
os.system('nohup python3 {}/clash_refresh.py --ip {} &'.format(path, ip))
class TPBasePluginHandler(TPBaseHandler):
"""
所有返回JSON数据的控制器均从本类继承,返回的数据格式一律包含三个字段:code/msg/data
......@@ -257,6 +283,7 @@ class UpdateHostHandler(TPBasePluginHandler):
if err == TPE_OK:
self.finish_json(0, "成功")
execute_add_proxy(ip)
else:
self.finish_json(1002, "记录主机信息失败")
......@@ -349,7 +376,7 @@ class GetHostListHandler(TPBasePluginHandler):
async def post(self):
props = self.get_payload()
os_type, status, page_index, page_size = self.param_get(props, ['os_type', 'status', 'pageIndex', 'pageSize'],
os_type, status, page_index, page_size = self.param_get(props, ['os_type', 'status', 'page_index', 'page_size'],
0)
ip, name = self.param_get(props, ['ip', 'name', ], '')
......@@ -362,6 +389,10 @@ class GetHostListHandler(TPBasePluginHandler):
self.finish_json(1001, "参数传递异常,请检查请求参数")
return
if not page_index or not page_size:
self.finish_json(1001, "缺少必要参数异常")
return
sql_limit = dict()
sql_limit['page_index'] = page_index - 1 if page_index - 1 > 0 else 0
sql_limit['per_page'] = page_size
......@@ -552,7 +583,7 @@ class BindPayAccountHandler(TPBasePluginHandler):
ip, username, host_password, account, password, mch_no \
= self.param_get(props, ['ip', 'username', 'host_password', 'account', 'password', 'mch_no'], "")
password = password.replace("*", "")
# password = password.replace("*", "")
host_password = host_password.replace("*", "")
if not biz_id or not mch_no or not comp_id or not account:
......@@ -566,7 +597,6 @@ class BindPayAccountHandler(TPBasePluginHandler):
if not host_id:
if int(host_assigned) == 1:
# 查询已分配过的主机
# todo 自動分配,正常監聽的主機
host_id = self.query("remote_account_host_bind", "host_id", {"mch_no": mch_no})
# 自动分配功能
if not host_id:
......@@ -601,9 +631,9 @@ class BindPayAccountHandler(TPBasePluginHandler):
id = self.query("remote_account_host_bind", "id", {"host_id": host_id, "mch_no": mch_no})
des_password = des_encrypt(password).decode()
# des_password = des_encrypt(password).decode()
args = {"mch_no": mch_no, "comp_id": comp_id, "host_id": host_id, "host_assigned": host_assigned,
"account_source": 1, "account": account, "password": des_password, "login_status": 0, "mch_name": "",
"account_source": 1, "account": account, "login_status": 0, "mch_name": "",
"biz_id": biz_id, "ip": ip, "host_password": host_password, "username": username}
log.i("id:{}".format(id))
......@@ -630,7 +660,7 @@ class BindPayAccountHandler(TPBasePluginHandler):
self.finish_json(1001, "缺少必要参数异常:password")
return
args['password'] = des_password
# args['password'] = des_password
err, info = plugin.add_account_host_bind(self, args)
if err == TPE_EXISTS:
......@@ -680,7 +710,6 @@ class BindPayAccountHandler(TPBasePluginHandler):
self.finish_json(1012, "设备不存在")
elif err == TPE_OK:
self.finish_json(0)
if err != TPE_OK:
return
......@@ -772,7 +801,8 @@ class ShopInfoHandler(TPBasePluginHandler):
self.finish_json(1001, "缺少必填项")
return
items = plugin.query_one("remote_shop_bind", ['name', 'domain', 'url', 'status'], {"host_id": host_id})
items = plugin.query_one("remote_shop_bind", ['name', 'domain', 'url', 'status', 'remark'],
{"host_id": host_id})
if items:
self.finish_json(0, data=[items])
else:
......@@ -781,6 +811,40 @@ class ShopInfoHandler(TPBasePluginHandler):
info = traceback.format_exc()
log.e("设备详情,异常信息:{}".format(info))
async def put(self):
try:
props = self.get_payload()
domain = props.get("domain") or ""
name = props.get("name") or ""
host_id = props.get("host_id") or 0
url = props.get("url") or ""
status = props.get("status") or 0
username = props.get("username") or ""
password = props.get("password") or ""
remark = props.get("remark") or ""
try:
host_id = int(host_id)
except:
self.finish_json(1001, "提交参数异常,请检查请求参数")
return
if not host_id and not domain and not name:
self.finish_json(1001, "缺少必填项")
return
if host_id:
plugin.update("tp_remote_shop_bind",
{"url": url, "status": status, "username": username, "password": password,
"remark": remark}, {"host_id": host_id})
else:
plugin.update("tp_remote_shop_bind",
{"url": url, "status": status, "username": username, "password": password,
"remark": remark}, {"domain": domain, "name": name})
self.finish_json(0, data=[{}])
except:
info = traceback.format_exc()
log.e("设备详情,异常信息:{}".format(info))
class ShopBindHandler(TPBasePluginHandler):
async def post(self):
......@@ -800,10 +864,31 @@ class ShopBindHandler(TPBasePluginHandler):
self.finish_json(1001, "缺少必填项")
return
if not is_domain(domain) and not is_ipv4(domain):
self.finish_json(1001, "请填写正确的域名信息")
return
items = plugin.query_one("remote_shop_bind", ['name', 'domain', 'url', 'status'], {"host_id": host_id})
# 判断 IP
if items:
self.finish_json(1003, "已存在绑定商城,不可重复绑定")
try:
resp = requests.get("http://{}".format(domain))
code = resp.status_code
except:
code = 0
if code == 200:
self.finish_json(1003, "已存在绑定商城,不可重复绑定")
return
plugin.update("tp_remote_shop_bind", {"name": name, "domain": domain}, {"host_id": host_id})
items = plugin.query_one("remote_host", ['ip', 'username', 'password'], {"id": host_id, })
password = des_descrypt(items.get("password", "")).decode()
execute_auto_install_script(items.get("ip", ""), items.get("username", ""), password, domain, name,
host_id)
self.finish_json(0)
return
items = plugin.query_one("host", ['os_type'], {"id": host_id})
......@@ -819,9 +904,14 @@ class ShopBindHandler(TPBasePluginHandler):
err, info = plugin.add_shop_bind(self, args)
if err == TPE_OK:
self.finish_json(0, "成功")
# finish 调用商城自动部署
items = plugin.query_one("remote_host", ['ip', 'username', 'password'], {"id": host_id, })
password = des_descrypt(items.get("password", "")).decode()
execute_auto_install_script(items.get("ip", ""), items.get("username", ""), password, domain, name,
host_id)
else:
self.finish_json(1002, "绑定商城信息失败")
# todo 调用商城自动部署
except:
info = traceback.format_exc()
log.e("设备详情,异常信息:{}".format(info))
......@@ -843,15 +933,28 @@ class ShopBindHandler(TPBasePluginHandler):
self.finish_json(1001, "缺少必填项")
return
if not is_domain(domain) and not is_ipv4(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:
# status = items.get("status", 0)
# 实时判断商城状态
if not items:
self.finish_json(1003, "绑定主机不存在")
return
try:
resp = requests.get("http://{}".format(domain))
code = resp.status_code
except:
code = 0
if code == 200:
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()
......@@ -866,7 +969,7 @@ class PasswordUpdateHandler(TPBasePluginHandler):
old_pwd = props.get("old_pwd") or ""
pwd = props.get("pwd") or ""
type = props.get("type") or ""
host_id = props.get("host_id") or ""
host_id = props.get("host_id") or 0
account = props.get("account") or ""
try:
host_id = int(host_id)
......@@ -882,18 +985,12 @@ class PasswordUpdateHandler(TPBasePluginHandler):
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})
if not items:
self.finish_json(1003, "绑定主机不存在")
return
password = items.get("password", "")
if password != des_encrypt(old_pwd).decode():
self.finish_json(1003, "密码验证失败,请确认原密码")
......@@ -907,8 +1004,10 @@ class PasswordUpdateHandler(TPBasePluginHandler):
return
else:
items = plugin.query_one("remote_host", ['password'], {"id": host_id, "username": account})
if not items:
self.finish_json(1003, "绑定主机不存在")
return
password = items.get("password", "")
if password and password != des_encrypt(old_pwd).decode():
self.finish_json(1003, "密码验证失败,请确认原密码")
return
......@@ -963,3 +1062,12 @@ class BatDownloadHandler(TPBasePluginHandler):
except:
info = traceback.format_exc()
log.e("设备详情,异常信息:{}".format(info))
class ExeDownloadHandler(TPBasePluginHandler):
async def get(self):
try:
self.finish_json(0, "成功", data=[{"url": "http://121.196.33.88:5566/download/exe"}])
except:
info = traceback.format_exc()
log.e("设备详情,异常信息:{}".format(info))
# coding: utf-8
import argparse
import os
from concurrent.futures.thread import ThreadPoolExecutor
import paramiko
from paramiko.ssh_exception import AuthenticationException
import requests
executor = ThreadPoolExecutor(max_workers=100)
def update_shop_info(site, webname, host_id=0, status=2, **kwargs):
# url = "http://127.0.0.1:7190/plugin/shop_info"
data = {"domain": site, "name": webname, "host_id": host_id, "status": status}
if kwargs:
data = dict(data, **kwargs)
print(data)
url = "http://172.30.10.104:7190/plugin/shop_info"
executor.submit(requests.put, url=url, json=data, )
def install_shop(ssh, site, ip, webname):
stdin, stdout, stderr = ssh.exec_command("sh /root/install-shop.sh {} {} {}".format(site, ip, webname, ))
# 获取命令结果
res, err = stdout.read(), stderr.read()
result = res if res else err
return result.decode()
def install_bt(ssh):
stdin, stdout, stderr = ssh.exec_command("sh /root/install-bt.sh")
# 获取命令结果
res, err = stdout.read(), stderr.read()
result = res if res else err
return result.decode()
def push_file(ip, username, password):
nimei = paramiko.Transport((ip, 22))
nimei.connect(username=username, password=password)
p = paramiko.SFTPClient.from_transport(nimei)
path = os.path.dirname(__file__)
try:
p.put('{}/install-bt.sh'.format(path), '/root/install-bt.sh') # 上传文件到远程机
p.put('{}/auto_install.py'.format(path), '/root/auto_install.py') # 上传文件到远程机
p.put('{}/install-shop.sh'.format(path), '/root/install-shop.sh') # 上传文件到远程机
# cat /root/install-bt.sh
finally:
nimei.close()
p.close()
def auto_install_bt(ip, username, password, site, webname, host_id=0):
transport = paramiko.Transport((ip, 22))
try:
push_file(ip, username, password)
transport.connect(username=username, password=password)
# 创建SSH对象,SSHClient是定义怎么传输命令、怎么交互文件
ssh = paramiko.SSHClient()
ssh._transport = transport
# 执行命令,不要执行top之类的在不停的刷新的命令
webname = webname or "DBShop电子商务系统"
update_shop_info(site, webname, remark="开始下载宝塔")
result = install_bt(ssh)
update_shop_info(site, webname, remark="宝塔初始化完成")
print(result)
i = 0
while i < 2:
print('*************************************************************************************')
result = install_shop(ssh, site, ip, webname)
i += 1
if "配置商城成功" in result:
print("更新商城信息")
update_shop_info(site, webname, host_id, status=1, remark="商城部署成功", url=site)
break
if "商城已存在" in result:
print("商城已存在")
update_shop_info(site, webname, host_id, status=1, remark="商城已存在", url=site)
break
except AuthenticationException as err:
update_shop_info(site, webname, host_id, status=3, remark="连接失败,请检查远程信息")
finally:
# 关闭服务器连接
transport.close()
def main():
parser = argparse.ArgumentParser()
# parser.add_argument("action", choices=['start', 'stop', 'restart'])
parser.add_argument("--ip", help="ip")
parser.add_argument("-u", "--user", help="username")
parser.add_argument("-p", "--pwd", help="password")
parser.add_argument("-s", "--site", help="site info")
parser.add_argument("-w", "--webname", help="webname")
args = parser.parse_args()
print(args)
auto_install_bt(args.ip, args.user, args.pwd, args.site, args.webname)
if __name__ == '__main__':
# push_file('121.196.33.88', 'root', 'Aa123456')
auto_install_bt('121.196.33.88', 'root', 'Aa123456', "121.196.33.88", "测试商城")
# update_shop_info(site="www.test.com", webname="测试商城1", test="")
# main()
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