mirror of https://github.com/tp4a/teleport
parent
c5859cdce6
commit
428dc323f3
|
@ -29,7 +29,7 @@ def create_and_init(db, step_begin, step_end):
|
|||
|
||||
_db_exec(db, step_begin, step_end, '创建表 auth', """CREATE TABLE `{}auth`(
|
||||
`auth_id` INTEGER PRIMARY KEY {},
|
||||
`account_name` varchar(256),
|
||||
`account_name` varchar(255),
|
||||
`host_id` INTEGER,
|
||||
`host_auth_id` int(11) NOT NULL
|
||||
);""".format(db.table_prefix, db.auto_increment))
|
||||
|
@ -38,16 +38,16 @@ def create_and_init(db, step_begin, step_end):
|
|||
# 这也是升级到数据库版本5的标志!
|
||||
_db_exec(db, step_begin, step_end, '创建表 key', """CREATE TABLE `{}key` (
|
||||
`cert_id` integer PRIMARY KEY {},
|
||||
`cert_name` varchar(256),
|
||||
`cert_name` varchar(255),
|
||||
`cert_pub` varchar(2048) DEFAULT '',
|
||||
`cert_pri` varchar(4096) DEFAULT '',
|
||||
`cert_desc` varchar(256)
|
||||
`cert_desc` varchar(255)
|
||||
);
|
||||
""".format(db.table_prefix, db.auto_increment))
|
||||
|
||||
_db_exec(db, step_begin, step_end, '创建表 config', """CREATE TABLE `{}config` (
|
||||
`name` varchar(256) NOT NULL,
|
||||
`value` varchar(256),
|
||||
`name` varchar(128) NOT NULL,
|
||||
`value` varchar(255),
|
||||
PRIMARY KEY (`name` ASC)
|
||||
);""".format(db.table_prefix))
|
||||
|
||||
|
@ -64,16 +64,16 @@ PRIMARY KEY (`name` ASC)
|
|||
`host_port` int(11) DEFAULT 0,
|
||||
`protocol` int(11) DEFAULT 0,
|
||||
`host_lock` int(11) DEFAULT 0,
|
||||
`host_desc` varchar(256) DEFAULT ''
|
||||
`host_desc` varchar(255) DEFAULT ''
|
||||
);""".format(db.table_prefix, db.auto_increment))
|
||||
|
||||
_db_exec(db, step_begin, step_end, '创建表 auth_info', """CREATE TABLE `{}auth_info`(
|
||||
`id` INTEGER PRIMARY KEY {},
|
||||
`host_id` INTEGER,
|
||||
`auth_mode` INTEGER,
|
||||
`user_name` varchar(256),
|
||||
`user_pswd` varchar(256),
|
||||
`user_param` varchar(256),
|
||||
`user_name` varchar(255),
|
||||
`user_pswd` varchar(255),
|
||||
`user_param` varchar(255),
|
||||
`cert_id` INTEGER,
|
||||
`encrypt` INTEGER,
|
||||
`log_time` varchar(60)
|
||||
|
|
|
@ -149,7 +149,7 @@ class DatabaseUpgrade:
|
|||
`group_id` int(11) DEFAULT 0,
|
||||
`host_sys_type` int(11) DEFAULT 1,
|
||||
`host_ip` varchar(32) DEFAULT '',
|
||||
`pro_port` varchar(256) NULL,
|
||||
`pro_port` varchar(255) NULL,
|
||||
`host_lock` int(11) DEFAULT 0,
|
||||
`host_desc` varchar(128) DEFAULT ''
|
||||
);""".format(self.db.table_prefix, self.db.auto_increment)):
|
||||
|
@ -161,8 +161,8 @@ class DatabaseUpgrade:
|
|||
`host_id` INTEGER,
|
||||
`pro_type` INTEGER,
|
||||
`auth_mode` INTEGER,
|
||||
`user_name` varchar(256),
|
||||
`user_pswd` varchar(256),
|
||||
`user_name` varchar(255),
|
||||
`user_pswd` varchar(255),
|
||||
`cert_id` INTEGER,
|
||||
`encrypt` INTEGER,
|
||||
`log_time` varchar(60)
|
||||
|
@ -381,7 +381,7 @@ class DatabaseUpgrade:
|
|||
# 先创建三个临时表
|
||||
if not self.db.exec("""CREATE TABLE `{}auth_tmp` (
|
||||
`auth_id` INTEGER PRIMARY KEY {},
|
||||
`account_name` varchar(256),
|
||||
`account_name` varchar(255),
|
||||
`host_id` INTEGER,
|
||||
`host_auth_id` int(11) NOT NULL
|
||||
);""".format(self.db.table_prefix, self.db.auto_increment)):
|
||||
|
@ -405,9 +405,9 @@ class DatabaseUpgrade:
|
|||
`id` INTEGER PRIMARY KEY {},
|
||||
`host_id` INTEGER,
|
||||
`auth_mode` INTEGER,
|
||||
`user_name` varchar(256),
|
||||
`user_pswd` varchar(256),
|
||||
`user_param` varchar(256),
|
||||
`user_name` varchar(255),
|
||||
`user_pswd` varchar(255),
|
||||
`user_param` varchar(255),
|
||||
`cert_id` INTEGER,
|
||||
`encrypt` INTEGER,
|
||||
`log_time` varchar(60)
|
||||
|
@ -492,8 +492,8 @@ class DatabaseUpgrade:
|
|||
|
||||
if not self.db.is_table_exists('{}config'.format(self.db.table_prefix)):
|
||||
if not self.db.exec("""CREATE TABLE `{}config` (
|
||||
`name` varchar(256) NOT NULL,
|
||||
`value` varchar(256),
|
||||
`name` varchar(128) NOT NULL,
|
||||
`value` varchar(255),
|
||||
PRIMARY KEY (`name` ASC)
|
||||
);""".format(self.db.table_prefix)):
|
||||
self.step_end(_step, -1, 'config表不存在且无法创建')
|
||||
|
|
|
@ -302,6 +302,13 @@ class TPDatabase:
|
|||
log.e('Unknown database type.\n')
|
||||
return False
|
||||
|
||||
def export_to_sql(self):
|
||||
# TODO: not implement.
|
||||
ret = []
|
||||
ret.append('{}'.format(self.db_type))
|
||||
ret.append('export to sql not implement.')
|
||||
return '\n'.join(ret)
|
||||
|
||||
|
||||
class TPDatabasePool:
|
||||
def __init__(self):
|
||||
|
@ -350,6 +357,7 @@ class TPDatabasePool:
|
|||
def _last_insert_id(self, conn):
|
||||
return -1
|
||||
|
||||
|
||||
class TPSqlitePool(TPDatabasePool):
|
||||
def __init__(self, db_file):
|
||||
super().__init__()
|
||||
|
|
|
@ -113,6 +113,8 @@ controllers = [
|
|||
# (r'/set/os-operator', set.OsOperator),
|
||||
# (r'/set/info', config.InfoHandler),
|
||||
# (r'/set/db', config.DatabaseHandler),
|
||||
(r'/config/export-database', config.ExportDatabaseHandler),
|
||||
(r'/config/import-database', config.ImportDatabaseHandler),
|
||||
(r'/config/', config.IndexHandler),
|
||||
(r'/config', config.IndexHandler),
|
||||
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
import os
|
||||
import time
|
||||
import json
|
||||
import tornado.gen
|
||||
import tornado.httpclient
|
||||
|
@ -8,6 +10,7 @@ from eom_ver import *
|
|||
from eom_app.app.db import get_db
|
||||
from eom_app.app.configs import app_cfg
|
||||
from eom_app.app.util import *
|
||||
from eom_common.eomcore.logger import log
|
||||
from .base import TPBaseAdminAuthHandler, TPBaseAdminAuthJsonHandler
|
||||
|
||||
cfg = app_cfg()
|
||||
|
@ -24,7 +27,6 @@ class IndexHandler(TPBaseAdminAuthHandler):
|
|||
if 'code' in return_data:
|
||||
_code = return_data['code']
|
||||
if _code == 0:
|
||||
# core['detected'] = True
|
||||
cfg.update_core(return_data['data'])
|
||||
core_detected = True
|
||||
|
||||
|
@ -52,138 +54,77 @@ class IndexHandler(TPBaseAdminAuthHandler):
|
|||
}
|
||||
self.render('config/index.mako', page_param=json.dumps(param))
|
||||
|
||||
# class InfoHandler(TPBaseAdminAuthHandler):
|
||||
# @tornado.gen.coroutine
|
||||
# def get(self):
|
||||
# core_detected = False
|
||||
# req = {'method': 'get_config', 'param': []}
|
||||
# _yr = async_post_http(req)
|
||||
# return_data = yield _yr
|
||||
# if return_data is not None:
|
||||
# if 'code' in return_data:
|
||||
# _code = return_data['code']
|
||||
# if _code == 0:
|
||||
# # core['detected'] = True
|
||||
# cfg.update_core(return_data['data'])
|
||||
# core_detected = True
|
||||
#
|
||||
# if not core_detected:
|
||||
# cfg.update_core(None)
|
||||
#
|
||||
# _db = get_db()
|
||||
# database = '未知'
|
||||
# if _db.db_source['type'] == _db.DB_TYPE_SQLITE:
|
||||
# database = 'SQLite({})'.format(_db.db_source['file'])
|
||||
# elif _db.db_source['type'] == _db.DB_TYPE_MYSQL:
|
||||
# database = 'MySQL'
|
||||
#
|
||||
# param = {
|
||||
# 'core': cfg.core,
|
||||
# 'web': {
|
||||
# 'version': TS_VER,
|
||||
# 'core_server_rpc': cfg['core_server_rpc'],
|
||||
# 'database': database
|
||||
# }
|
||||
# }
|
||||
# self.render('set/info.mako', page_param=json.dumps(param))
|
||||
|
||||
class ExportDatabaseHandler(TPBaseAdminAuthHandler):
|
||||
def get(self):
|
||||
self.set_header('Content-Type', 'application/octet-stream')
|
||||
self.set_header('Content-Disposition', 'attachment; filename=teleport-database-export.sql')
|
||||
|
||||
sql = get_db().export_to_sql()
|
||||
|
||||
# self.write("分组ID, 操作系统, IP地址, 端口, 协议, 状态, 描述, 系统用户, 系统密码, 是否加密, 附加参数, 密钥ID, 认证类型\n".encode('gbk'))
|
||||
self.write(sql)
|
||||
self.finish()
|
||||
|
||||
|
||||
# class DatabaseHandler(TPBaseAdminAuthHandler):
|
||||
# def get(self):
|
||||
# _db = get_db()
|
||||
# # database = '未知'
|
||||
# # if _db.db_source['type'] == _db.DB_TYPE_SQLITE:
|
||||
# # database = 'SQLite({})'.format(_db.db_source['file'])
|
||||
# # elif _db.db_source['type'] == _db.DB_TYPE_MYSQL:
|
||||
# # database = 'MySQL'
|
||||
#
|
||||
# param = {'db': _db.db_source}
|
||||
# self.render('set/database.mako', page_param=json.dumps(param))
|
||||
class ImportDatabaseHandler(TPBaseAdminAuthHandler):
|
||||
# TODO: 导入操作可能会比较耗时,应该分离导入和获取导入状态两个过程,在页面上可以呈现导入进度,并列出导出成功/失败的项
|
||||
|
||||
# def _restart_func():
|
||||
# time.sleep(1)
|
||||
#
|
||||
# PLATFORM = platform.system().lower()
|
||||
#
|
||||
# if PLATFORM == 'windows':
|
||||
# sf = os.path.join(cfg.app_path, 'tools', 'restart.bat')
|
||||
# os.system('cmd.exe /c "{}"'.format(sf))
|
||||
# else:
|
||||
# # sf = os.path.join(cfg.app_path, 'tools', 'restart.sh')
|
||||
# # os.system(sf)
|
||||
# os.system('service eom_ts restart')
|
||||
#
|
||||
# # os.system(sf)
|
||||
@tornado.gen.coroutine
|
||||
def post(self):
|
||||
"""
|
||||
sql导入规则:
|
||||
以事务方式执行sql语句
|
||||
"""
|
||||
ret = dict()
|
||||
ret['code'] = 0
|
||||
ret['message'] = ''
|
||||
# ret['data'] = {}
|
||||
# ret['data']['msg'] = list() # 记录跳过的行(格式不正确,或者数据重复等)
|
||||
sql_filename = ''
|
||||
|
||||
try:
|
||||
upload_path = os.path.join(cfg.data_path, 'tmp') # 文件的暂存路径
|
||||
if not os.path.exists(upload_path):
|
||||
os.mkdir(upload_path)
|
||||
file_metas = self.request.files['sqlfile'] # 提取表单中‘name’为‘file’的文件元数据
|
||||
for meta in file_metas:
|
||||
now = time.localtime(time.time())
|
||||
tmp_name = 'upload-{:04d}{:02d}{:02d}{:02d}{:02d}{:02d}.sql'.format(now.tm_year, now.tm_mon, now.tm_mday, now.tm_hour, now.tm_min, now.tm_sec)
|
||||
sql_filename = os.path.join(upload_path, tmp_name)
|
||||
with open(sql_filename, 'wb') as f:
|
||||
f.write(meta['body'])
|
||||
|
||||
# def restart_service():
|
||||
# # todo: 使用eom_ts.exe运行脚本的方式(新进程)来重启服务,避免正在运行的本服务未退出的影响
|
||||
#
|
||||
# t = threading.Thread(target=_restart_func)
|
||||
# t.start()
|
||||
#
|
||||
# file encode maybe utf8 or gbk... check it out.
|
||||
file_encode = None
|
||||
with open(sql_filename, encoding='utf8') as f:
|
||||
try:
|
||||
f.readlines()
|
||||
file_encode = 'utf8'
|
||||
except:
|
||||
pass
|
||||
|
||||
# class UpdateConfig(TPBaseAdminAuthJsonHandler):
|
||||
# def post(self):
|
||||
# args = self.get_argument('args', None)
|
||||
# if args is not None:
|
||||
# args = json.loads(args)
|
||||
# else:
|
||||
# self.write_json(-1)
|
||||
# return
|
||||
#
|
||||
# change_list = args['cfg']
|
||||
# reboot = args['reboot']
|
||||
#
|
||||
# try:
|
||||
# ret = set.set_config(change_list)
|
||||
# if ret:
|
||||
# for i in range(len(change_list)):
|
||||
# if change_list[i]['name'] == 'ts_server_ip':
|
||||
# # static_path = cfg.static_path
|
||||
# var_js = os.path.join(cfg.static_path, 'js', 'var.js')
|
||||
# f = None
|
||||
# try:
|
||||
# f = open(var_js, 'w')
|
||||
# # config_list = host.get_config_list()
|
||||
# # ts_server = dict()
|
||||
# # ts_server['ip'] = config_list['ts_server_ip']
|
||||
# # ts_server['ssh_port'] = config_list['ts_server_ssh_port']
|
||||
# # ts_server['rdp_port'] = config_list['ts_server_rdp_port']
|
||||
# # f.write("\"use strict\";\nvar teleport_ip = \"{}\";\n".format(ts_server['ip']))
|
||||
# f.write("\"use strict\";\nvar teleport_ip = \"{}\";\n".format(change_list[i]['value']))
|
||||
# break
|
||||
# except Exception:
|
||||
# return self.write(-1)
|
||||
# finally:
|
||||
# if f is not None:
|
||||
# f.close()
|
||||
#
|
||||
# if reboot:
|
||||
# restart_service()
|
||||
#
|
||||
# self.write_json(0)
|
||||
# else:
|
||||
# self.write_json(-1)
|
||||
# except:
|
||||
# self.write_json(-2)
|
||||
if file_encode is None:
|
||||
os.remove(sql_filename)
|
||||
log.e('file `{}` unknown encode, neither GBK nor UTF8.\n'.format(sql_filename))
|
||||
ret['code'] = -2
|
||||
ret['message'] = 'upload sql file is not utf8 encode.'
|
||||
return self.write(json.dumps(ret).encode('utf8'))
|
||||
|
||||
# class OsOperator(TPBaseUserAuthJsonHandler):
|
||||
# def post(self):
|
||||
# args = self.get_argument('args', None)
|
||||
# if args is not None:
|
||||
# args = json.loads(args)
|
||||
# else:
|
||||
# self.write_json(-1)
|
||||
# return
|
||||
# _OP = int(args['OP'])
|
||||
# try:
|
||||
# if _OP == 1:
|
||||
# os.system('reboot')
|
||||
# else:
|
||||
# os.system('shutdown -h now')
|
||||
# # 重新启动
|
||||
# self.write_json(0)
|
||||
# except:
|
||||
# self.write_json(-2)
|
||||
#
|
||||
with open(sql_filename, encoding=file_encode) as f:
|
||||
lines = f.readlines()
|
||||
for line in lines:
|
||||
print(line)
|
||||
pass
|
||||
|
||||
ret['code'] = 0
|
||||
return self.write(json.dumps(ret).encode('utf8'))
|
||||
except:
|
||||
log.e('error\n')
|
||||
ret['code'] = -6
|
||||
ret['message'] = '发生异常.'
|
||||
return self.write(json.dumps(ret).encode('utf8'))
|
||||
|
||||
finally:
|
||||
if os.path.exists(sql_filename):
|
||||
os.remove(sql_filename)
|
||||
|
|
|
@ -4,8 +4,10 @@ ywl.on_init = function (cb_stack, cb_args) {
|
|||
console.log(ywl.page_options);
|
||||
|
||||
var dom = {
|
||||
info: $('#info-kv')
|
||||
info: $('#info-kv'),
|
||||
// , btn_maintance: $('#btn_maintenance')
|
||||
btn_db_export: $('#btn-db-export'),
|
||||
btn_db_import: $('#btn-db-import'),
|
||||
};
|
||||
|
||||
var html = [];
|
||||
|
@ -66,9 +68,79 @@ ywl.on_init = function (cb_stack, cb_args) {
|
|||
// });
|
||||
// });
|
||||
//
|
||||
|
||||
dom.btn_db_export.click(function () {
|
||||
alert('not implement.');
|
||||
window.location.href = '/config/export-database'
|
||||
});
|
||||
dom.btn_db_import.click(function () {
|
||||
alert('not implement.');
|
||||
|
||||
var _fn_sure = function (cb_stack, cb_args) {
|
||||
var html = '<input id="upload-file" type="file" name="sqlfile" class="hidden" value="" style="display: none;"/>';
|
||||
dom.btn_db_import.after($(html));
|
||||
var update_file = $("#upload-file");
|
||||
|
||||
update_file.change(function () {
|
||||
var file_path = $(this).val();
|
||||
if (file_path === null || file_path === undefined || file_path === '') {
|
||||
return;
|
||||
}
|
||||
ywl.do_upload_sql_file();
|
||||
});
|
||||
|
||||
update_file.trigger('click');
|
||||
};
|
||||
|
||||
var cb_stack = CALLBACK_STACK.create();
|
||||
ywl.dlg_confirm(cb_stack, {
|
||||
msg: '<p><strong>注意:操作不可恢复!!</strong></p><p>您确定要清除所有现有数据,然后导入sql文件吗?</p>',
|
||||
fn_yes: _fn_sure
|
||||
});
|
||||
});
|
||||
|
||||
cb_stack.exec();
|
||||
};
|
||||
|
||||
ywl.do_upload_sql_file = function () {
|
||||
var param = {};
|
||||
$.ajaxFileUpload({
|
||||
url: "/config/import-database",// 需要链接到服务器地址
|
||||
secureuri: false,
|
||||
fileElementId: "upload-file", // 文件选择框的id属性
|
||||
dataType: 'text', // 服务器返回的格式,可以是json
|
||||
data: param,
|
||||
success: function (data) {
|
||||
$('#upload-file').remove();
|
||||
var ret = JSON.parse(data);
|
||||
if (ret.code === TPE_OK) {
|
||||
// g_host_table.reload();
|
||||
ywl.notify_success('导入sql成功!');
|
||||
// if (ret.data.msg.length > 0) {
|
||||
// var html = [];
|
||||
// html.push('<ul>');
|
||||
// for (var i = 0, cnt = ret.data.msg.length; i < cnt; ++i) {
|
||||
// html.push('<li>');
|
||||
// html.push('<span style="font-weight:bold;color:#993333;">' + ret.data.msg[i].reason + '</span><br/>');
|
||||
// html.push(ret.data.msg[i].line);
|
||||
// html.push('</li>');
|
||||
// }
|
||||
// html.push('</ul>');
|
||||
//
|
||||
// // $('#batch_add_host_result').html(html.join(''));
|
||||
//// $('#dialog_batch_add_host').modal({backdrop: 'static'});
|
||||
// }
|
||||
} else {
|
||||
ywl.notify_error('导入sql失败! 错误号:' + ret.code);
|
||||
}
|
||||
},
|
||||
error: function () {
|
||||
$('#upload-file').remove();
|
||||
ywl.notify_error('网络故障,导入sql失败!');
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
ywl._make_protocol_info = function (name, p) {
|
||||
if (_.isUndefined(p))
|
||||
return ywl._make_info(name, '未能检测到');
|
||||
|
|
|
@ -8,7 +8,7 @@ ywl.on_init = function (cb_stack, cb_args) {
|
|||
//===================================
|
||||
// 表格数据
|
||||
var disk_rate = 0;
|
||||
if(0 == ywl.page_options.total_size) {
|
||||
if(0 === ywl.page_options.total_size) {
|
||||
$('#disk-status').text('未能获取到录像文件所在磁盘空间信息');
|
||||
} else {
|
||||
disk_rate = parseInt(ywl.page_options.free_size * 100 / ywl.page_options.total_size);
|
||||
|
|
|
@ -19,6 +19,24 @@
|
|||
|
||||
<%block name="extend_css">
|
||||
<style type="text/css">
|
||||
.box {
|
||||
padding-left: 30px;
|
||||
}
|
||||
|
||||
h2 {
|
||||
margin-left:-20px;
|
||||
font-size:160%;
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: 120%;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.table {
|
||||
width: auto;
|
||||
}
|
||||
|
||||
.table .key {
|
||||
text-align: right;
|
||||
}
|
||||
|
@ -35,6 +53,19 @@
|
|||
.table .value .disabled {
|
||||
color: #ffa861;
|
||||
}
|
||||
|
||||
.db-box {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.notice-box {
|
||||
border: 1px solid #e2cab4;
|
||||
background-color: #ffe4cb;
|
||||
padding: 15px;
|
||||
color: #000000;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
</style>
|
||||
</%block>
|
||||
|
||||
|
@ -46,14 +77,27 @@
|
|||
<div class="box">
|
||||
|
||||
<div>
|
||||
<h4><strong>服务器配置信息</strong></h4>
|
||||
<h2><strong>服务器配置信息</strong></h2>
|
||||
<table id="info-kv" class="table"></table>
|
||||
</div>
|
||||
|
||||
## <div>
|
||||
## <h4><strong>高级设置</strong></h4>
|
||||
## <p><a href="javascript:;" id="btn_maintenance">进入维护模式</a></p>
|
||||
## </div>
|
||||
<div>
|
||||
<hr/>
|
||||
<h2><strong>数据库管理</strong></h2>
|
||||
|
||||
<div class="db-box">
|
||||
<h3>导出</h3>
|
||||
<p>将数据库中所有数据导出到sql文件,可用作备份。</p>
|
||||
<button type="button" id="btn-db-export" class="btn btn-sm btn-primary"><i class="fa fa-sign-out fa-fw"></i> 导出数据库</button>
|
||||
</div>
|
||||
|
||||
<div class="db-box">
|
||||
<h3>导入</h3>
|
||||
<p>清空当前数据库中所有数据,然后从sql文件中导入数据到数据库中。</p>
|
||||
<p class="notice-box">注意!导入操作将导致现有数据被清除且无法恢复,请谨慎使用!</p>
|
||||
<button type="button" id="btn-db-import" class="btn btn-sm btn-danger"><i class="fa fa-sign-in fa-fw"></i> 导入数据库</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<!-- end of box -->
|
||||
|
|
Loading…
Reference in New Issue