diff --git a/server/www/teleport/app/eom_app/app/database/create.py b/server/www/teleport/app/eom_app/app/database/create.py index 47f8c86..3a045a3 100644 --- a/server/www/teleport/app/eom_app/app/database/create.py +++ b/server/www/teleport/app/eom_app/app/database/create.py @@ -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) diff --git a/server/www/teleport/app/eom_app/app/database/upgrade.py b/server/www/teleport/app/eom_app/app/database/upgrade.py index 7d7d393..c9175f3 100644 --- a/server/www/teleport/app/eom_app/app/database/upgrade.py +++ b/server/www/teleport/app/eom_app/app/database/upgrade.py @@ -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表不存在且无法创建') diff --git a/server/www/teleport/app/eom_app/app/db.py b/server/www/teleport/app/eom_app/app/db.py index e0b8f50..9b4fcc2 100644 --- a/server/www/teleport/app/eom_app/app/db.py +++ b/server/www/teleport/app/eom_app/app/db.py @@ -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__() diff --git a/server/www/teleport/app/eom_app/controller/__init__.py b/server/www/teleport/app/eom_app/controller/__init__.py index 21bee29..10a32f9 100644 --- a/server/www/teleport/app/eom_app/controller/__init__.py +++ b/server/www/teleport/app/eom_app/controller/__init__.py @@ -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), diff --git a/server/www/teleport/app/eom_app/controller/config.py b/server/www/teleport/app/eom_app/controller/config.py index 10f69fa..2cf38f7 100644 --- a/server/www/teleport/app/eom_app/controller/config.py +++ b/server/www/teleport/app/eom_app/controller/config.py @@ -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) diff --git a/server/www/teleport/static/js/ui/config/info.js b/server/www/teleport/static/js/ui/config/info.js index 8ff06da..8431334 100644 --- a/server/www/teleport/static/js/ui/config/info.js +++ b/server/www/teleport/static/js/ui/config/info.js @@ -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 = ''; + 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: '
注意:操作不可恢复!!
您确定要清除所有现有数据,然后导入sql文件吗?
', + 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('将数据库中所有数据导出到sql文件,可用作备份。
+ +清空当前数据库中所有数据,然后从sql文件中导入数据到数据库中。
+注意!导入操作将导致现有数据被清除且无法恢复,请谨慎使用!
+ +