实现了主机、账号的禁用、解禁及删除对授权关系的影响。

pull/105/head
Apex Liu 2017-10-31 18:52:49 +08:00
parent 51b143c828
commit e075dcc690
9 changed files with 141 additions and 309 deletions

View File

@ -0,0 +1 @@
teleport

View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Encoding" defaultCharsetForPropertiesFiles="UTF-8">
<file url="PROJECT" charset="UTF-8" />
</component>
</project>

View File

@ -820,6 +820,8 @@ $app.create_dlg_edit_host = function () {
} else {
dlg.dom.edit_router_port.val('' + dlg.field_router_port);
}
} else {
dlg.field_router_port = 0;
}
return true;
@ -836,18 +838,20 @@ $app.create_dlg_edit_host = function () {
// router_addr = dlg.field_router_ip + ':' + dlg.field_router_port;
// }
var args = {
id: dlg.field_id,
os_type: dlg.field_os_type,
ip: dlg.field_ip,
router_ip: dlg.field_router_ip,
router_port: dlg.field_router_port,
name: dlg.field_name,
cid: dlg.field_cid,
desc: dlg.field_desc
};
console.log(args);
// 如果id为-1表示创建否则表示更新
$tp.ajax_post_json('/asset/update-host', {
id: dlg.field_id,
// role: dlg.field_role,
os_type: dlg.field_os_type,
ip: dlg.field_ip,
router_ip: dlg.field_router_ip,
router_port: dlg.field_router_port,
name: dlg.field_name,
cid: dlg.field_cid,
desc: dlg.field_desc
},
$tp.ajax_post_json('/asset/update-host', args,
function (ret) {
if (ret.code === TPE_OK) {
$tp.notify_success('远程主机' + action + '成功!');
@ -1306,7 +1310,8 @@ $app.create_dlg_edit_account = function () {
}
dlg.dom.auth_type.empty().append($(html.join('')));
dlg.dom.auth_type.val(dlg.account.auth_type);
//console.log(dlg.account);
//dlg.dom.auth_type.val(dlg.account.auth_type);
dlg.on_auth_change();
};

View File

@ -207,7 +207,7 @@ class TPDatabase:
def transaction(self, sql_list):
log.d('[db] transaction\n')
for sql in sql_list:
log.d('[db] {}\n'.format(sql))
log.d('[db] * {}\n'.format(sql))
# _start = datetime.datetime.utcnow().timestamp()
ret = self._conn_pool.transaction(sql_list)
@ -816,188 +816,6 @@ class SQL:
return TPE_OK
class MSQL:
def __init__(self, db):
self._db = db
self._select_fields = []
self._from = ''
# self._where = ''
self._group_by = ''
# self._order_by = ''
# self._order_sort = 'ASC'
self._order_by = []
self._limit = None
self._ret_page_index = 0
self._ret_total_recorder = 0
self._ret_recorder = []
def reset(self):
self._select_fields = []
self._from = ''
# self._where = ''
self._group_by = ''
self._order_by = []
# self._order_sort = 'ASC'
self._limit = None
self._ret_page_index = 0
self._ret_total_recorder = 0
self._ret_recorder = []
return self
@property
def total_count(self):
return self._ret_total_recorder
@property
def recorder(self):
return self._ret_recorder
@property
def page_index(self):
return self._ret_page_index
def SELECT(self, fields):
self._select_fields = fields
return self
def FROM(self, _from):
self._from = _from
return self
def GROUP_BY(self, _group_by):
self._group_by = _group_by
return self
def ORDER_BY(self, name, is_asc=True):
_sort = 'ASC' if is_asc else 'DESC'
self._order_by.append('{} {}'.format(name, _sort))
return self
def LIMIT(self, page_index, per_page):
self._limit = {'page_index': page_index, 'per_page': per_page}
return self
def select_from(self, name, fields, alt_name=None, out_map=None):
if len(fields) == 0:
raise RuntimeError('empty fields.')
if len(self._from) != 0:
raise RuntimeError('select_from() should call only once.')
self._from = {'n': name, 'a': name, 'f': fields}
if alt_name is not None:
self._from['a'] = alt_name
self._table_used.append(name)
self._alt_name.append(self._from['a'])
_o = {}
for f in fields:
_o[f] = f
if out_map is not None:
for k in out_map:
if k not in _o:
raise RuntimeError('invalid out_map. {} not in fields.'.format(k))
_o[k] = out_map[k]
_o = list()
for f in fields:
if out_map is not None and f in out_map:
_field = out_map[f]
else:
_field = f
if _field not in _o:
_o.append(_field)
else:
raise RuntimeError('duplicated output field: {}'.format(_field))
self._select_fields = ['{}.{}'.format(self._from['a'], k) for k in fields]
self._output_fields = _o
return self
def where(self, _where):
self._where = _where
return self
def order_by(self, name, is_asc=True):
self._order_by = name
self._order_sort = 'ASC' if is_asc else 'DESC'
return self
def limit(self, page_index, per_page):
self._limit = {'page_index': page_index, 'per_page': per_page}
return self
def _make_sql_query_string(self):
sql = list()
sql.append('SELECT {}'.format(','.join(self._select_fields)))
sql.append('FROM {}'.format(self._from))
# if len(self._where) > 0:
# sql.append('WHERE {}'.format(self._where))
if len(self._group_by) > 0:
sql.append('GROUP BY {}'.format(self._group_by))
if len(self._order_by) > 0:
sql.append('ORDER BY {}'.format(','.join(self._order_by)))
if self._limit is not None:
if self._ret_total_recorder <= self._limit['page_index'] * self._limit['per_page']:
self._ret_page_index = int(self._ret_total_recorder / self._limit['per_page']) - 1
if self._ret_page_index < 0:
self._ret_page_index = 0
else:
self._ret_page_index = self._limit['page_index']
sql.append('LIMIT {},{}'.format(self._ret_page_index * self._limit['per_page'], self._limit['per_page']))
sql.append(';')
return ' '.join(sql)
def _make_sql_counter_string(self):
sql = list()
sql.append('SELECT COUNT(*)')
sql.append('FROM {}'.format(self._from))
# if len(self._where) > 0:
# sql.append('WHERE {}'.format(self._where))
if len(self._group_by) > 0:
sql.append('GROUP BY {}'.format(self._group_by))
sql.append(';')
return ' '.join(sql)
def query(self):
# 如果要分页,那么需要计算记录总数
if self._limit is not None:
sql = self._make_sql_counter_string()
# log.d(sql, '\n')
db_ret = self._db.query(sql)
if db_ret is None or 0 == len(db_ret):
self._ret_page_index = 0
return TPE_OK
self._ret_total_recorder = db_ret[0][0]
if self._ret_total_recorder == 0:
self._ret_page_index = 0
return TPE_OK
sql = self._make_sql_query_string()
# log.d(sql, '\n')
db_ret = self._db.query(sql)
for db_item in db_ret:
item = AttrDict()
for i in range(len(self._select_fields)):
item[self._select_fields[i]] = db_item[i]
self._ret_recorder.append(item)
return TPE_OK
def get_db():
"""
:rtype : TPDatabase

View File

@ -223,10 +223,10 @@ class DoUpdateAccountHandler(TPBaseJsonHandler):
err = account.remove_account(self, host_id, acc_id)
return self.write_json(err)
elif action == 'lock':
err = account.lock_account(self, host_id, acc_id)
err = account.update_account_state(self, host_id, acc_id, TP_STATE_DISABLED)
return self.write_json(err)
elif action == 'unlock':
err = account.unlock_account(self, host_id, acc_id)
err = account.update_account_state(self, host_id, acc_id, TP_STATE_NORMAL)
return self.write_json(err)
elif action == 'update':
try:

View File

@ -573,6 +573,7 @@ class DoUpdateHostHandler(TPBaseJsonHandler):
args['cid'] = args['cid'].strip()
args['desc'] = args['desc'].strip()
except:
log.e('\n')
return self.write_json(TPE_PARAM)
if len(args['ip']) == 0:
@ -611,10 +612,10 @@ class DoUpdateHostsHandler(TPBaseJsonHandler):
return self.write_json(TPE_PARAM)
if action == 'lock':
err = host.lock_hosts(self, host_ids)
err = host.update_hosts_state(self, host_ids, TP_STATE_DISABLED)
return self.write_json(err)
elif action == 'unlock':
err = host.unlock_hosts(self, host_ids)
err = host.update_hosts_state(self, host_ids, TP_STATE_NORMAL)
return self.write_json(err)
elif action == 'remove':
err = host.remove_hosts(self, host_ids)

View File

@ -250,59 +250,31 @@ def update_account(handler, host_id, acc_id, args):
return TPE_OK
def lock_account(handler, host_id, acc_id):
def update_account_state(handler, host_id, acc_id, state):
db = get_db()
# 1. 判断是否存在
sql = 'SELECT id FROM {}acc WHERE id={};'.format(db.table_prefix, acc_id)
sql = 'SELECT id FROM {}acc WHERE host_id={host_id} AND id={acc_id};'.format(db.table_prefix, host_id=host_id, acc_id=acc_id)
db_ret = db.query(sql)
if db_ret is None or len(db_ret) == 0:
return TPE_NOT_EXISTS
sql = list()
sql.append('UPDATE `{}acc` SET'.format(db.table_prefix))
sql_list = []
_set = list()
_set.append('state={}'.format(TP_STATE_DISABLED))
sql = 'UPDATE `{}acc` SET state={state} WHERE id={acc_id};' \
''.format(db.table_prefix, state=state, acc_id=acc_id)
sql_list.append(sql)
sql.append(','.join(_set))
sql.append('WHERE id={};'.format(acc_id))
# sync to update the ops-audit table.
sql = 'UPDATE `{}ops_map` SET a_state={state} WHERE a_id={acc_id};' \
''.format(db.table_prefix, state=state, acc_id=acc_id)
sql_list.append(sql)
db_ret = db.exec(' '.join(sql))
if not db_ret:
if db.transaction(sql_list):
return TPE_OK
else:
return TPE_DATABASE
# TODO: update ops_map.
return TPE_OK
def unlock_account(handler, host_id, acc_id):
db = get_db()
# 1. 判断是否存在
sql = 'SELECT id FROM {}acc WHERE id={};'.format(db.table_prefix, acc_id)
db_ret = db.query(sql)
if db_ret is None or len(db_ret) == 0:
return TPE_NOT_EXISTS
sql = list()
sql.append('UPDATE `{}acc` SET'.format(db.table_prefix))
_set = list()
_set.append('state={}'.format(TP_STATE_NORMAL))
sql.append(','.join(_set))
sql.append('WHERE id={};'.format(acc_id))
db_ret = db.exec(' '.join(sql))
if not db_ret:
return TPE_DATABASE
# TODO: update ops_map.
return TPE_OK
def remove_account(handler, host_id, acc_id):
"""
@ -324,22 +296,26 @@ def remove_account(handler, host_id, acc_id):
if len(s.recorder[0]['router_ip']) > 0:
acc_name += '(由{}:{}路由)'.format(s.recorder[0]['router_ip'], s.recorder[0]['router_port'])
sql_list = []
sql = 'DELETE FROM `{}group_map` WHERE type={} AND mid={};'.format(db.table_prefix, TP_GROUP_ACCOUNT, acc_id)
db_ret = db.exec(sql)
if not db_ret:
return TPE_DATABASE
sql_list.append(sql)
sql = 'DELETE FROM `{}acc` WHERE id={} AND host_id={};'.format(db.table_prefix, acc_id, host_id)
db_ret = db.exec(sql)
if not db_ret:
return TPE_DATABASE
sql_list.append(sql)
# 更新主机相关账号数量
sql = 'UPDATE `{}host` SET acc_count=acc_count-1 WHERE id={host_id};' \
''.format(db.table_prefix, host_id=host_id)
db_ret = db.exec(sql)
sql = 'UPDATE `{}host` SET acc_count=acc_count-1 WHERE id={host_id};'.format(db.table_prefix, host_id=host_id)
sql_list.append(sql)
# TODO: update ops_map.
sql = 'DELETE FROM `{}ops_auz` WHERE rtype={rtype} AND rid={rid};'.format(db.table_prefix, rtype=TP_ACCOUNT, rid=acc_id)
sql_list.append(sql)
sql = 'DELETE FROM `{}ops_map` WHERE a_id={acc_id};'.format(db.table_prefix, acc_id=acc_id)
sql_list.append(sql)
if not db.transaction(sql_list):
return TPE_DATABASE
syslog.sys_log(handler.get_current_user(), handler.request.remote_ip, TPE_OK, "删除账号:{}".format(acc_name))

View File

@ -120,22 +120,20 @@ def add_host(handler, args):
def remove_hosts(handler, hosts):
db = get_db()
host_ids = [str(i) for i in hosts]
host_ids = ','.join([str(i) for i in hosts])
sql_list = []
# step 1. 处理主机对应的账号
# 1.1 获取账号列表
s = SQL(db)
s.select_from('acc', ['id', 'host_ip', 'router_ip', 'router_port', 'username'], alt_name='a')
s.where('a.host_id IN ({})'.format(','.join(host_ids)))
s.where('a.host_id IN ({})'.format(host_ids))
err = s.query()
if err != TPE_OK:
return err
# sql = 'SELECT id, host_ip, router_ip, router_port FROM {}acc WHERE {};'.format(db.table_prefix, where)
# db_ret = db.query(sql)
# if db_ret is None:
# return TPE_DATABASE
#
acc_ids = []
acc_names = []
for acc in s.recorder:
@ -151,22 +149,27 @@ def remove_hosts(handler, hosts):
# 1.2 将账号从所在组中移除
where = 'mid IN ({})'.format(','.join(acc_ids))
sql = 'DELETE FROM `{}group_map` WHERE (type={} AND {});'.format(db.table_prefix, TP_GROUP_ACCOUNT, where)
if not db.exec(sql):
return TPE_DATABASE
sql_list.append(sql)
# if not db.exec(sql):
# return TPE_DATABASE
# 1.3 将账号删除
where = 'id IN ({})'.format(','.join(acc_ids))
sql = 'DELETE FROM `{}acc` WHERE {};'.format(db.table_prefix, where)
if not db.exec(sql):
return TPE_DATABASE
sql_list.append(sql)
# if not db.exec(sql):
# return TPE_DATABASE
if len(acc_names) > 0:
syslog.sys_log(handler.get_current_user(), handler.request.remote_ip, TPE_OK, "删除账号:{}".format(''.join(acc_names)))
sql = 'DELETE FROM `{}ops_auz` WHERE rtype={rtype} AND rid IN({rid});'.format(db.table_prefix, rtype=TP_ACCOUNT, rid=','.join(acc_ids))
sql_list.append(sql)
sql = 'DELETE FROM `{}ops_map` WHERE a_id IN({});'.format(db.table_prefix, ','.join(acc_ids))
sql_list.append(sql)
# step 2. 处理主机
s = SQL(db)
s.select_from('host', ['ip', 'router_ip', 'router_port'], alt_name='h')
s.where('h.id IN ({})'.format(','.join(host_ids)))
s.where('h.id IN ({})'.format(host_ids))
err = s.query()
if err != TPE_OK:
return err
@ -180,17 +183,25 @@ def remove_hosts(handler, hosts):
host_names.append(h_name)
# 2.1 将主机从所在组中移除
where = 'mid IN ({})'.format(','.join(host_ids))
where = 'mid IN ({})'.format(host_ids)
sql = 'DELETE FROM `{}group_map` WHERE (type={} AND {});'.format(db.table_prefix, TP_GROUP_HOST, where)
if not db.exec(sql):
return TPE_DATABASE
sql_list.append(sql)
# 2.2 将主机删除
where = 'id IN ({})'.format(','.join(host_ids))
where = 'id IN ({})'.format(host_ids)
sql = 'DELETE FROM `{}host` WHERE {};'.format(db.table_prefix, where)
if not db.exec(sql):
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_list.append(sql)
sql = 'DELETE FROM `{}ops_map` WHERE h_id IN({});'.format(db.table_prefix, ','.join(host_ids))
sql_list.append(sql)
if not db.transaction(sql_list):
return TPE_DATABASE
if len(acc_names) > 0:
syslog.sys_log(handler.get_current_user(), handler.request.remote_ip, TPE_OK, "删除账号:{}".format(''.join(acc_names)))
if len(host_names) > 0:
syslog.sys_log(handler.get_current_user(), handler.request.remote_ip, TPE_OK, "删除主机:{}".format(''.join(host_names)))
@ -209,57 +220,65 @@ def update_host(handler, args):
if db_ret is None or len(db_ret) == 0:
return TPE_NOT_EXISTS
sql_list = []
sql = 'UPDATE `{}host` SET os_type="{os_type}", name="{name}", ip="{ip}", router_ip="{router_ip}", router_port={router_port}, cid="{cid}", desc="{desc}" WHERE id={host_id};' \
''.format(db.table_prefix,
os_type=args['os_type'], name=args['name'], ip=args['ip'], router_ip=args['router_ip'], router_port=args['router_port'],
cid=args['cid'], desc=args['desc'], host_id=args['id']
)
db_ret = db.exec(sql)
if not db_ret:
return TPE_DATABASE
sql_list.append(sql)
# 更新所有此主机相关的账号
# host_addr = args['ip']
# if len(args['router_addr']) > 0:
# host_addr += '/'
# host_addr += args['router_addr']
sql = 'UPDATE `{}acc` SET ip="{ip}", router_ip="{router_ip}", router_port={router_port} WHERE host_id={id};' \
''.format(db.table_prefix,
ip=args['ip'], router_ip=args['router_ip'], router_port=args['router_port'], id=args['id'])
db_ret = db.exec(sql)
sql_list.append(sql)
return TPE_OK
def lock_hosts(handler, host_ids):
db = get_db()
ids = [str(i) for i in host_ids]
sql = 'UPDATE `{}host` SET state={state} WHERE id IN ({ids});' \
''.format(db.table_prefix,
state=TP_STATE_DISABLED, ids=','.join(ids))
db_ret = db.exec(sql)
if not db_ret:
if db.transaction(sql_list):
return TPE_OK
else:
return TPE_DATABASE
return TPE_OK
def unlock_hosts(handler, host_ids):
def update_hosts_state(handler, host_ids, state):
db = get_db()
ids = [str(i) for i in host_ids]
host_ids = ','.join([str(i) for i in host_ids])
sql = 'UPDATE `{}host` SET state={state} WHERE id IN ({ids});' \
''.format(db.table_prefix,
state=TP_STATE_NORMAL, ids=','.join(ids))
db_ret = db.exec(sql)
if not db_ret:
sql_list = []
sql = 'UPDATE `{}host` SET state={state} WHERE id IN ({host_ids});' \
''.format(db.table_prefix, state=state, host_ids=host_ids)
sql_list.append(sql)
# sync to update the ops-audit table.
sql = 'UPDATE `{}ops_map` SET h_state={state} WHERE h_id IN({host_ids});' \
''.format(db.table_prefix, state=state, host_ids=host_ids)
sql_list.append(sql)
if db.transaction(sql_list):
return TPE_OK
else:
return TPE_DATABASE
return TPE_OK
#
# def unlock_hosts(handler, host_ids):
# db = get_db()
#
# host_ids = ','.join([str(i) for i in host_ids])
# sql_list = []
#
# sql = 'UPDATE `{}host` SET state={state} WHERE id IN ({host_ids});' \
# ''.format(db.table_prefix, state=TP_STATE_NORMAL, host_ids=host_ids)
# sql_list.append(sql)
# sql = 'UPDATE `{}ops_map` SET h_state={state} WHERE h_id IN({host_ids});' \
# ''.format(db.table_prefix, state=TP_STATE_NORMAL, host_ids=host_ids)
# sql_list.append(sql)
#
# if db.transaction(sql_list):
# return TPE_OK
# else:
# return TPE_DATABASE
def get_group_with_member(sql_filter, sql_order, sql_limit):

View File

@ -4,7 +4,7 @@ import json
from app.const import *
from app.base.logger import log
from app.base.db import get_db, SQL, MSQL
from app.base.db import get_db, SQL
from app.model import syslog
from app.base.utils import AttrDict, tp_timestamp_utc_now
@ -673,11 +673,17 @@ def build_auz_map():
_accs[i.id] = i
# 加载所有的组
err = s.reset().select_from('group', ['id', 'state'], alt_name='g').query()
err = s.reset().select_from('group', ['id', 'type', 'state'], alt_name='g').query()
if err != TPE_OK:
return err
for i in s.recorder:
_groups[i.id] = i
if i.type == TP_GROUP_USER:
_gusers[i.id] = []
elif i.type == TP_GROUP_HOST:
_ghosts[i.id] = []
elif i.type == TP_GROUP_ACCOUNT:
_gaccs[i.id] = []
# 加载所有的组
err = s.reset().select_from('group_map', ['id', 'type', 'gid', 'mid'], alt_name='g').query()
@ -685,16 +691,16 @@ def build_auz_map():
return err
for g in s.recorder:
if g.type == TP_GROUP_USER:
if g.gid not in _gusers:
_gusers[g.gid] = []
# if g.gid not in _gusers:
# _gusers[g.gid] = []
_gusers[g.gid].append(_users[g.mid])
elif g.type == TP_GROUP_HOST:
if g.gid not in _ghosts:
_ghosts[g.gid] = []
# if g.gid not in _ghosts:
# _ghosts[g.gid] = []
_ghosts[g.gid].append(_hosts[g.mid])
elif g.type == TP_GROUP_ACCOUNT:
if g.gid not in _gaccs:
_gaccs[g.gid] = []
# if g.gid not in _gaccs:
# _gaccs[g.gid] = []
_gaccs[g.gid].append(_accs[g.mid])
# 加载所有策略明细