Commit 555448c4 authored by ibuler's avatar ibuler

[Fixture] 完成日志记录

parent 86cf253e
...@@ -2,9 +2,9 @@ ...@@ -2,9 +2,9 @@
import logging import logging
import time import time
import threading
from flask import Flask from flask import Flask
import socketio
from flask_socketio import SocketIO from flask_socketio import SocketIO
from .conf import config from .conf import config
from .service import service from .service import service
...@@ -18,19 +18,52 @@ __version__ = '0.4.0' ...@@ -18,19 +18,52 @@ __version__ = '0.4.0'
class Luna(Flask): class Luna(Flask):
service = service service = service
clients = {}
proxy_list = {} proxy_list = {}
clients = {}
active = True active = True
def run(self, host=None, port=None, debug=None, **options): def bootstrap(self):
print(time.ctime()) print(time.ctime())
print('Luna version %s, more see https://www.jumpserver.org' % __version__) print(
'Luna version %s, more see https://www.jumpserver.org' % __version__)
print('Starting ssh server at %(host)s:%(port)s' % print('Starting ssh server at %(host)s:%(port)s' %
{'host': self.config['BIND_HOST'], {'host': self.config['BIND_HOST'],
'port': self.config['LISTEN_PORT']}) 'port': self.config['LISTEN_PORT']})
print('Quit the server with CONTROL-C.') print('Quit the server with CONTROL-C.')
self.heatbeat()
def handle_task(self, tasks):
for task in tasks:
if task['name'] == 'kill_proxy':
try:
proxy_log_id = int(task['proxy_log_id'])
except ValueError:
pass
if proxy_log_id in self.proxy_list:
client_channel, backend_channel = self.proxy_list.get(
proxy_log_id)
client_channel.send('Terminated by admin ')
backend_channel.close()
client_channel.close()
def heatbeat(self):
def _keep():
while True:
result = service.terminal_heatbeat()
if result is None:
logger.warning('Terminal heatbeat failed or '
'Terminal need accepted by administrator')
else:
tasks = result.get('tasks')
if tasks:
logger.info('Receive task: %s' % tasks)
print(tasks)
self.handle_task(tasks)
time.sleep(config.HEATBEAT_INTERVAL)
return Flask.run(self, host=host, port=port, debug=debug, **options) thread = threading.Thread(target=_keep)
thread.daemon = True
thread.start()
def stop(self): def stop(self):
self.active = False self.active = False
...@@ -38,9 +71,9 @@ class Luna(Flask): ...@@ -38,9 +71,9 @@ class Luna(Flask):
i.disconnect() i.disconnect()
socket_io.stop() socket_io.stop()
async_mode = 'threading' async_mode = 'gevent'
app = Luna(__name__, template_folder='dist') app = Luna(__name__, template_folder='dist')
socket_io = SocketIO(app) socket_io = SocketIO(app, async_mode=async_mode)
app.config.update(**config) app.config.update(**config)
#socket_io = socketio.Server(logger=False, async_mode=async_mode) #socket_io = socketio.Server(logger=False, async_mode=async_mode)
#app.wsgi_app = socketio.Middleware(socket_io, app.wsgi_app) #app.wsgi_app = socketio.Middleware(socket_io, app.wsgi_app)
...@@ -16,7 +16,7 @@ class ProxyChannel(object): ...@@ -16,7 +16,7 @@ class ProxyChannel(object):
def send(self, s): def send(self, s):
"""Proxy server中使用select, 通过socketio发送给用户""" """Proxy server中使用select, 通过socketio发送给用户"""
return socket_io.emit('data', s, root=self.sid) return socket_io.emit('data', s, room=self.sid)
def recv(self, size): def recv(self, size):
"""Proxy server使用select, 接受socketio客户端数据发送来的数据""" """Proxy server使用select, 接受socketio客户端数据发送来的数据"""
...@@ -24,10 +24,17 @@ class ProxyChannel(object): ...@@ -24,10 +24,17 @@ class ProxyChannel(object):
def write(self, s): def write(self, s):
"""socket io写数据,proxy可以通过recv收到""" """socket io写数据,proxy可以通过recv收到"""
print('Client write message: %s' % s)
self.cli.send(s) self.cli.send(s)
def set_win_size(self, size): def set_win_size(self, size):
self.win_width, self.win_height = size win_width, win_height = size
try:
self.win_width = int(win_width)
self.win_height = int(win_height)
except TypeError:
pass
def close(self):
self.srv.close()
self.cli.close()
...@@ -328,6 +328,8 @@ var AppService = (function () { ...@@ -328,6 +328,8 @@ var AppService = (function () {
socket.on('connect', function () { socket.on('connect', function () {
socket.emit('machine', uuid); socket.emit('machine', uuid);
exports.DataStore.term[id]["term"].on('data', function (data) { exports.DataStore.term[id]["term"].on('data', function (data) {
// console.log(data);
// socket.emit('data', 'echo 你好');
socket.emit('data', data); socket.emit('data', data);
}); });
socket.on('data', function (data) { socket.on('data', function (data) {
......
# # ~*~ coding: utf-8 ~*~ # # ~*~ coding: utf-8 ~*~
# # # #
# #
# import os import os
# import logging import logging
# from logging import StreamHandler from logging import StreamHandler
# from logging.handlers import TimedRotatingFileHandler from logging.handlers import TimedRotatingFileHandler
#
# from .conf import config from .conf import config
# PROJECT_DIR = os.path.dirname(os.path.dirname(os.path.dirname(__file__))) from .app import app
# PROJECT_DIR = os.path.dirname(os.path.dirname(os.path.dirname(__file__)))
#
# LOG_LEVELS = {
# 'DEBUG': logging.DEBUG, LOG_LEVELS = {
# 'INFO': logging.INFO, 'DEBUG': logging.DEBUG,
# 'WARN': logging.WARNING, 'INFO': logging.INFO,
# 'WARNING': logging.WARNING, 'WARN': logging.WARNING,
# 'ERROR': logging.ERROR, 'WARNING': logging.WARNING,
# 'FATAL': logging.FATAL, 'ERROR': logging.ERROR,
# 'CRITICAL': logging.CRITICAL, 'FATAL': logging.FATAL,
# } 'CRITICAL': logging.CRITICAL,
# }
#
# def create_logger():
# level = config.get('LOG_LEVEL', None) def create_logger():
# level = LOG_LEVELS.get(level, logging.INFO) level = config.get('LOG_LEVEL', None)
# log_dir = config.get('LOG_DIR', os.path.join(PROJECT_DIR, 'logs')) level = LOG_LEVELS.get(level, logging.INFO)
# log_path = os.path.join(log_dir, 'luna.log') log_dir = config.get('LOG_DIR', os.path.join(PROJECT_DIR, 'logs'))
# logger_root = logging.getLogger() log_path = os.path.join(log_dir, 'luna.log')
# logger = logging.getLogger(config.get('NAME', 'luna')) logger_root = logging.getLogger()
# logger = logging.getLogger(config.get('NAME', 'luna'))
# main_formatter = logging.Formatter(
# fmt='%(asctime)s [%(module)s %(levelname)s] %(message)s', main_formatter = logging.Formatter(
# datefmt='%Y-%m-%d %H:%M:%S') fmt='%(asctime)s [%(module)s %(levelname)s] %(message)s',
# console_handler = StreamHandler() datefmt='%Y-%m-%d %H:%M:%S')
# file_handler = TimedRotatingFileHandler( console_handler = StreamHandler()
# filename=log_path, when='D', backupCount=10) file_handler = TimedRotatingFileHandler(
# filename=log_path, when='D', backupCount=10)
# for handler in [console_handler, file_handler]:
# handler.setFormatter(main_formatter) for handler in [console_handler, file_handler]:
# logger.addHandler(handler) handler.setFormatter(main_formatter)
# logger_root.addHandler(console_handler) logger.addHandler(handler)
# logger_root.setLevel(logging.WARNING) logger_root.addHandler(console_handler)
# logger.setLevel(level) logger_root.setLevel(logging.WARNING)
# logger.setLevel(level)
#
# def get_logger(name): # def get_logger(name):
# return logging.getLogger('luna.%s' % name) # return logging.getLogger('luna.%s' % name)
# #
......
...@@ -34,7 +34,7 @@ class ProxyServer(object): ...@@ -34,7 +34,7 @@ class ProxyServer(object):
IGNORE_OUTPUT_COMMAND = [re.compile(r'^cat\s+'), IGNORE_OUTPUT_COMMAND = [re.compile(r'^cat\s+'),
re.compile(r'^tailf?\s+')] re.compile(r'^tailf?\s+')]
def __init__(self, app, user, asset, system_user, client_channel): def __init__(self, app, user, asset, system_user, client_channel, stop_event):
self.app = app self.app = app
self.user = user self.user = user
self.asset = asset self.asset = asset
...@@ -42,6 +42,7 @@ class ProxyServer(object): ...@@ -42,6 +42,7 @@ class ProxyServer(object):
self.service = app.service self.service = app.service
self.client_channel = client_channel self.client_channel = client_channel
self.change_win_size_event = threading.Event() self.change_win_size_event = threading.Event()
self.stop_event = stop_event
self.input = '' self.input = ''
self.output = '' self.output = ''
...@@ -66,7 +67,7 @@ class ProxyServer(object): ...@@ -66,7 +67,7 @@ class ProxyServer(object):
def get_output(self): def get_output(self):
width = self.client_channel.win_width width = self.client_channel.win_width
height = self.client_channel.win_heigth height = self.client_channel.win_height
parser = TtyIOParser(width=width, height=height) parser = TtyIOParser(width=width, height=height)
self.output = parser.parse_output(b''.join(self.output_data)) self.output = parser.parse_output(b''.join(self.output_data))
if self.input: if self.input:
...@@ -85,7 +86,7 @@ class ProxyServer(object): ...@@ -85,7 +86,7 @@ class ProxyServer(object):
def get_input(self): def get_input(self):
width = self.client_channel.win_width width = self.client_channel.win_width
height = self.client_channel.win_heigth height = self.client_channel.win_height
parser = TtyIOParser(width=width, height=height) parser = TtyIOParser(width=width, height=height)
self.input = parser.parse_input(b''.join(self.input_data)) self.input = parser.parse_input(b''.join(self.input_data))
...@@ -103,6 +104,12 @@ class ProxyServer(object): ...@@ -103,6 +104,12 @@ class ProxyServer(object):
asset = self.asset asset = self.asset
system_user = self.system_user system_user = self.system_user
client_channel = self.client_channel client_channel = self.client_channel
try:
width = int(client_channel.win_width)
height = int(client_channel.win_height)
print('term %s*%s' % (width, height))
except TypeError:
pass
if not self.validate_user_asset_permission(): if not self.validate_user_asset_permission():
logger.warning('User %s have no permission connect %s with %s' % logger.warning('User %s have no permission connect %s with %s' %
(user.username, asset.ip, system_user.username)) (user.username, asset.ip, system_user.username))
...@@ -115,6 +122,7 @@ class ProxyServer(object): ...@@ -115,6 +122,7 @@ class ProxyServer(object):
"system_user": system_user.username, "login_type": "WT", "system_user": system_user.username, "login_type": "WT",
"date_start": time.time(), "is_failed": 0} "date_start": time.time(), "is_failed": 0}
self.proxy_log_id = proxy_log_id = self.service.send_proxy_log(data) self.proxy_log_id = proxy_log_id = self.service.send_proxy_log(data)
self.app.proxy_list[proxy_log_id] = self.client_channel, self.backend_channel
try: try:
client_channel.send( client_channel.send(
wr('Connecting %s@%s:%s ... ' % wr('Connecting %s@%s:%s ... ' %
...@@ -171,42 +179,32 @@ class ProxyServer(object): ...@@ -171,42 +179,32 @@ class ProxyServer(object):
self.app.proxy_list[self.proxy_log_id] = \ self.app.proxy_list[self.proxy_log_id] = \
[self.client_channel, backend_channel] [self.client_channel, backend_channel]
#while True:
# r, w, x = select.select([client_channel], [], [])
# if client_channel in r:
# data = client_channel.recv(100)
# if len(data) == 0:
# break
# print('Receive from client: %s' % data)
#return
if backend_channel is None: if backend_channel is None:
return return
while True: while not self.stop_event.set():
r, w, x = select.select([client_channel, backend_channel], [], []) r, w, x = select.select([client_channel, backend_channel], [], [])
#if self.change_win_size_event.is_set(): #if self.change_win_size_event.is_set():
# self.change_win_size_event.clear() # self.change_win_size_event.clear()
# width = self.client_channel.win_width # width = self.client_channel.win_width
# height = self.client_channel.win_heigth # height = self.client_channel.win_height
# backend_channel.resize_pty(width=width, height=height) # backend_channel.resize_pty(width=width, height=height)
if client_channel in r: if client_channel in r:
# Get output of the command # Get output of the command
print('Recive from client') self.is_first_input = False
# self.is_first_input = False if self.in_input_state is False:
# if self.in_input_state is False: self.get_output()
# self.get_output() del self.output_data[:]
# del self.output_data[:]
# self.in_input_state = True self.in_input_state = True
client_data = client_channel.recv(1024) client_data = client_channel.recv(1024)
# if self.is_finish_input(client_data): if self.is_finish_input(client_data):
# self.in_input_state = False self.in_input_state = False
# self.get_input() self.get_input()
# del self.input_data[:] del self.input_data[:]
if len(client_data) == 0: if len(client_data) == 0:
break break
...@@ -214,25 +212,26 @@ class ProxyServer(object): ...@@ -214,25 +212,26 @@ class ProxyServer(object):
if backend_channel in r: if backend_channel in r:
backend_data = backend_channel.recv(1024) backend_data = backend_channel.recv(1024)
# if self.in_input_state: if self.in_input_state:
# self.input_data.append(backend_data) self.input_data.append(backend_data)
# else: else:
# self.output_data.append(backend_data) self.output_data.append(backend_data)
if len(backend_data) == 0: if len(backend_data) == 0:
# client_channel.send( client_channel.send(
# wr('Disconnect from %s' % self.asset.ip)) wr('Disconnect from %s' % self.asset.ip))
# logger.info('Logout from asset %(host)s: %(username)s' % { logger.info('Logout from asset %(host)s: %(username)s' % {
# 'host': self.asset.ip, 'host': self.asset.ip,
# 'username': self.user.username, 'username': self.user.username,
# }) })
break break
client_channel.send(backend_data) client_channel.send(backend_data)
if self.is_match_ignore_command(self.input): # Todo: record log send
output = 'ignore output ...' # if self.is_match_ignore_command(self.input):
else: # output = 'ignore output ...'
output = backend_data # else:
# output = backend_data
# record_data = { # record_data = {
# 'proxy_log_id': self.proxy_log_id, # 'proxy_log_id': self.proxy_log_id,
# 'output': output, # 'output': output,
...@@ -245,4 +244,5 @@ class ProxyServer(object): ...@@ -245,4 +244,5 @@ class ProxyServer(object):
"date_finished": time.time(), "date_finished": time.time(),
} }
self.service.finish_proxy_log(data) self.service.finish_proxy_log(data)
del self.app.proxy_list[self.proxy_log_id]
...@@ -41,20 +41,20 @@ def handle_machine(message): ...@@ -41,20 +41,20 @@ def handle_machine(message):
clients[sid]['port'] = port = 8022 clients[sid]['port'] = port = 8022
user = to_dotmap({'username': 'root', 'name': 'redhat'}) user = to_dotmap({'username': 'root', 'name': 'redhat'})
asset = to_dotmap({'hostname': host, 'ip': host, 'port': 8022}) asset = to_dotmap({'hostname': host, 'ip': host, 'port': 8022})
# win_width = request.cookies.get('col') win_width = request.cookies.get('cols')
# win_height = request.cookies.get('row') win_height = request.cookies.get('rows')
system_user = to_dotmap({'name': 'jms', 'username': 'jms', 'id': 102}) system_user = to_dotmap({'name': 'jms', 'username': 'jms', 'id': 102})
clients[sid]['proxy_chan'] = proxy_chan = ProxyChannel(sid) clients[sid]['proxy_chan'] = proxy_chan = ProxyChannel(sid)
# proxy_chan.set_win_size((win_width, win_height)) proxy_chan.set_win_size((win_width, win_height))
proxy_server = ProxyServer(app, user, asset, system_user, proxy_chan) stop_event = threading.Event()
clients[sid]['stop_event'] = stop_event
proxy_server = ProxyServer(app, user, asset, system_user,
proxy_chan, stop_event)
socket_io.start_background_task(proxy_server.proxy) socket_io.start_background_task(proxy_server.proxy)
# t = threading.Thread(target=proxy_server.proxy, args=())
# t.daemon = True
# t.start()
@socket_io.on('data') @socket_io.on('data')
def handle_data( message): def handle_data(message):
sid = request.sid sid = request.sid
logger.debug('Receive data: %s' % message) logger.debug('Receive data: %s' % message)
if clients[sid]['proxy_chan']: if clients[sid]['proxy_chan']:
......
...@@ -5,6 +5,7 @@ import sys ...@@ -5,6 +5,7 @@ import sys
import os import os
from luna import app, socket_io from luna import app, socket_io
from luna.tasks import command_task, record_task
host = app.config['BIND_HOST'] host = app.config['BIND_HOST']
port = app.config['LISTEN_PORT'] port = app.config['LISTEN_PORT']
...@@ -18,6 +19,9 @@ if __name__ == '__main__': ...@@ -18,6 +19,9 @@ if __name__ == '__main__':
pass pass
try: try:
command_task.run()
record_task.run()
app.bootstrap()
socket_io.run(app) socket_io.run(app)
# app.run(threaded=True, host=host, port=port) # app.run(threaded=True, host=host, port=port)
except KeyboardInterrupt: except KeyboardInterrupt:
......
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