Commit e932076f authored by ibuler's avatar ibuler

[Update] 优化coco

parent b5221652
...@@ -6,14 +6,11 @@ import socket ...@@ -6,14 +6,11 @@ import socket
import threading import threading
import os import os
from jms.models import Asset, AssetGroup
from . import char from . import char
from .utils import wrap_with_line_feed as wr, wrap_with_title as title, \ from .utils import wrap_with_line_feed as wr, wrap_with_title as title, \
wrap_with_warning as warning, is_obj_attr_has, \ wrap_with_warning as warning, is_obj_attr_has, is_obj_attr_eq, \
is_obj_attr_eq, sort_assets, TtyIOParser, \ sort_assets, ugettext as _, get_logger, net_input, format_with_zh, \
ugettext as _, get_logger, net_input, format_with_zh, item_max_length, \ item_max_length, size_of_str_with_zh
size_of_str_with_zh
from .ctx import current_app, app_service from .ctx import current_app, app_service
from .proxy import ProxyServer from .proxy import ProxyServer
...@@ -28,7 +25,7 @@ class InteractiveServer: ...@@ -28,7 +25,7 @@ class InteractiveServer:
self.request = client.request self.request = client.request
self.assets = None self.assets = None
self._search_result = None self._search_result = None
self.asset_groups = None self.nodes = None
self.get_user_assets_async() self.get_user_assets_async()
self.get_user_nodes_async() self.get_user_nodes_async()
...@@ -58,8 +55,8 @@ class InteractiveServer: ...@@ -58,8 +55,8 @@ class InteractiveServer:
1) 输入 {green}ID{end} 直接登录 或 输入{green}部分 IP,主机名,备注{end} 进行搜索登录(如果唯一).\r 1) 输入 {green}ID{end} 直接登录 或 输入{green}部分 IP,主机名,备注{end} 进行搜索登录(如果唯一).\r
2) 输入 {green}/{end} + {green}IP, 主机名{end} or {green}备注 {end}搜索. 如: /ip\r 2) 输入 {green}/{end} + {green}IP, 主机名{end} or {green}备注 {end}搜索. 如: /ip\r
3) 输入 {green}p{end} 显示您有权限的主机.\r 3) 输入 {green}p{end} 显示您有权限的主机.\r
4) 输入 {green}g{end} 显示您有权限的主机组.\r 4) 输入 {green}g{end} 显示您有权限的节点\r
5) 输入 {green}g{end} + {green}组ID{end} 显示节点下主机. 如: g1\r 5) 输入 {green}g{end} + {green}组ID{end} 显示节点下主机. 如: g1\r
6) 输入 {green}h{end} 帮助.\r 6) 输入 {green}h{end} 帮助.\r
0) 输入 {green}q{end} 退出.\r\n""").format( 0) 输入 {green}q{end} 退出.\r\n""").format(
title="\033[1;32m", green="\033[32m", title="\033[1;32m", green="\033[32m",
...@@ -75,9 +72,9 @@ class InteractiveServer: ...@@ -75,9 +72,9 @@ class InteractiveServer:
elif opt in ['p', 'P', '']: elif opt in ['p', 'P', '']:
self.display_assets() self.display_assets()
elif opt in ['g', 'G']: elif opt in ['g', 'G']:
self.display_asset_groups() self.display_nodes()
elif opt.startswith("g") and opt.lstrip("g").isdigit(): elif opt.startswith("g") and opt.lstrip("g").isdigit():
self.display_group_assets(int(opt.lstrip("g"))) self.display_node_assets(int(opt.lstrip("g")))
elif opt in ['q', 'Q', 'exit', 'quit']: elif opt in ['q', 'Q', 'exit', 'quit']:
return self._sentinel return self._sentinel
elif opt in ['h', 'H']: elif opt in ['h', 'H']:
...@@ -94,18 +91,21 @@ class InteractiveServer: ...@@ -94,18 +91,21 @@ class InteractiveServer:
if q == '': if q == '':
result = self.assets result = self.assets
# 用户输入的是数字,可能想使用id唯一键搜索 # 用户输入的是数字,可能想使用id唯一键搜索
elif q.isdigit() and self.search_result and len(self.search_result) >= int(q): elif q.isdigit() and self.search_result and \
len(self.search_result) >= int(q):
result = [self.search_result[int(q) - 1]] result = [self.search_result[int(q) - 1]]
# 全匹配到则直接返回全匹配的 # 全匹配到则直接返回全匹配的
if len(result) == 0: if len(result) == 0:
_result = [asset for asset in self.assets if is_obj_attr_eq(asset, q)] _result = [asset for asset in self.assets
if is_obj_attr_eq(asset, q)]
if len(_result) == 1: if len(_result) == 1:
result = _result result = _result
# 最后模糊匹配 # 最后模糊匹配
if len(result) == 0: if len(result) == 0:
result = [asset for asset in self.assets if is_obj_attr_has(asset, q)] result = [asset for asset in self.assets
if is_obj_attr_has(asset, q)]
self.search_result = result self.search_result = result
...@@ -116,17 +116,17 @@ class InteractiveServer: ...@@ -116,17 +116,17 @@ class InteractiveServer:
""" """
self.search_and_display('') self.search_and_display('')
def display_asset_groups(self): def display_nodes(self):
if self.asset_groups is None: if self.nodes is None:
self.get_user_nodes() self.get_user_nodes()
if len(self.asset_groups) == 0: if len(self.nodes) == 0:
self.client.send(warning(_("无"))) self.client.send(warning(_("无")))
return return
id_length = max(len(str(len(self.asset_groups))), 5) id_length = max(len(str(len(self.nodes))), 5)
name_length = item_max_length(self.asset_groups, 15, key=lambda x: x.name) name_length = item_max_length(self.nodes, 15, key=lambda x: x.name)
amount_length = item_max_length(self.asset_groups, 10, amount_length = item_max_length(self.nodes, 10,
key=lambda x: x.assets_amount) key=lambda x: x.assets_amount)
size_list = [id_length, name_length, amount_length] size_list = [id_length, name_length, amount_length]
fake_data = ['ID', _("Name"), _("Assets")] fake_data = ['ID', _("Name"), _("Assets")]
...@@ -140,18 +140,18 @@ class InteractiveServer: ...@@ -140,18 +140,18 @@ class InteractiveServer:
fake_data.append(_("Comment")) fake_data.append(_("Comment"))
self.client.send(title(format_with_zh(size_list, *fake_data))) self.client.send(title(format_with_zh(size_list, *fake_data)))
for index, group in enumerate(self.asset_groups, 1): for index, group in enumerate(self.nodes, 1):
data = [index, group.name, group.assets_amount, group.comment] data = [index, group.name, group.assets_amount, group.comment]
self.client.send(wr(format_with_zh(size_list, *data))) self.client.send(wr(format_with_zh(size_list, *data)))
self.client.send(wr(_("总共: {}").format(len(self.asset_groups)), before=1)) self.client.send(wr(_("总共: {}").format(len(self.nodes)), before=1))
def display_group_assets(self, _id): def display_node_assets(self, _id):
if _id > len(self.asset_groups) or _id <= 0: if _id > len(self.nodes) or _id <= 0:
self.client.send(wr(warning("没有匹配分组,请重新输入"))) self.client.send(wr(warning("没有匹配分组,请重新输入")))
self.display_asset_groups() self.display_nodes()
return return
self.search_result = self.asset_groups[_id - 1].assets_granted self.search_result = self.nodes[_id - 1].assets_granted
self.display_search_result() self.display_search_result()
def display_search_result(self): def display_search_result(self):
...@@ -188,7 +188,7 @@ class InteractiveServer: ...@@ -188,7 +188,7 @@ class InteractiveServer:
self.display_search_result() self.display_search_result()
def get_user_nodes(self): def get_user_nodes(self):
self.asset_groups = app_service.get_user_asset_groups(self.client.user) self.nodes = app_service.get_user_asset_groups(self.client.user)
def get_user_nodes_async(self): def get_user_nodes_async(self):
thread = threading.Thread(target=self.get_user_nodes) thread = threading.Thread(target=self.get_user_nodes)
...@@ -198,30 +198,31 @@ class InteractiveServer: ...@@ -198,30 +198,31 @@ class InteractiveServer:
def filter_system_users(assets): def filter_system_users(assets):
for asset in assets: for asset in assets:
system_users_granted = asset.system_users_granted system_users_granted = asset.system_users_granted
high_priority = max([s.priority for s in system_users_granted]) if system_users_granted else 1 high_priority = max([s.priority for s in system_users_granted]) \
system_users_cleaned = [s for s in system_users_granted if s.priority == high_priority] if system_users_granted else 1
system_users_cleaned = [s for s in system_users_granted
if s.priority == high_priority]
asset.system_users_granted = system_users_cleaned asset.system_users_granted = system_users_cleaned
return assets return assets
def get_user_assets(self): def get_user_assets(self):
self.assets = app_service.get_user_assets(self.client.user) self.assets = app_service.get_user_assets(self.client.user)
logger.debug("Get user {} assets total: {}".format(self.client.user, len(self.assets))) logger.debug("Get user {} assets total: {}".format(
self.client.user, len(self.assets))
)
def get_user_assets_async(self): def get_user_assets_async(self):
thread = threading.Thread(target=self.get_user_assets) thread = threading.Thread(target=self.get_user_assets)
thread.start() thread.start()
def choose_system_user(self, system_users): def choose_system_user(self, system_users):
# highest_priority = max([s.priority for s in system_users])
# system_users = [s for s in system_users if s == highest_priority]
if len(system_users) == 1: if len(system_users) == 1:
return system_users[0] return system_users[0]
elif len(system_users) == 0: elif len(system_users) == 0:
return None return None
while True: while True:
self.client.send(wr(_("选择一个登: "), after=1)) self.client.send(wr(_("选择一个登: "), after=1))
self.display_system_users(system_users) self.display_system_users(system_users)
opt = net_input(self.client, prompt="ID> ") opt = net_input(self.client, prompt="ID> ")
if opt.isdigit() and len(system_users) > int(opt): if opt.isdigit() and len(system_users) > int(opt):
...@@ -242,7 +243,9 @@ class InteractiveServer: ...@@ -242,7 +243,9 @@ class InteractiveServer:
if self.search_result and len(self.search_result) == 1: if self.search_result and len(self.search_result) == 1:
asset = self.search_result[0] asset = self.search_result[0]
if asset.platform == "Windows": if asset.platform == "Windows":
self.client.send(warning(_("终端不支持登录windows, 请使用web terminal访问"))) self.client.send(warning(
_("终端不支持登录windows, 请使用web terminal访问"))
)
return return
self.proxy(asset) self.proxy(asset)
else: else:
......
...@@ -90,8 +90,9 @@ class ProxyServer: ...@@ -90,8 +90,9 @@ class ProxyServer:
width = request.meta.get('width', 80) width = request.meta.get('width', 80)
height = request.meta.get('height', 24) height = request.meta.get('height', 24)
ssh = SSHConnection() ssh = SSHConnection()
chan, msg = ssh.get_channel(asset, system_user, term=term, chan, msg = ssh.get_channel(
width=width, height=height) asset, system_user, term=term, width=width, height=height
)
if not chan: if not chan:
self.client.send(warning(wr(msg, before=1, after=0))) self.client.send(warning(wr(msg, before=1, after=0)))
server = None server = None
...@@ -125,9 +126,11 @@ class ProxyServer: ...@@ -125,9 +126,11 @@ class ProxyServer:
def send_connecting_message(self, asset, system_user): def send_connecting_message(self, asset, system_user):
def func(): def func():
delay = 0.0 delay = 0.0
self.client.send('Connecting to {}@{} {:.1f}'.format(system_user, asset, delay)) self.client.send('Connecting to {}@{} {:.1f}'.format(
system_user, asset, delay)
)
while self.connecting and delay < TIMEOUT: while self.connecting and delay < TIMEOUT:
self.client.send('\x08\x08\x08{:.1f}'.format(delay).encode('utf-8')) self.client.send('\x08\x08\x08{:.1f}'.format(delay).encode())
time.sleep(0.1) time.sleep(0.1)
delay += 0.1 delay += 0.1
thread = threading.Thread(target=func) thread = threading.Thread(target=func)
......
...@@ -40,7 +40,7 @@ class Session: ...@@ -40,7 +40,7 @@ class Session:
""" """
logger.info("Session add watcher: {} -> {} ".format(self.id, watcher)) logger.info("Session add watcher: {} -> {} ".format(self.id, watcher))
if not silent: if not silent:
watcher.send("Welcome to watch session {}\r\n".format(self.id).encode("utf-8")) watcher.send("Welcome to watch session {}\r\n".format(self.id).encode())
self.sel.register(watcher, selectors.EVENT_READ) self.sel.register(watcher, selectors.EVENT_READ)
self._watchers.append(watcher) self._watchers.append(watcher)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment