Commit 578cbf0b authored by ibuler's avatar ibuler

[Update] 修改luna

parent 2d6bd826
...@@ -4,112 +4,234 @@ from flask import Flask, send_from_directory, render_template, request, jsonify, ...@@ -4,112 +4,234 @@ from flask import Flask, send_from_directory, render_template, request, jsonify,
from flask_socketio import SocketIO, Namespace, emit, join_room, leave_room from flask_socketio import SocketIO, Namespace, emit, join_room, leave_room
import paramiko import paramiko
import uuid import uuid
import eventlet
from threading import Lock
from flask import Flask, request, current_app, redirect from flask import Flask, request, current_app, redirect
app = Flask(__name__, template_folder='dist') app = Flask(__name__, template_folder='dist')
socketio = None
thread = None
thread_lock = Lock()
class SSHws(Namespace): class SSHws(Namespace):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
self.clients = dict() """
:param args:
:param kwargs:
self.connections = {
"request_sid": {
"room_id": {
"id": room_id,
"proxy": None,
"client": None,
"forwarder": None,
"request": None,
"cols": 80,
"rows": 24
},
...
},
...
}
"""
super().__init__(*args, **kwargs) super().__init__(*args, **kwargs)
self.connections = dict()
def ssh_with_password(self, connection): def ssh_with_password(self, ws, room_id):
ssh = paramiko.SSHClient() ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect("127.0.0.1", 22, "liuzheng", "liuzheng") ssh.connect("192.168.244.176", 22, "root", "redhat123")
self.clients[request.sid]["chan"][connection] = ssh.invoke_shell(term='xterm', width, height = self.get_win_size()
width=self.clients[request.sid]["cols"],
height=self.clients[request.sid]["rows"]) chan = ssh.invoke_shell(term='xterm', width=width, height=height)
# self.socketio.start_background_task(self.send_data, self.clients[request.sid]["chan"]) # self.socketio.start_background_task(self.send_data, self.clients[request.sid]["chan"])
# self.chan.settimeout(0.1) # self.chan.settimeout(0.1)
self.socketio.start_background_task(self.sent_data, self, self.clients[request.sid]["chan"][connection], return chan
self.clients[request.sid]["room"],
connection, request.sid)
def sent_data(self, s, chan, room, connection, sid): def proxy(self, ws, chan, room_id):
# eventlet.monkey_patch(thread=True, select=True, socket=True)
while True: while True:
if connection not in s.clients[sid]["chan"].keys(): data = chan.recv(1024)
return socketio.sleep(1)
try: if len(data) == 0:
data = chan.recv(2048).decode('utf-8', 'replace') break
s.emit(event='data', data={"data": data, "room": connection}, room=room) ws.emit(event="data", data={"data": data.decode(), "room": room_id}, room=room_id, namespace='/ssh')
except RuntimeError:
print(room, connection) def new_connection(self):
self.connections[request.sid] = dict()
def send_data(self, s):
# Todo: 这里涉及到并发优化 def new_room(self):
while True: room_id = str(uuid.uuid4())
for sid in self.clients: room = {
if self.clients[sid]["chan"]: "id": room_id,
for room, chan in self.clients[sid]["chan"]: "proxy": None,
try: "client": None,
data = chan.recv(2048).decode('utf-8', 'replace') "forwarder": None,
s.emit(event='data', data={"data": data, "room": room}, room=self.clients[sid]["room"]) "request": self.ssh_with_password(self, room_id),
except RuntimeError: "cols": 80,
print(self.clients) "rows": 24
}
self.connections[request.sid][room_id] = room
return room
@staticmethod
def get_win_size():
cols_request = request.cookies.get('cols')
rows_request = request.cookies.get('rows')
if cols_request and cols_request.isdigit():
cols = int(cols_request)
else:
cols = 80
if rows_request and rows_request.isdigit():
rows = int(rows_request)
else:
rows = 24
return cols, rows
def on_connect(self): def on_connect(self):
self.clients[request.sid] = { print("On connect event trigger")
"cols": int(request.cookies.get('cols', 80)), self.new_connection()
"rows": int(request.cookies.get('rows', 24)), # self.connections[request.sid] = connection
"room": str(uuid.uuid4()), # self.rooms[connection['room']] = {
"chan": dict() # "admin": request.sid,
} # "member": [],
print(request.sid) # "rw": []
join_room(self.clients[request.sid]["room"]) # }
# self.socketio.start_background_task(self.send_data, self) # join_room(connection['room'])
def on_host(self, message):
# 此处获取主机的信息
print("On host event trigger")
asset_id = message.get('uuid', None)
user_id = message.get('userid', None)
secret = message.get('secret', None)
room = self.new_room()
self.emit('room', {'room': room["id"], 'secret': secret})
print("Join room: {}".format(room["id"]))
join_room(room["id"])
if not asset_id or not user_id:
# self.on_connect()
return
global thread
if thread is None:
thread = self.socketio.start_background_task(
self.proxy, self, room["request"], room["id"]
)
def on_data(self, message): def on_data(self, message):
self.clients[request.sid]["chan"][message["room"]].send(message["data"]) """
收到浏览器请求
:param message: {"data": "xxx", "room": "xxx"}
:return:
"""
room_id = message.get('room')
room = self.connections.get(request.sid, {}).get(room_id)
if not room:
return
room["request"].send(message['data'])
def on_host(self, message): def on_token(self, message):
connection = str(uuid.uuid4()) # 此处获取token含有的主机的信息
self.emit('room', {'room': connection, 'secret': message['secret']}) print("On token trigger")
self.ssh_with_password(connection) token = message.get('token', None)
secret = message.get('secret', None)
room = self.new_room()
self.emit('room', {'room': room["id"], 'secret': secret})
if not token or not secret:
print("Token or secret is None")
self.emit('data', {'data': "\nOperation not permitted!",
'room': room["id"]})
self.emit('disconnect')
return None
info = self.app.service.get_token_asset(token)
print(info)
if not info:
print("Token info is None")
self.emit('data', {'data': "\nOperation not permitted!",
'room': room["id"]})
self.emit('disconnect')
return None
user_id = info.get('user', None)
self.current_user = self.app.service.get_user_profile(user_id)
room["request"].user = self.current_user
print(self.current_user)
self.on_host({
'secret': secret,
'uuid': info['asset'],
'userid': info['system_user'],
})
def on_resize(self, message): def on_resize(self, message):
self.clients[request.sid]["cols"] = message.get('cols', 80) cols, rows = message.get('cols', None), message.get('rows', None)
self.clients[request.sid]["rows"] = message.get('rows', 24) print("On resize event trigger: {}*{}".format(cols, rows))
for room in self.clients[request.sid]["chan"]: rooms = self.connections.get(request.sid)
self.clients[request.sid]["chan"][room].resize_pty(width=self.clients[request.sid]["cols"],
height=self.clients[request.sid]["rows"], width_pixels=1,
height_pixels=1)
def on_room(self, sessionid):
if sessionid not in self.clients.keys():
self.emit('error', "no such session", room=self.clients[request.sid]["room"])
else:
self.emit('room', self.clients[sessionid]["room"], room=self.clients[request.sid]["room"])
def on_join(self, room): if not rooms:
self.leave_room(room=self.clients[request.sid]["room"]) return
join_room(room)
def on_token(self, token): room_tmp = list(rooms.values())[0]
self.on_host(token) if (room_tmp["cols"], room_tmp["rows"]) != (cols, rows):
for room in rooms.values():
room["request"].resize_pty(width=cols, height=rows)
# room["request"].change_size_event.set()
# room.update({"cols": cols, "rows": rows})
def on_disconnect(self): # def on_room(self, session_id):
print("disconnect") # print("On room event trigger")
for connection in self.clients[request.sid]["chan"]: # if session_id not in self.connections.keys():
self.clients[request.sid]["chan"][connection].close() # self.emit(
del self.clients[request.sid]["chan"] # 'error', "no such session",
pass # room=self.connections[request.sid]["room"]
# )
# else:
# self.emit(
# 'room', self.connections[session_id]["room"],
# room=self.connections[request.sid]["room"]
# )
#
# def on_join(self, room):
# print("On join room event trigger")
# self.on_leave(self.connections[request.id]["room"])
# self.connections[request.sid]["room"] = room
# self.rooms[room]["member"].append(request.sid)
# join_room(room=room)
#
# def on_leave(self, room):
# print("On leave room event trigger")
# if self.rooms[room]["admin"] == request.sid:
# self.emit("data", "\nAdmin leave", room=room)
# del self.rooms[room]
# leave_room(room=room)
def on_leave(self): def on_disconnect(self):
leave_room(self.room) print("On disconnect event trigger")
# self.on_leave(self.clients[request.sid]["room"])
for room in self.connections.get(request.sid, {}):
self.on_logout(room["id"])
del self.connections[request.sid]
def on_logout(self, connection): def on_logout(self, room_id):
print("logout", connection) print("On logout event trigger")
if connection: room = self.connections.get(request.sid, {}).get(room_id)
self.clients[request.sid]["chan"][connection].close() if room:
del self.clients[request.sid]["chan"][connection] room["proxy"].close()
del self.connections[request.sid][room_id]
del room
@app.route('/luna/<path:path>') @app.route('/luna/<path:path>')
def send_js(path): def send_js(path):
return send_from_directory('dist', path) return send_from_directory('dist', path)
@app.route('/api/perms/v1/user/nodes-assets/') @app.route('/api/perms/v1/user/nodes-assets/')
def asset_groups_assets(): def asset_groups_assets():
assets = [ assets = [
...@@ -173,14 +295,6 @@ def asset_groups_assets(): ...@@ -173,14 +295,6 @@ def asset_groups_assets():
"priority": 10, "priority": 10,
"protocol": "ssh", "protocol": "ssh",
"comment": "" "comment": ""
},
{
"id": "17f384f4-683d-4944-a38d-db73608b92a9",
"name": "zbh-test",
"username": "zbh",
"priority": 10,
"protocol": "ssh",
"comment": ""
} }
], ],
"is_active": True, "is_active": True,
...@@ -217,7 +331,7 @@ def asset_groups_assets(): ...@@ -217,7 +331,7 @@ def asset_groups_assets():
"comment": "" "comment": ""
}, },
{ {
"id": "ad594b10-9f64-4913-b7b1-135fe63561d1", "id": "9fcd7a09-a171-4cb7-b2f9-a025754f8635",
"hostname": "ali-windows", "hostname": "ali-windows",
"ip": "47.104.206.228", "ip": "47.104.206.228",
"port": 3389, "port": 3389,
...@@ -269,14 +383,6 @@ def asset_groups_assets(): ...@@ -269,14 +383,6 @@ def asset_groups_assets():
"priority": 10, "priority": 10,
"protocol": "ssh", "protocol": "ssh",
"comment": "" "comment": ""
},
{
"id": "17f384f4-683d-4944-a38d-db73608b92a9",
"name": "zbh-test",
"username": "zbh",
"priority": 10,
"protocol": "ssh",
"comment": ""
} }
], ],
"is_active": True, "is_active": True,
...@@ -318,14 +424,6 @@ def asset_groups_assets(): ...@@ -318,14 +424,6 @@ def asset_groups_assets():
"protocol": "ssh", "protocol": "ssh",
"comment": "" "comment": ""
}, },
{
"id": "17f384f4-683d-4944-a38d-db73608b92a9",
"name": "zbh-test",
"username": "zbh",
"priority": 10,
"protocol": "ssh",
"comment": ""
}
], ],
"is_active": True, "is_active": True,
"system_users_join": "root, zbh", "system_users_join": "root, zbh",
...@@ -463,14 +561,6 @@ def asset_groups_assets(): ...@@ -463,14 +561,6 @@ def asset_groups_assets():
"priority": 10, "priority": 10,
"protocol": "ssh", "protocol": "ssh",
"comment": "" "comment": ""
},
{
"id": "17f384f4-683d-4944-a38d-db73608b92a9",
"name": "zbh-test",
"username": "zbh",
"priority": 10,
"protocol": "ssh",
"comment": ""
} }
], ],
"is_active": True, "is_active": True,
...@@ -789,17 +879,32 @@ def replay(): ...@@ -789,17 +879,32 @@ def replay():
return redirect("http://jps.ilz.me/media/2017-12-24/ec87a486-0344-4f12-b27a-620321944f7f.gz") return redirect("http://jps.ilz.me/media/2017-12-24/ec87a486-0344-4f12-b27a-620321944f7f.gz")
@app.route('/api/terminal/v2/sessions/<pk>/replay/')
def get_session_replay(pk):
# return jsonify({
# 'type': 'guacamole',
# 'src': 'http://localhost/media/2018-05-07/5c205f0a-b5ae-405a-9444-c0d59262ec29.gz',
# 'status': 'DONE'
# })
return jsonify({
'type': 'json',
'src': 'http://localhost/media/2018-05-02/dbd5302d-7861-4810-b555-5fe71e26ccc3.gz',
'status': 'DONE',
})
@app.route('/luna/i18n/<i18n>') @app.route('/luna/i18n/<i18n>')
def i18n(i18n): def i18n(i18n):
return send_file('./i18n/' + i18n) return send_file('./i18n/' + i18n)
def read_file(filename, charset='utf-8'): def read_file(filename, charset='utf-8'):
with open(filename, 'r') as f: with open(filename, 'rb') as f:
return f.read().decode(charset) return f.read().decode(charset)
if __name__ == '__main__': if __name__ == '__main__':
socketio = SocketIO(app) async_mode = 'threading'
socketio = SocketIO(app, async_mode=async_mode)
socketio.on_namespace(SSHws('/ssh')) socketio.on_namespace(SSHws('/ssh'))
socketio.run(app) socketio.run(app, debug=True)
...@@ -6,6 +6,6 @@ npm run-script build ...@@ -6,6 +6,6 @@ npm run-script build
rm -fr luna* rm -fr luna*
mv dist luna mv dist luna
cp -R i18n/ luna/ cp -R i18n luna/
tar czf luna.tar.gz luna tar czf luna.tar.gz luna
md5 luna.tar.gz md5 luna.tar.gz
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