1. 修正批量导入模板在excel中打开是乱码的问题(必须使用utf8-BOM);2. dashboard页面可以显示基本信息数量了。

pull/105/head
Apex Liu 2017-11-27 18:54:10 +08:00
parent 9034daf0f3
commit c0bfcd2226
15 changed files with 225 additions and 669 deletions

1
.gitignore vendored
View File

@ -93,3 +93,4 @@ build/*
xcuserdata
profile
*.moved-aside
/server/share/tmp

View File

@ -122,6 +122,10 @@ class BuilderLinux(BuilderBase):
utils.copy_file(os.path.join(env.root_path, 'server', 'share', 'etc'), os.path.join(self.path_tmp_data, 'tmp', 'etc'), ('core.ini.in', 'core.ini'))
utils.copy_file(os.path.join(env.root_path, 'server', 'share', 'etc'), os.path.join(self.path_tmp_data, 'tmp', 'etc'), 'tp_ssh_server.key')
# fix new line flag
utils.fix_new_line_flag(os.path.join(self.path_tmp_data, 'tmp', 'etc', 'web.ini'))
utils.fix_new_line_flag(os.path.join(self.path_tmp_data, 'tmp', 'etc', 'core.ini'))
# out_path = os.path.join(env.root_path, 'out', 'eom_ts', ctx.target_path, ctx.dist_path)
# out_path = os.path.join(env.root_path, 'out', 'eom_ts', ctx.bits_path, 'bin')
# bin_path = os.path.join(self.tmp_path, 'bin')

View File

@ -355,6 +355,17 @@ def strip(filename):
return True
def fix_new_line_flag(filename):
cc.n('fix new line flag to CR for text file', filename)
if not os.path.exists(filename):
return False
cmd = 'dos2unix {}'.format(filename)
ret, _ = sys_exec(cmd, direct_output=True)
if ret != 0:
raise RuntimeError('failed to dos2unix file [{}], ret={}.'.format(filename, ret))
return True
def make_zip(src_path, to_file, from_parent=True):
cc.v('compress folder into .zip...')

View File

@ -1,5 +1,8 @@
#用户账号,用户姓名,登录认证方式,EMail,Mobile,QQ,微信,所属组,描述
zhangsan,张三,1,zhangsan@domain.tld,,12345678,112233,运维人员|审计员,
lisi,李四,1,lisi@domain.tld,,,,审计员,
wangwu,王五,1,wangwu@domain.tld,,,,,
bai.lee,李白,1,bai.lee@domain.tld,,10086,bai.lee,审计管理员,著名诗人、剑客
#IP,操作系统类型linux/win,名称,路由IP,路由端口,资产编号,账号,协议类型ssh/rdp/telnet,协议端口,认证类型no/pw/key,密码或私钥,账号提示仅telnet,密码提示仅telnet,分组,描述
1.2.3.4,linux,数据库,,,DB-0453,,,,,,,,数据库|阿里云-天津机房,
,,,,,,root,ssh,22,pw,abcd1234,,,管理员,
,,,,,,test,ssh,22,pw,abcd1234,,,测试|部署,
1.2.3.5,windows,,192.168.0.5,2054,,,,,,,,,,阿里云,天津机房\naS2n129m
,,,,,,administrator,rdp,,pw,abcd1234,,,管理员,
1.2.3.6,linux,,,,,,,,,,,,,
,,,,,,root,ssh,22,key,abcd1234,,,管理员,

1 #用户账号 #IP 用户姓名 操作系统类型(linux/win) 登录认证方式 名称 EMail 路由IP Mobile 路由端口 QQ 资产编号 微信 账号 所属组 协议类型(ssh/rdp/telnet) 协议端口 认证类型(no/pw/key) 密码或私钥 账号提示(仅telnet) 密码提示(仅telnet) 分组 描述
2 zhangsan 1.2.3.4 张三 linux 1 数据库 zhangsan@domain.tld 12345678 DB-0453 112233 运维人员|审计员 数据库|阿里云-天津机房
3 lisi 李四 1 lisi@domain.tld root 审计员 ssh 22 pw abcd1234 管理员
4 wangwu 王五 1 wangwu@domain.tld test ssh 22 pw abcd1234 测试|部署
5 bai.lee 1.2.3.5 李白 windows 1 bai.lee@domain.tld 192.168.0.5 2054 10086 bai.lee 审计管理员 著名诗人、剑客 阿里云,天津机房\naS2n129m
6 administrator rdp pw abcd1234 管理员
7 1.2.3.6 linux
8 root ssh 22 key abcd1234 管理员

View File

@ -1,6 +1,6 @@
#用户账号示例文件使用CSV格式每行一个用户用英文逗号分隔共8个字段需要7个英文逗号,,,,,,,
#用户账号,用户姓名,EMail,Mobile,QQ,微信,所属组,描述
zhangsan,张三,zhangsan@domain.tld,,12345678,112233,运维人员|审计员,
lisi,李四,lisi@domain.tld,,,,审计员,
wangwu,,,,,,,
bai.lee,李白,bai.lee@domain.tld,,10086,bai.lee,审计管理员,著名诗人
#用户账号示例文件使用CSV格式每行一个用户用英文逗号分隔共8个字段需要7个英文逗号,,,,,,,
#用户账号,用户姓名,EMail,Mobile,QQ,微信,所属组,描述
zhangsan,张三,zhangsan@domain.tld,,12345678,112233,运维人员|审计员,
lisi,李四,lisi@domain.tld,,,,审计员,
wangwu,,,,,,,
bai.lee,李白,bai.lee@domain.tld,,10086,bai.lee,审计管理员,著名诗人

1 #用户账号示例文件,使用CSV格式,每行一个用户,用英文逗号分隔,共8个字段,需要7个英文逗号
2 #用户账号 用户姓名 EMail Mobile QQ 微信 所属组 描述
3 zhangsan 张三 zhangsan@domain.tld 12345678 112233 运维人员|审计员
4 lisi 李四 lisi@domain.tld 审计员
5 wangwu
6 bai.lee 李白 bai.lee@domain.tld 10086 bai.lee 审计管理员 著名诗人

View File

@ -0,0 +1,42 @@
"use strict";
$app.on_init = function (cb_stack) {
$app.dom = {
count_user: $('#count-user')
, count_host: $('#count-host')
, count_acc: $('#count-acc')
, count_conn: $('#count-conn')
};
// refresh basic info every 1m.
$app.load_basic_info();
// refresh overload info every 5m.
$app.load_overload_info();
cb_stack.exec();
};
$app.load_basic_info = function () {
$tp.ajax_post_json('/dashboard/do-get-basic', {},
function (ret) {
console.log(ret);
if (ret.code === TPE_OK) {
$app.dom.count_user.text(ret.data.count_user);
$app.dom.count_host.text(ret.data.count_host);
$app.dom.count_acc.text(ret.data.count_acc);
$app.dom.count_conn.text(ret.data.count_conn);
} else {
console.log('do-get-basic failed' + tp_error_msg(ret.code, ret.message));
}
},
function () {
console.log('can not connect to server.');
}
);
setTimeout($app.load_basic_info, 60*1000);
};
$app.load_overload_info = function () {
};

View File

@ -5,9 +5,9 @@
%>
<%inherit file="../page_base.mako"/>
## <%block name="extend_js_file">
## <script type="text/javascript" src="${ static_url('js/ui/config/info.js') }"></script>
## </%block>
<%block name="extend_js_file">
<script type="text/javascript" src="${ static_url('js/dashboard/dashboard.js') }"></script>
</%block>
<%block name="extend_css_file">
<link href="${ static_url('css/dashboard.css') }" rel="stylesheet" type="text/css"/>
@ -27,7 +27,7 @@
</div>
<div class="stats-content">
<div class="stats-name">用户</div>
<div class="stats-value">-</div>
<div class="stats-value" id="count-user">-</div>
</div>
</div>
</div>
@ -38,7 +38,7 @@
</div>
<div class="stats-content">
<div class="stats-name">主机</div>
<div class="stats-value">-</div>
<div class="stats-value" id="count-host">-</div>
</div>
</div>
</div>
@ -49,7 +49,7 @@
</div>
<div class="stats-content">
<div class="stats-name">主机账号</div>
<div class="stats-value">-</div>
<div class="stats-value" id="count-acc">-</div>
</div>
</div>
</div>
@ -60,7 +60,7 @@
</div>
<div class="stats-content">
<div class="stats-name">当前连接</div>
<div class="stats-value">-</div>
<div class="stats-value" id="count-conn">-</div>
</div>
</div>
</div>

View File

@ -70,7 +70,7 @@
<tr>
<td class="key">WEB会话超时</td>
<td class="value">
<input id="sec-session-timeout" type="text" value="30"/><span class="unit">分钟</span><span class="desc">5~1440。超过设定时长无操作用户将被强制登出。默认为30分钟。</span>
<input id="sec-session-timeout" type="text" value="30"/><span class="unit">分钟</span><span class="desc">5~1440。超过设定时长无操作用户将被强制登出。默认为60分钟。</span>
</td>
</tr>
<tr>

View File

@ -251,15 +251,15 @@ class TPDatabase:
log.e('database create and initialize failed.\n')
return False
def upgrade_database(self, step_begin, step_end):
log.v('start database upgrade process.\n')
if DatabaseUpgrade(self, step_begin, step_end).do_upgrade():
log.v('database upgraded.\n')
self.need_upgrade = False
return True
else:
log.e('database upgrade failed.\n')
return False
# def upgrade_database(self, step_begin, step_end):
# log.v('start database upgrade process.\n')
# if DatabaseUpgrade(self, step_begin, step_end).do_upgrade():
# log.v('database upgraded.\n')
# self.need_upgrade = False
# return True
# else:
# log.e('database upgrade failed.\n')
# return False
def alter_table(self, table_names, field_names=None):
"""
@ -450,7 +450,7 @@ class TPMysqlPool(TPDatabasePool):
def _do_connect(self):
try:
return pymysql.connect(host=self._host,
conn = pymysql.connect(host=self._host,
user=self._user,
passwd=self._password,
db=self._db_name,
@ -458,6 +458,10 @@ class TPMysqlPool(TPDatabasePool):
autocommit=False,
connect_timeout=3.0,
charset='utf8')
err = self._do_exec(conn, 'SET SESSION sql_mode=(SELECT REPLACE(@@sql_mode,"ONLY_FULL_GROUP_BY",""));', args=())
if err is None:
log.e('[mysql] can not disable ONLY_FULL_GROUP_BY flag.\n')
return conn
except pymysql.err.OperationalError as e:
errno, _ = e.args
if 2003 == errno:

View File

@ -24,6 +24,8 @@ controllers = [
# ====================================================
# - 控制台页面
(r'/dashboard', dashboard.IndexHandler),
# - [json] 获取基本信息
(r'/dashboard/do-get-basic', dashboard.DoGetBasicHandler),
# ====================================================
# 外部调用接口

View File

@ -1,7 +1,8 @@
# -*- coding: utf-8 -*-
from app.const import *
from app.base.controller import TPBaseHandler
from app.base.controller import TPBaseHandler, TPBaseJsonHandler
from app.model import stat
class IndexHandler(TPBaseHandler):
@ -11,3 +12,22 @@ class IndexHandler(TPBaseHandler):
return
self.render('dashboard/index.mako')
class DoGetBasicHandler(TPBaseJsonHandler):
def post(self):
ret = self.check_privilege(TP_PRIVILEGE_LOGIN_WEB)
if ret != TPE_OK:
return
err, info = stat.get_basic()
if err != TPE_OK:
return self.write_json(err)
# ret = dict()
# ret['count_user'] = 5
# ret['count_host'] = 5
# ret['count_acc'] = 5
# ret['count_conn'] = 5
self.write_json(TPE_OK, data=info)

View File

@ -4,6 +4,7 @@ import time
import csv
import os
import json
import codecs
import ipaddress
import tornado.gen
import tornado.httpclient
@ -183,7 +184,7 @@ class DoImportHandler(TPBaseHandler):
# file encode maybe utf8 or gbk... check it out.
file_encode = None
with open(csv_filename, encoding='gbk') as f:
with codecs.open(csv_filename, 'r', encoding='gbk') as f:
try:
f.readlines()
file_encode = 'gbk'
@ -191,10 +192,11 @@ class DoImportHandler(TPBaseHandler):
pass
if file_encode is None:
with open(csv_filename, encoding='utf8') as f:
log.v('file `{}` is not gbk, try utf8\n'.format(csv_filename))
with codecs.open(csv_filename, 'r', encoding='utf_8_sig') as f:
try:
f.readlines()
file_encode = 'utf8'
file_encode = 'utf_8_sig'
except:
pass
@ -685,627 +687,3 @@ class DoGetHostGroupWithMemberHandler(TPBaseJsonHandler):
ret['total'] = total_count
ret['data'] = row_data
self.write_json(err, data=ret)
# class UpdateHandler(TPBaseUserAuthJsonHandler):
# def post(self):
# args = self.get_argument('args', None)
# if args is not None:
# args = json.loads(args)
# else:
# return self.write_json(-1, '参数错误')
#
# if 'host_id' not in args or 'kv' not in args:
# self.write_json(-2, '缺少必要参数')
#
# _ret = host.update(args['host_id'], args['kv'])
#
# if _ret:
# self.write_json(0)
# else:
# self.write_json(-3, '数据库操作失败')
#
#
# class LockHost(TPBaseUserAuthJsonHandler):
# def post(self):
# args = self.get_argument('args', None)
# if args is not None:
# args = json.loads(args)
# else:
# return self.write_json(-1, '参数错误')
#
# host_id = args['host_id']
# lock = args['lock']
# try:
# ret = host.lock_host(host_id, lock)
# if ret:
# return self.write_json(0)
# else:
# return self.write_json(-2, '数据库操作失败errcode:{}'.format(ret))
# except:
# log.e('lock host failed.\n')
# return self.write_json(-3, '发生异常')
#
#
# class DeleteHost(TPBaseUserAuthJsonHandler):
# def post(self):
# args = self.get_argument('args', None)
# if args is not None:
# args = json.loads(args)
# else:
# return self.write_json(-1, '参数错误')
#
# host_list = args['host_list']
# try:
# ret = host.delete_host(host_list)
# if ret:
# return self.write_json(0)
# else:
# return self.write_json(-2, '数据库操作失败errcode:{}'.format(ret))
# except:
# log.e('delete host failed.\n')
# return self.write_json(-3, '发生异常')
#
#
# class ExportHostHandler(TPBaseAdminAuthHandler):
# def get(self):
# self.set_header('Content-Type', 'application/octet-stream')
# self.set_header('Content-Disposition', 'attachment; filename=teleport-host-export.csv')
#
# order = dict()
# order['name'] = 'host_id'
# order['asc'] = True
# limit = dict()
# limit['page_index'] = 0
# limit['per_page'] = 999999
# _total, _hosts = host.get_all_host_info_list(dict(), order, limit, True)
#
# self.write("分组ID, 操作系统, IP地址, 端口, 协议, 状态, 描述, 系统用户, 系统密码, 是否加密, 附加参数, 密钥ID, 认证类型\n".encode('gbk'))
#
# try:
#
# for h in _hosts:
# auth_list = h['auth_list']
# # 分组ID, 操作系统, IP地址, 端口, 协议, 状态, 描述, 系统用户, 系统密码, 是否加密,附加参数, 密钥ID, 认证类型
# for j in auth_list:
# row_string = ''
# # row_string = str(h['host_id'])
# # row_string += ','
# row_string += str(h['group_id'])
# row_string += ','
# row_string += str(h['host_sys_type'])
# row_string += ','
# row_string += h['host_ip']
# row_string += ','
# row_string += str(h['host_port'])
# row_string += ','
# row_string += str(h['protocol'])
# row_string += ','
# row_string += str(h['host_lock'])
# row_string += ','
# row_string += h['host_desc']
# row_string += ','
#
# # row_string += str(j['host_auth_id'])
# # row_string += ','
# row_string += j['user_name']
# row_string += ','
# row_string += j['user_pswd']
# row_string += ','
# row_string += '1'
# row_string += ','
# user_param = j['user_param']
# if len(user_param) > 0:
# user_param = user_param.replace('\n', '\\n')
# row_string += user_param
# row_string += ','
# row_string += str(j['cert_id'])
# row_string += ','
# row_string += str(j['auth_mode'])
#
# self.write(row_string.encode('gbk'))
# self.write('\n')
#
# except IndexError:
# self.write('**********************************************\n'.encode('gbk'))
# self.write('!!错误!!\n'.encode('gbk'))
# self.write('导出过程中发生了错误!!\n'.encode('gbk'))
# self.write('**********************************************\n'.encode('gbk'))
# log.e('')
#
# self.finish()
#
#
# class GetCertList(TPBaseUserAuthJsonHandler):
# def post(self):
# _certs = host.get_cert_list()
# if _certs is None or len(_certs) == 0:
# return self.write_json(-1, '参数错误')
# else:
# return self.write_json(0, data=_certs)
#
#
# class AddCert(TPBaseUserAuthJsonHandler):
# @tornado.gen.coroutine
# def post(self):
# args = self.get_argument('args', None)
# if args is not None:
# args = json.loads(args)
# else:
# return self.write_json(-1, '参数错误')
#
# cert_pub = args['cert_pub']
# cert_pri = args['cert_pri']
# cert_name = args['cert_name']
#
# if len(cert_pri) == 0:
# return self.write_json(-2, '参数错误,数据不完整')
#
# _yr = async_enc(cert_pri)
# return_data = yield _yr
# if return_data is None:
# return self.write_json(-3, '调用核心服务加密失败')
#
# if 'code' not in return_data or return_data['code'] != 0:
# return self.write_json(-4, '核心服务加密返回错误')
#
# cert_pri = return_data['data']
#
# try:
# ret = host.add_cert(cert_pub, cert_pri, cert_name)
# if ret:
# return self.write_json(0)
# else:
# return self.write_json(-5, '数据库操作失败errcode:{}'.format(ret))
# except:
# log.e('add cert failed.\n')
# return self.write_json(-6, '发生异常')
#
#
# class DeleteCert(TPBaseUserAuthJsonHandler):
# def post(self):
# args = self.get_argument('args', None)
# if args is not None:
# args = json.loads(args)
# else:
# return self.write_json(-1, '参数错误')
#
# cert_id = args['cert_id']
#
# try:
# ret = host.delete_cert(cert_id)
# if ret:
# return self.write_json(0)
# else:
# if ret == -2:
# return self.write_json(-2, '')
# else:
# return self.write_json(-3, '数据库操作失败errcode:{}'.format(ret))
# except:
# log.e('add cert failed.\n')
# return self.write_json(-4, '发生异常')
#
#
# class UpdateCert(TPBaseUserAuthJsonHandler):
# @tornado.gen.coroutine
# def post(self):
# args = self.get_argument('args', None)
# if args is not None:
# args = json.loads(args)
# else:
# return self.write_json(-1, '参数错误')
#
# cert_id = args['cert_id']
# cert_pub = args['cert_pub']
# cert_pri = args['cert_pri']
# cert_name = args['cert_name']
#
# if len(cert_pri) > 0:
# _yr = async_enc(cert_pri)
# return_data = yield _yr
# if return_data is None:
# return self.write_json(-2, '调用核心服务加密失败')
#
# if 'code' not in return_data or return_data['code'] != 0:
# return self.write_json(-3, '核心服务加密返回错误')
#
# cert_pri = return_data['data']
#
# try:
# ret = host.update_cert(cert_id, cert_pub, cert_pri, cert_name)
# if ret:
# return self.write_json(0)
# else:
# return self.write_json(-4, '数据库操作失败errcode:{}'.format(ret))
# except:
# log.e('update cert failed.\n')
# return self.write_json(-5, '发生异常')
#
#
# class AddGroup(TPBaseUserAuthJsonHandler):
# def post(self):
# args = self.get_argument('args', None)
# if args is not None:
# args = json.loads(args)
# else:
# return self.write_json(-1, '参数错误')
#
# group_name = args['group_name']
# try:
# ret = host.add_group(group_name)
# if ret:
# return self.write_json(0)
# else:
# return self.write_json(-2, '数据库操作失败errcode:{}'.format(ret))
# except:
# log.e('add group failed.\n')
# return self.write_json(-3, '发生异常')
#
#
# class UpdateGroup(TPBaseUserAuthJsonHandler):
# def post(self):
# args = self.get_argument('args', None)
# if args is not None:
# args = json.loads(args)
# else:
# return self.write_json(-1, '参数错误')
#
# group_id = args['group_id']
# group_name = args['group_name']
# try:
# ret = host.update_group(group_id, group_name)
# if ret:
# return self.write_json(0)
# else:
# return self.write_json(-2, '数据库操作失败errcode:{}'.format(ret))
# except:
# log.e('update group failed.\n')
# return self.write_json(-3, '发生异常')
#
#
# class DeleteGroup(TPBaseUserAuthJsonHandler):
# def post(self):
# args = self.get_argument('args', None)
# if args is not None:
# args = json.loads(args)
# else:
# return self.write_json(-1, '参数错误')
#
# group_id = args['group_id']
# try:
# ret = host.delete_group(group_id)
# if ret == 0:
# return self.write_json(0)
# else:
# if ret == -2:
# return self.write_json(-2, '')
# else:
# return self.write_json(-3, '数据库操作失败errcode:{}'.format(ret))
# except:
# log.e('delete group failed.\n')
# return self.write_json(-4, '发生异常')
#
#
# class AddHostToGroup(TPBaseUserAuthJsonHandler):
# def post(self):
# args = self.get_argument('args', None)
# if args is not None:
# args = json.loads(args)
# else:
# return self.write_json(-1, '参数错误')
#
# host_list = args['host_list']
# group_id = args['group_id']
# try:
# ret = host.add_host_to_group(host_list, group_id)
# if ret:
# self.write_json(0)
# else:
# return self.write_json(-2, '数据库操作失败errcode:{}'.format(ret))
# return
# except:
# log.e('add host to group failed.\n')
# return self.write_json(-3, '发生异常')
#
#
# class GetSessionId(TPBaseUserAuthJsonHandler):
# @tornado.gen.coroutine
# def post(self, *args, **kwargs):
# args = self.get_argument('args', None)
# if args is not None:
# args = json.loads(args)
# else:
# return self.write_json(-1, '参数错误')
#
# if 'auth_id' not in args:
# return self.write_json(-1, '参数缺失')
#
# auth_id = args['auth_id']
#
# req = {'method': 'request_session', 'param': {'authid': auth_id}}
# _yr = async_post_http(req)
# return_data = yield _yr
# if return_data is None:
# return self.write_json(-2, '调用核心服务获取会话ID失败')
#
# if 'code' not in return_data:
# return self.write_json(-3, '核心服务获取会话ID时返回错误数据')
#
# _code = return_data['code']
# if _code != 0:
# return self.write_json(-4, '核心服务获取会话ID时返回错误 {}'.format(_code))
#
# try:
# session_id = return_data['data']['sid']
# except IndexError:
# return self.write_json(-5, '核心服务获取会话ID时返回错误数据')
#
# data = dict()
# data['session_id'] = session_id
#
# return self.write_json(0, data=data)
#
#
# class AdminGetSessionId(TPBaseUserAuthJsonHandler):
# @tornado.gen.coroutine
# def post(self, *args, **kwargs):
# args = self.get_argument('args', None)
# if args is not None:
# args = json.loads(args)
# else:
# return self.write_json(-1, '参数错误')
#
# if 'host_auth_id' not in args:
# return self.write_json(-1, '参数缺失')
#
# _host_auth_id = int(args['host_auth_id'])
#
# user = self.get_current_user()
#
# # host_auth_id 对应的是 ts_auth_info 表中的某个条目,含有具体的认证数据,因为管理员无需授权即可访问所有远程主机,因此
# # 直接给出 host_auth_id且account直接指明是当前登录用户其必然是管理员
#
# tmp_auth_info = host.get_host_auth_info(_host_auth_id)
# if tmp_auth_info is None:
# return self.write_json(-2, '指定数据不存在')
#
# tmp_auth_info['account_lock'] = 0
# tmp_auth_info['account_name'] = user['name']
#
# with tmp_auth_id_lock:
# global tmp_auth_id_base
# tmp_auth_id_base -= 1
# auth_id = tmp_auth_id_base
#
# # 将这个临时认证信息放到session中备后续查找使用10秒内有效
# session_manager().set('tmp-auth-info-{}'.format(auth_id), tmp_auth_info, 10)
#
# req = {'method': 'request_session', 'param': {'authid': auth_id}}
# _yr = async_post_http(req)
# return_data = yield _yr
# if return_data is None:
# return self.write_json(-3, '调用核心服务获取会话ID失败')
#
# if 'code' not in return_data:
# return self.write_json(-4, '核心服务获取会话ID时返回错误数据')
#
# _code = return_data['code']
# if _code != 0:
# return self.write_json(-5, '核心服务获取会话ID时返回错误 {}'.format(_code))
#
# try:
# session_id = return_data['data']['sid']
# except IndexError:
# return self.write_json(-5, '核心服务获取会话ID时返回错误数据')
#
# data = dict()
# data['session_id'] = session_id
#
# return self.write_json(0, data=data)
#
#
# class AdminFastGetSessionId(TPBaseAdminAuthJsonHandler):
# @tornado.gen.coroutine
# def post(self, *args, **kwargs):
# args = self.get_argument('args', None)
# if args is not None:
# args = json.loads(args)
# else:
# return self.write_json(-1, '参数错误')
#
# user = self.get_current_user()
#
# tmp_auth_info = dict()
#
# try:
# _host_auth_id = int(args['host_auth_id'])
# _user_pswd = args['user_pswd']
# _cert_id = int(args['cert_id'])
#
# tmp_auth_info['host_ip'] = args['host_ip']
# tmp_auth_info['host_port'] = int(args['host_port'])
# tmp_auth_info['sys_type'] = int(args['sys_type'])
# tmp_auth_info['protocol'] = int(args['protocol'])
# tmp_auth_info['user_name'] = args['user_name']
# tmp_auth_info['auth_mode'] = int(args['auth_mode'])
# tmp_auth_info['user_param'] = args['user_param']
# tmp_auth_info['encrypt'] = 1
# tmp_auth_info['account_lock'] = 0
# tmp_auth_info['account_name'] = user['name']
# except IndexError:
# return self.write_json(-2, '参数缺失')
#
# if tmp_auth_info['auth_mode'] == 1:
# if len(_user_pswd) == 0: # 修改登录用户信息时可能不会修改密码,因此页面上可能不会传来密码,需要从数据库中直接读取
# h = host.get_host_auth_info(_host_auth_id)
# tmp_auth_info['user_auth'] = h['user_auth']
# else: # 如果页面上修改了密码或者新建账号时设定了密码那么需要先交给core服务进行加密
# req = {'method': 'enc', 'param': {'p': _user_pswd}}
# _yr = async_post_http(req)
# return_data = yield _yr
# if return_data is None:
# return self.write_json(-3, '调用核心服务加密失败')
# if 'code' not in return_data or return_data['code'] != 0:
# return self.write_json(-3, '核心服务加密返回错误')
#
# tmp_auth_info['user_auth'] = return_data['data']['c']
#
# elif tmp_auth_info['auth_mode'] == 2:
# tmp_auth_info['user_auth'] = host.get_cert_info(_cert_id)
# if tmp_auth_info['user_auth'] is None:
# self.write_json(-100, '指定私钥不存在')
# return
# elif tmp_auth_info['auth_mode'] == 0:
# tmp_auth_info['user_auth'] = ''
# else:
# self.write_json(-101, '认证类型未知')
# return
#
# with tmp_auth_id_lock:
# global tmp_auth_id_base
# tmp_auth_id_base -= 1
# auth_id = tmp_auth_id_base
#
# session_manager().set('tmp-auth-info-{}'.format(auth_id), tmp_auth_info, 10)
#
# req = {'method': 'request_session', 'param': {'authid': auth_id}}
# _yr = async_post_http(req)
# return_data = yield _yr
# if return_data is None:
# return self.write_json(-3, '调用核心服务获取会话ID失败')
#
# if 'code' not in return_data:
# return self.write_json(-4, '核心服务获取会话ID时返回错误数据')
#
# _code = return_data['code']
# if _code != 0:
# return self.write_json(-5, '核心服务获取会话ID时返回错误 {}'.format(_code))
#
# try:
# session_id = return_data['data']['sid']
# except IndexError:
# return self.write_json(-5, '核心服务获取会话ID时返回错误数据')
#
# data = dict()
# data['session_id'] = session_id
#
# return self.write_json(0, data=data)
#
#
# class SysUserList(TPBaseUserAuthJsonHandler):
# def post(self, *args, **kwargs):
# args = self.get_argument('args', None)
# if args is not None:
# args = json.loads(args)
# else:
# return self.write_json(-1, '参数错误')
#
# try:
# host_id = args['host_id']
# except:
# return self.write_json(-1, '参数缺失')
#
# data = host.sys_user_list(host_id)
# return self.write_json(0, data=data)
#
#
# class SysUserAdd(TPBaseUserAuthJsonHandler):
# @tornado.gen.coroutine
# def post(self, *args, **kwargs):
# args = self.get_argument('args', None)
# if args is not None:
# args = json.loads(args)
# else:
# return self.write_json(-1, '参数错误')
#
# try:
# auth_mode = args['auth_mode']
# user_pswd = args['user_pswd']
# cert_id = args['cert_id']
# except:
# return self.write_json(-1, '参数缺失')
#
# if auth_mode == 1:
# if 0 == len(args['user_pswd']):
# return self.write_json(-2, '参数缺失')
#
# _yr = async_enc(user_pswd)
# return_data = yield _yr
# if return_data is None:
# return self.write_json(-3, '调用核心服务加密失败')
#
# if 'code' not in return_data or return_data['code'] != 0:
# return self.write_json(-3, '核心服务加密返回错误')
#
# args['user_pswd'] = return_data['data']
#
# user_id = host.sys_user_add(args)
# if user_id < 0:
# if user_id == -100:
# return self.write_json(user_id, '同名账户已经存在!')
# else:
# return self.write_json(user_id, '数据库操作失败!')
#
# return self.write_json(0)
#
#
# class SysUserUpdate(TPBaseUserAuthJsonHandler):
# @tornado.gen.coroutine
# def post(self, *args, **kwargs):
# args = self.get_argument('args', None)
# if args is not None:
# args = json.loads(args)
# else:
# return self.write_json(-1, '参数错误')
#
# if 'host_auth_id' not in args or 'kv' not in args:
# return self.write_json(-2, '参数缺失')
#
# kv = args['kv']
# if 'auth_mode' not in kv or 'user_pswd' not in kv or 'cert_id' not in kv:
# return self.write_json(-3, '参数缺失')
#
# auth_mode = kv['auth_mode']
# if 'user_pswd' in kv:
# user_pswd = kv['user_pswd']
# if 0 == len(user_pswd):
# args['kv'].pop('user_pswd')
# user_pswd = None
# else:
# user_pswd = None
#
# cert_id = kv['cert_id']
# if auth_mode == 1 and user_pswd is not None:
# _yr = async_enc(user_pswd)
# return_data = yield _yr
# if return_data is None:
# return self.write_json(-4, '调用核心服务加密失败')
#
# if 'code' not in return_data or return_data['code'] != 0:
# return self.write_json(-5, '核心服务加密返回错误')
#
# args['kv']['user_pswd'] = return_data['data']
#
# if host.sys_user_update(args['host_auth_id'], args['kv']):
# return self.write_json(0)
#
# return self.write_json(-6, '数据库操作失败')
#
#
# class SysUserDelete(TPBaseUserAuthJsonHandler):
# def post(self, *args, **kwargs):
# args = self.get_argument('args', None)
# if args is not None:
# args = json.loads(args)
# else:
# return self.write_json(-1, '参数错误')
#
# try:
# host_auth_id = args['host_auth_id']
# except IndexError:
# return self.write_json(-2, '参数缺失')
#
# if host.sys_user_delete(host_auth_id):
# return self.write_json(0)
#
# return self.write_json(-3, '数据库操作失败')

View File

@ -344,10 +344,11 @@ class DoImportHandler(TPBaseHandler):
pass
if file_encode is None:
with open(csv_filename, encoding='utf8') as f:
log.v('file `{}` is not gbk, try utf8\n'.format(csv_filename))
with open(csv_filename, encoding='utf_8_sig') as f:
try:
f.readlines()
file_encode = 'utf8'
file_encode = 'utf_8_sig'
except:
pass

View File

@ -118,6 +118,7 @@ def add_host(handler, args):
def remove_hosts(handler, hosts):
print('----', hosts)
db = get_db()
host_ids = ','.join([str(i) for i in hosts])
@ -134,36 +135,37 @@ def remove_hosts(handler, hosts):
if err != TPE_OK:
return err
acc_ids = []
accs = []
acc_names = []
for acc in s.recorder:
if str(acc['id']) not in acc_ids:
acc_ids.append(str(acc['id']))
if str(acc['id']) not in accs:
accs.append(str(acc['id']))
acc_name = '{}@{}'.format(acc['username'], acc['host_ip'])
if len(acc['router_ip']) > 0:
acc_name += '(由{}:{}路由)'.format(acc['router_ip'], acc['router_port'])
if acc_name not in acc_names:
acc_names.append(acc_name)
if len(acc_ids) > 0:
acc_ids = ','.join([i for i in accs])
if len(accs) > 0:
# 1.2 将账号从所在组中移除
where = 'mid IN ({})'.format(','.join(acc_ids))
where = 'mid IN ({})'.format(acc_ids)
sql = 'DELETE FROM `{}group_map` WHERE (type={} AND {});'.format(db.table_prefix, TP_GROUP_ACCOUNT, where)
sql_list.append(sql)
# if not db.exec(sql):
# return TPE_DATABASE
# 1.3 将账号删除
where = 'id IN ({})'.format(','.join(acc_ids))
where = 'id IN ({})'.format(acc_ids)
sql = 'DELETE FROM `{}acc` WHERE {};'.format(db.table_prefix, where)
sql_list.append(sql)
# if not db.exec(sql):
# return TPE_DATABASE
sql = 'DELETE FROM `{}ops_auz` WHERE rtype={rtype} AND rid IN ({rid});'.format(db.table_prefix, rtype=TP_ACCOUNT, rid=','.join(acc_ids))
sql = 'DELETE FROM `{}ops_auz` WHERE rtype={rtype} AND rid IN ({rid});'.format(db.table_prefix, rtype=TP_ACCOUNT, rid=acc_ids)
sql_list.append(sql)
sql = 'DELETE FROM `{}ops_map` WHERE a_id IN ({});'.format(db.table_prefix, ','.join(acc_ids))
sql = 'DELETE FROM `{}ops_map` WHERE a_id IN ({acc_ids});'.format(db.table_prefix, acc_ids=acc_ids)
sql_list.append(sql)
# step 2. 处理主机
@ -192,9 +194,9 @@ def remove_hosts(handler, hosts):
sql = 'DELETE FROM `{}host` WHERE {};'.format(db.table_prefix, where)
sql_list.append(sql)
sql = 'DELETE FROM `{}ops_auz` WHERE rtype={rtype} AND rid IN ({rid});'.format(db.table_prefix, rtype=TP_HOST, rid=','.join(host_ids))
sql = 'DELETE FROM `{}ops_auz` WHERE rtype={rtype} AND rid IN ({rid});'.format(db.table_prefix, rtype=TP_HOST, rid=host_ids)
sql_list.append(sql)
sql = 'DELETE FROM `{}ops_map` WHERE h_id IN ({});'.format(db.table_prefix, ','.join(host_ids))
sql = 'DELETE FROM `{}ops_map` WHERE h_id IN ({host_ids});'.format(db.table_prefix, host_ids=host_ids)
sql_list.append(sql)
if not db.transaction(sql_list):

View File

@ -0,0 +1,88 @@
# -*- coding: utf-8 -*-
from app.const import *
from app.base.db import get_db, SQL
from app.base.logger import log
from app.base.utils import tp_timestamp_utc_now
def get_basic():
db = get_db()
ret = {'count_user': 0,
'count_host': 0,
'count_acc': 0,
'count_conn': 0
}
sql = 'SELECT COUNT(*) FROM `{tpdb}user`;'.format(tpdb=db.table_prefix)
db_ret = db.query(sql)
if not db_ret or len(db_ret) == 0:
pass
else:
ret['count_user'] = db_ret[0][0]
sql = 'SELECT COUNT(*) FROM `{tpdb}host`;'.format(tpdb=db.table_prefix)
db_ret = db.query(sql)
if not db_ret or len(db_ret) == 0:
pass
else:
ret['count_host'] = db_ret[0][0]
sql = 'SELECT COUNT(*) FROM `{tpdb}acc`;'.format(tpdb=db.table_prefix)
db_ret = db.query(sql)
if not db_ret or len(db_ret) == 0:
pass
else:
ret['count_acc'] = db_ret[0][0]
sql = 'SELECT COUNT(*) FROM `{tpdb}record` WHERE `state` IN ({sess_running},{sess_started});'.format(tpdb=db.table_prefix, sess_running=TP_SESS_STAT_RUNNING, sess_started=TP_SESS_STAT_STARTED)
db_ret = db.query(sql)
if not db_ret or len(db_ret) == 0:
pass
else:
ret['count_conn'] = db_ret[0][0]
return TPE_OK, ret
def get_logs(sql_filter, sql_order, sql_limit):
s = SQL(get_db())
s.select_from('syslog', ['id', 'user_name', 'user_surname', 'client_ip', 'code', 'log_time', 'message'], alt_name='l')
str_where = ''
_where = list()
if len(sql_filter) > 0:
for k in sql_filter:
if k == 'log_user_name':
_where.append('l.user_name="{}"'.format(sql_filter[k]))
# elif k == 'search_record':
# _where.append('(h.name LIKE "%{}%" OR h.ip LIKE "%{}%" OR h.router_addr LIKE "%{}%" OR h.desc LIKE "%{}%" OR h.cid LIKE "%{}%")'.format(sql_filter[k], sql_filter[k], sql_filter[k], sql_filter[k], sql_filter[k]))
if len(_where) > 0:
str_where = '( {} )'.format(' AND '.join(_where))
s.where(str_where)
if sql_order is not None:
_sort = False if not sql_order['asc'] else True
if 'log_time' == sql_order['name']:
s.order_by('l.log_time', _sort)
# elif 'name' == sql_order['name']:
# s.order_by('h.name', _sort)
# elif 'os_type' == sql_order['name']:
# s.order_by('h.os_type', _sort)
# elif 'cid' == sql_order['name']:
# s.order_by('h.cid', _sort)
# elif 'state' == sql_order['name']:
# s.order_by('h.state', _sort)
else:
log.e('unknown order field: {}\n'.format(sql_order['name']))
return TPE_PARAM, s.total_count, s.recorder
if len(sql_limit) > 0:
s.limit(sql_limit['page_index'], sql_limit['per_page'])
err = s.query()
return err, s.total_count, s.recorder