Commit 555448c4 authored by ibuler's avatar ibuler

[Fixture] 完成日志记录

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