Commit 123e05b7 authored by ibuler's avatar ibuler

[Update] 修改 heartbeat机制

parent 8452d75d
import datetime
import os
import time
import threading
......@@ -8,6 +9,7 @@ from .config import Config
from .sshd import SSHServer
from .httpd import HttpServer
from .logging import create_logger
from . import utils
__version__ = '0.4.0'
......@@ -67,17 +69,40 @@ class Coco:
self.httpd = HttpServer(self)
self.initial_service()
self.heartbeat()
self.monitor_sessions()
def heartbeat(self):
def _heartbeat():
def func():
while not self.stop_evt.is_set():
self.service.terminal_heartbeat()
_sessions = [s.to_json() for s in self.sessions]
tasks = self.service.terminal_heartbeat(_sessions)
if tasks:
self.handle_task(tasks)
time.sleep(self.config["HEARTBEAT_INTERVAL"])
thread = threading.Thread(target=_heartbeat)
thread = threading.Thread(target=func)
thread.daemon = True
thread.start()
def monitor_sessions(self):
def func():
while True:
for s in self.sessions:
if s.is_finished:
if s.date_finished is None:
self.sessions.remove(s)
continue
delta = datetime.datetime.now() - s.date_finished
if delta > datetime.timedelta(minutes=1):
self.sessions.remove(s)
time.sleep(5)
thread = threading.Thread(target=func)
thread.start()
def handle_task(self, tasks):
pass
def run_forever(self):
self.bootstrap()
print(time.ctime())
......@@ -132,7 +157,3 @@ class Coco:
def initial_service(self):
self.service = AppService(self)
self.service.initial()
def monitor_session(self):
pass
......@@ -34,7 +34,7 @@ class ProxyServer:
self.watch_win_size_change_async()
session.record_async()
session.bridge()
self.app.sessions.remove(session)
session.is_finished = True
def validate_permission(self, asset, system_user):
"""
......
......@@ -32,17 +32,17 @@ class InteractiveServer:
def display_banner(self):
self.client.send(char.CLEAR_CHAR)
banner = _("""\n {title} {user}, 欢迎使用Jumpserver开源跳板机系统 {end}\r\n\r
1) 输入 {green}ID{end} 直接登录 或 输入{green}部分 IP,主机名,备注{end} 进行搜索登录(如果唯一).\r
2) 输入 {green}/{end} + {green}IP, 主机名 or 备注 {end}搜索. 如: /ip\r
3) 输入 {green}P/p{end} 显示您有权限的主机.\r
4) 输入 {green}G/g{end} 显示您有权限的主机组.\r
5) 输入 {green}G/g{end} + {green}组ID{end} 显示该组下主机. 如: g1\r
6) 输入 {green}E/e{end} 批量执行命令.(未完成)\r
7) 输入 {green}U/u{end} 批量上传文件.(未完成)\r
8) 输入 {green}D/d{end} 批量下载文件.(未完成)\r
9) 输入 {green}H/h{end} 帮助.\r
0) 输入 {green}Q/q{end} 退出.\r\n""").format(
banner = _("""\n {title} {user}, 欢迎使用Jumpserver开源跳板机系统 {end}\r\n\r
1) 输入 {green}ID{end} 直接登录 或 输入{green}部分 IP,主机名,备注{end} 进行搜索登录(如果唯一).\r
2) 输入 {green}/{end} + {green}IP, 主机名{end} or {green}备注 {end}搜索. 如: /ip\r
3) 输入 {green}P/p{end} 显示您有权限的主机.\r
4) 输入 {green}G/g{end} 显示您有权限的主机组.\r
5) 输入 {green}G/g{end} + {green}组ID{end} 显示该组下主机. 如: g1\r
6) 输入 {green}E/e{end} 批量执行命令.(未完成)\r
7) 输入 {green}U/u{end} 批量上传文件.(未完成)\r
8) 输入 {green}D/d{end} 批量下载文件.(未完成)\r
9) 输入 {green}H/h{end} 帮助.\r
0) 输入 {green}Q/q{end} 退出.\r\n""").format(
title="\033[1;32m", green="\033[32m",
end="\033[0m", user=self.client.user
)
......@@ -160,7 +160,7 @@ class InteractiveServer:
amount_max_length = max(len(str(max([group.assets_amount for group in self.asset_groups]))), 10)
header = '{1:>%d} {0.name:%d} {0.assets_amount:<%s} ' % (id_max_length, name_max_length, amount_max_length)
comment_length = self.request.meta["width"] - len(header.format(fake_group, id_max_length))
line = header + '{0.comment:%s}' % (comment_length / 2) # comment中可能有中文
line = header + '{0.comment:%s}' % (comment_length//2) # comment中可能有中文
header += "{0.comment:%s}" % comment_length
self.client.send(title(header.format(fake_group, "ID")))
for index, group in enumerate(self.asset_groups):
......@@ -184,7 +184,7 @@ class InteractiveServer:
header = '{1:>%d} {0.hostname:%d} {0.ip:15} {0.system_users_join:%d} ' % \
(id_max_length, hostname_max_length, sysuser_max_length)
comment_length = self.request.meta["width"] - len(header.format(fake_asset, id_max_length))
line = header + '{0.comment:.%d}' % (comment_length / 2) # comment中可能有中文
line = header + '{0.comment:.%d}' % (comment_length // 2) # comment中可能有中文
header += '{0.comment:%s}' % comment_length
self.client.send(wr(title(header.format(fake_asset, "ID"))))
for index, asset in enumerate(self.search_result, 1):
......@@ -216,7 +216,7 @@ class InteractiveServer:
return None
while True:
self.client.send(wr(_("Choose one to login: ")))
self.client.send(wr(_("Choose one to login: "), after=1))
self.display_system_users(system_users)
opt = self.get_choice("ID> ")
if opt.isdigit() and len(system_users) > int(opt):
......
......@@ -23,7 +23,7 @@ class Session:
self.record_dir = record_dir # Dir to save session record
self.watchers = [] # Only watch session
self.sharers = [] # Join to the session, read and write
self.running = True
self.is_finished = False
self.replaying = True
self.date_created = datetime.datetime.now()
self.date_finished = None
......@@ -78,7 +78,7 @@ class Session:
logger.info("Start bridge session %s" % self.id)
self.sel.register(self.client, selectors.EVENT_READ)
self.sel.register(self.server, selectors.EVENT_READ)
while self.running:
while not self.is_finished:
events = self.sel.select()
for sock in [key.fileobj for key, _ in events]:
data = sock.recv(BUF_SIZE)
......@@ -91,7 +91,7 @@ class Session:
elif sock == self.client:
if len(data) == 0:
for watcher in self.watchers + self.sharers:
watcher.send(b"Client %s close the session" % self.client)
watcher.send("Client {} close the session".format(self.client).encode("utf-8"))
self.close()
break
self.server.send(data)
......@@ -119,7 +119,7 @@ class Session:
open(os.path.join(self.record_dir, self.id + ".time"), "w") as timef:
dataf.write("Script started on {}\n".format(time.asctime()).encode("utf-8"))
while self.running:
while not self.is_finished:
start_t = time.time()
data = child.recv(BUF_SIZE)
end_t = time.time()
......@@ -164,9 +164,22 @@ class Session:
pass
def close(self):
self.running = False
self.is_finished = True
self.date_finished = datetime.datetime.now()
self.server.close()
def to_json(self):
return {
"id": self.id,
"user": self.client.user.username,
"asset": self.server.asset.hostname,
"system_user": self.server.system_user.username,
"login_from": "ST",
"is_finished": self.is_finished,
"date_start": self.date_created.strftime("%Y-%m-%d %H:%M:%S"),
"date_finished": self.date_finished.strftime("%Y-%m-%d %H:%M:%S") if self.date_finished else None
}
def __str__(self):
return self.id
......
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