mirror of https://github.com/tp4a/teleport
support export database.
parent
f99d39e2fa
commit
b4be3de0b3
|
@ -706,6 +706,7 @@ $app.create_config_storage = function () {
|
||||||
storage_size: $('#storage-size'),
|
storage_size: $('#storage-size'),
|
||||||
btn_save: $('#btn-save-storage-config'),
|
btn_save: $('#btn-save-storage-config'),
|
||||||
btn_cleanup: $('#btn-clear-storage'),
|
btn_cleanup: $('#btn-clear-storage'),
|
||||||
|
btn_export_db: $('#btn-export-db'),
|
||||||
|
|
||||||
input_keep_log: $('#storage-keep-log'),
|
input_keep_log: $('#storage-keep-log'),
|
||||||
input_keep_record: $('#storage-keep-record'),
|
input_keep_record: $('#storage-keep-record'),
|
||||||
|
@ -735,6 +736,10 @@ $app.create_config_storage = function () {
|
||||||
_sto.on_btn_cleanup();
|
_sto.on_btn_cleanup();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
_sto.dom.btn_export_db.click(function() {
|
||||||
|
_sto.on_export_db();
|
||||||
|
});
|
||||||
|
|
||||||
cb_stack.exec();
|
cb_stack.exec();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -835,5 +840,9 @@ $app.create_config_storage = function () {
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
_sto.on_export_db = function() {
|
||||||
|
window.location.href = '/system/export-db';
|
||||||
|
};
|
||||||
|
|
||||||
return _sto;
|
return _sto;
|
||||||
};
|
};
|
||||||
|
|
|
@ -378,6 +378,21 @@
|
||||||
<button id="btn-clear-storage" class="btn btn-sm btn-success"><i class="fa fa-leaf fa-fw"></i> 现在立即清理</button>
|
<button id="btn-clear-storage" class="btn btn-sm btn-success"><i class="fa fa-leaf fa-fw"></i> 现在立即清理</button>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td colspan="2" class="title">
|
||||||
|
<hr class="hr-sm"/>
|
||||||
|
数据库导出
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td class="key"></td>
|
||||||
|
<td class="value">
|
||||||
|
<button id="btn-export-db" class="btn btn-sm btn-success"><i class="fa fa-leaf fa-fw"></i> 导出到SQL</button>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
|
||||||
</table>
|
</table>
|
||||||
<hr/>
|
<hr/>
|
||||||
<button id="btn-save-storage-config" class="btn btn-sm btn-primary"><i class="fa fa-check-circle fa-fw"></i> 保存存储设置</button>
|
<button id="btn-save-storage-config" class="btn btn-sm btn-primary"><i class="fa fa-check-circle fa-fw"></i> 保存存储设置</button>
|
||||||
|
|
|
@ -14,22 +14,49 @@ def _db_exec(db, step_begin, step_end, msg, sql):
|
||||||
step_end(_step, 0)
|
step_end(_step, 0)
|
||||||
|
|
||||||
|
|
||||||
def _export_table(db, table_name, fields):
|
def _export_table(db, table_name):
|
||||||
|
table_name = '{}{}'.format(db.table_prefix, table_name)
|
||||||
|
f = db.get_fields(table_name)
|
||||||
|
fields = [i[0] for i in f]
|
||||||
|
types = [i[1] for i in f]
|
||||||
|
if fields is None:
|
||||||
|
return '错误:表 {} 不存在'.format(table_name)
|
||||||
|
s = list()
|
||||||
|
for t in types:
|
||||||
|
if (t.lower().find('char') != -1) or (t.lower().find('text') != -1):
|
||||||
|
s.append(True)
|
||||||
|
else:
|
||||||
|
s.append(False)
|
||||||
|
|
||||||
ret = ['', '-- table: {}'.format(table_name), '-- fields: {}'.format(', '.join(fields)), 'TRUNCATE TABLE `{}`;'.format(table_name)]
|
ret = ['', '-- table: {}'.format(table_name), '-- fields: {}'.format(', '.join(fields)), 'TRUNCATE TABLE `{}`;'.format(table_name)]
|
||||||
|
|
||||||
fields_str = '`,`'.join(fields)
|
fields_str = '`,`'.join(fields)
|
||||||
sql = 'SELECT `{}` FROM `{}{}`'.format(fields_str, db.table_prefix, table_name)
|
sql = 'SELECT `{}` FROM `{}`'.format(fields_str, table_name)
|
||||||
d = db.query(sql)
|
d = db.query(sql)
|
||||||
if not d or len(d) == 0:
|
if not d or len(d) == 0:
|
||||||
ret.append('-- table is empty.')
|
ret.append('-- table is empty.')
|
||||||
else:
|
else:
|
||||||
fields_count = len(fields)
|
fields_count = len(fields)
|
||||||
for i in range(len(d)):
|
for i in range(len(d)):
|
||||||
x = []
|
# x = []
|
||||||
|
# for j in range(fields_count):
|
||||||
|
# x.append(d[i][j].__str__())
|
||||||
|
# val = "','".join(x).replace('\n', '\\n')
|
||||||
|
x = list()
|
||||||
for j in range(fields_count):
|
for j in range(fields_count):
|
||||||
x.append(d[i][j].__str__())
|
# if j > 0:
|
||||||
val = "','".join(x).replace('\n', '\\n')
|
# x.append(',')
|
||||||
sql = "INSERT INTO `{}` VALUES ('{}');".format(table_name, val)
|
if s[j]:
|
||||||
|
if d[i][j] is None:
|
||||||
|
x.append('NULL')
|
||||||
|
else:
|
||||||
|
x.append('"{}"'.format(d[i][j].replace(r'"', r'\"')))
|
||||||
|
else:
|
||||||
|
x.append('{}'.format(d[i][j]))
|
||||||
|
val = ','.join(x)
|
||||||
|
print('VAL:', val, '\n')
|
||||||
|
|
||||||
|
sql = "INSERT INTO `{}` VALUES ({});".format(table_name, val)
|
||||||
ret.append(sql)
|
ret.append(sql)
|
||||||
|
|
||||||
return '\r\n'.join(ret)
|
return '\r\n'.join(ret)
|
||||||
|
@ -52,21 +79,41 @@ def export_database(db):
|
||||||
else:
|
else:
|
||||||
ret.append('-- DATABASE VERSION {}'.format(db_ret[0][0]))
|
ret.append('-- DATABASE VERSION {}'.format(db_ret[0][0]))
|
||||||
|
|
||||||
_fields = ['account_id', 'account_type', 'account_name', 'account_pwd', 'account_status', 'account_lock', 'account_desc', 'oath_secret']
|
# _fields = ['account_id', 'account_type', 'account_name', 'account_pwd', 'account_status', 'account_lock', 'account_desc', 'oath_secret']
|
||||||
ret.append(_export_table(db, 'account', _fields))
|
# ret.append(_export_table(db, 'account', _fields))
|
||||||
_fields = ['auth_id', 'account_name', 'host_id', 'host_auth_id']
|
# _fields = ['auth_id', 'account_name', 'host_id', 'host_auth_id']
|
||||||
ret.append(_export_table(db, 'auth', _fields))
|
# ret.append(_export_table(db, 'auth', _fields))
|
||||||
_fields = ['cert_id', 'cert_name', 'cert_pub', 'cert_pri', 'cert_desc']
|
# _fields = ['cert_id', 'cert_name', 'cert_pub', 'cert_pri', 'cert_desc']
|
||||||
ret.append(_export_table(db, 'key', _fields))
|
# ret.append(_export_table(db, 'key', _fields))
|
||||||
_fields = ['name', 'value']
|
# _fields = ['name', 'value']
|
||||||
ret.append(_export_table(db, 'config', _fields))
|
# ret.append(_export_table(db, 'config', _fields))
|
||||||
_fields = ['group_id', 'group_name']
|
# _fields = ['group_id', 'group_name']
|
||||||
ret.append(_export_table(db, 'group', _fields))
|
# ret.append(_export_table(db, 'group', _fields))
|
||||||
_fields = ['host_id', 'group_id', 'host_sys_type', 'host_ip', 'host_port', 'protocol', 'host_lock', 'host_desc']
|
# _fields = ['host_id', 'group_id', 'host_sys_type', 'host_ip', 'host_port', 'protocol', 'host_lock', 'host_desc']
|
||||||
ret.append(_export_table(db, 'host_info', _fields))
|
# ret.append(_export_table(db, 'host_info', _fields))
|
||||||
_fields = ['id', 'host_id', 'auth_mode', 'user_name', 'user_pswd', 'user_param', 'cert_id', 'encrypt', 'log_time']
|
# _fields = ['id', 'host_id', 'auth_mode', 'user_name', 'user_pswd', 'user_param', 'cert_id', 'encrypt', 'log_time']
|
||||||
ret.append(_export_table(db, 'auth_info', _fields))
|
# ret.append(_export_table(db, 'auth_info', _fields))
|
||||||
_fields = ['id', 'session_id', 'account_name', 'host_ip', 'host_port', 'sys_type', 'auth_type', 'protocol', 'user_name', 'ret_code', 'begin_time', 'end_time', 'log_time']
|
# _fields = ['id', 'session_id', 'account_name', 'host_ip', 'host_port', 'sys_type', 'auth_type', 'protocol', 'user_name', 'ret_code', 'begin_time', 'end_time', 'log_time']
|
||||||
ret.append(_export_table(db, 'log', _fields))
|
# ret.append(_export_table(db, 'log', _fields))
|
||||||
|
|
||||||
|
ret.append(_export_table(db, 'config'))
|
||||||
|
ret.append(_export_table(db, 'core_server'))
|
||||||
|
ret.append(_export_table(db, 'role'))
|
||||||
|
ret.append(_export_table(db, 'user'))
|
||||||
|
ret.append(_export_table(db, 'user_rpt'))
|
||||||
|
ret.append(_export_table(db, 'host'))
|
||||||
|
ret.append(_export_table(db, 'acc'))
|
||||||
|
ret.append(_export_table(db, 'acc_auth'))
|
||||||
|
ret.append(_export_table(db, 'group'))
|
||||||
|
ret.append(_export_table(db, 'group_map'))
|
||||||
|
ret.append(_export_table(db, 'ops_policy'))
|
||||||
|
ret.append(_export_table(db, 'ops_auz'))
|
||||||
|
ret.append(_export_table(db, 'ops_map'))
|
||||||
|
ret.append(_export_table(db, 'audit_policy'))
|
||||||
|
ret.append(_export_table(db, 'audit_auz'))
|
||||||
|
ret.append(_export_table(db, 'audit_map'))
|
||||||
|
ret.append(_export_table(db, 'syslog'))
|
||||||
|
ret.append(_export_table(db, 'record'))
|
||||||
|
ret.append(_export_table(db, 'record_audit'))
|
||||||
|
|
||||||
return '\r\n'.join(ret), True
|
return '\r\n'.join(ret), True
|
||||||
|
|
|
@ -177,6 +177,25 @@ class TPDatabase:
|
||||||
log.e('Unknown database type.\n')
|
log.e('Unknown database type.\n')
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
def get_fields(self, table_name):
|
||||||
|
fields = list()
|
||||||
|
if self.db_type == self.DB_TYPE_SQLITE:
|
||||||
|
ret = self.query('PRAGMA table_info(`{}`);'.format(table_name))
|
||||||
|
log.d('[sqlite] fields of {}'.format(table_name), ret, '\n')
|
||||||
|
if ret is None:
|
||||||
|
return None
|
||||||
|
for f in ret:
|
||||||
|
fields.append((f[1], f[2])) # field_name, field_type, e.g.: ('id', 'integer'), ('desc', 'varchar(255)')
|
||||||
|
elif self.db_type == self.DB_TYPE_MYSQL:
|
||||||
|
ret = self.query('SELECT `column_name` FROM `information_schema`.`columns` WHERE `table_schema`="db" AND `table_name`="{}";'.format(table_name))
|
||||||
|
log.d('[mysql] fields of {}'.format(table_name), ret, '\n')
|
||||||
|
if ret is None:
|
||||||
|
return None
|
||||||
|
for f in ret:
|
||||||
|
fields.append(f)
|
||||||
|
|
||||||
|
return fields
|
||||||
|
|
||||||
def is_field_exists(self, table_name, field_name):
|
def is_field_exists(self, table_name, field_name):
|
||||||
if self.db_type == self.DB_TYPE_SQLITE:
|
if self.db_type == self.DB_TYPE_SQLITE:
|
||||||
ret = self.query('PRAGMA table_info(`{}`);'.format(table_name))
|
ret = self.query('PRAGMA table_info(`{}`);'.format(table_name))
|
||||||
|
|
|
@ -160,6 +160,10 @@ def tp_second2human(n):
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
|
|
||||||
|
def tp_timestamp_from_str(t):
|
||||||
|
return 0
|
||||||
|
|
||||||
|
|
||||||
def tp_timestamp_sec():
|
def tp_timestamp_sec():
|
||||||
return int(datetime.datetime.now().timestamp())
|
return int(datetime.datetime.now().timestamp())
|
||||||
|
|
||||||
|
|
|
@ -262,6 +262,8 @@ controllers = [
|
||||||
(r'/system/do-ldap-get-users', system.DoLdapGetUsersHandler),
|
(r'/system/do-ldap-get-users', system.DoLdapGetUsersHandler),
|
||||||
# - [json] 导入LDAP用户
|
# - [json] 导入LDAP用户
|
||||||
(r'/system/do-ldap-import', system.DoLdapImportHandler),
|
(r'/system/do-ldap-import', system.DoLdapImportHandler),
|
||||||
|
# - [text] 导出数据库
|
||||||
|
(r'/system/export-db', system.DoExportDBHandler),
|
||||||
|
|
||||||
#
|
#
|
||||||
# - [json] 获取服务器时间
|
# - [json] 获取服务器时间
|
||||||
|
|
|
@ -4,6 +4,7 @@ import datetime
|
||||||
import hashlib
|
import hashlib
|
||||||
import json
|
import json
|
||||||
import shutil
|
import shutil
|
||||||
|
import time
|
||||||
|
|
||||||
import app.model.system as system_model
|
import app.model.system as system_model
|
||||||
import tornado.gen
|
import tornado.gen
|
||||||
|
@ -87,6 +88,18 @@ class RoleHandler(TPBaseHandler):
|
||||||
self.render('system/role.mako')
|
self.render('system/role.mako')
|
||||||
|
|
||||||
|
|
||||||
|
class DoExportDBHandler(TPBaseHandler):
|
||||||
|
def get(self):
|
||||||
|
ret = self.check_privilege(TP_PRIVILEGE_SYS_CONFIG)
|
||||||
|
if ret != TPE_OK:
|
||||||
|
return
|
||||||
|
sql, err = get_db().export_to_sql()
|
||||||
|
self.set_header('Content-Type', 'application/sql')
|
||||||
|
self.set_header('Content-Disposition', 'attachment; filename="teleport-db-export-{}.sql"'.format(time.strftime('%Y%m%d-%H%M%S')))
|
||||||
|
self.write(sql)
|
||||||
|
self.finish()
|
||||||
|
|
||||||
|
|
||||||
class DoRoleUpdateHandler(TPBaseJsonHandler):
|
class DoRoleUpdateHandler(TPBaseJsonHandler):
|
||||||
@tornado.gen.coroutine
|
@tornado.gen.coroutine
|
||||||
def post(self):
|
def post(self):
|
||||||
|
|
Loading…
Reference in New Issue