mirror of
https://github.com/ComputerScienceHouse/proxstar.git
synced 2025-03-09 15:40:09 +00:00
Dude it works holy shit
We need to fix some logistical bugs, probably, and also like remove dead code lol
This commit is contained in:
parent
586536c708
commit
0b4efa9784
4 changed files with 52 additions and 24 deletions
|
@ -42,6 +42,7 @@ from proxstar.vnc import (
|
||||||
get_vnc_targets,
|
get_vnc_targets,
|
||||||
delete_vnc_target,
|
delete_vnc_target,
|
||||||
stop_websockify,
|
stop_websockify,
|
||||||
|
open_vnc_session,
|
||||||
)
|
)
|
||||||
from proxstar.auth import get_auth
|
from proxstar.auth import get_auth
|
||||||
from proxstar.util import gen_password
|
from proxstar.util import gen_password
|
||||||
|
@ -286,17 +287,12 @@ def vm_console(vmid):
|
||||||
if user.rtp or int(vmid) in user.allowed_vms:
|
if user.rtp or int(vmid) in user.allowed_vms:
|
||||||
# import pdb; pdb.set_trace()
|
# import pdb; pdb.set_trace()
|
||||||
vm = VM(vmid)
|
vm = VM(vmid)
|
||||||
stop_ssh_tunnel(vm.id, ssh_tunnels)
|
vnc_ticket, vnc_port = open_vnc_session(vmid, vm.node, app.config['PROXMOX_USER'], app.config['PROXMOX_PASS'])
|
||||||
port = str(5900 + int(vmid))
|
node = f'proxmox01-nrh.csh.rit.edu'
|
||||||
token = add_vnc_target(port)
|
token = add_vnc_target(node, vnc_port)
|
||||||
node = '{}.csh.rit.edu'.format(vm.node)
|
# return {'host' : node, 'port' : vnc_port, 'token' : token, 'password' : vnc_ticket}, 200
|
||||||
logging.info('creating SSH tunnel to %s for VM %s', node, vm.id)
|
return {'host' : app.config['VNC_HOST'], 'port' : 8081, 'token' : token, 'password' : vnc_ticket}, 200
|
||||||
tunnel = start_ssh_tunnel(node, port)
|
|
||||||
vm.configure_vnc_in_vm_config(app.config['PROXMOX_SSH_USER'], app.config['PROXMOX_SSH_KEY_PASS'])
|
|
||||||
ssh_tunnels.append(tunnel)
|
|
||||||
# vm.start_vnc(port) # Broken :(
|
|
||||||
# return json.dumps([app.config['VNC_HOST'], token]), 200
|
|
||||||
return {'host' : app.config['VNC_HOST'], 'token' : token}, 200
|
|
||||||
else:
|
else:
|
||||||
return '', 403
|
return '', 403
|
||||||
|
|
||||||
|
|
|
@ -654,7 +654,7 @@ $("#console-vm").click(function(){
|
||||||
}).then((vnc_params) => {
|
}).then((vnc_params) => {
|
||||||
// TODO (willnilges): encrypt=true
|
// TODO (willnilges): encrypt=true
|
||||||
// TODO (willnilges): set host and port to an env variable
|
// TODO (willnilges): set host and port to an env variable
|
||||||
window.open(`/static/noVNC/vnc.html?autoconnect=true&password=${vmid}&host=${vnc_params.host}&port=8081&path=path?token=${vnc_params.token}`, '_blank');
|
window.open(`/static/noVNC/vnc.html?autoconnect=true&password=${vnc_params.password}&host=${vnc_params.host}&port=${vnc_params.port}&path=path?token=${vnc_params.token}`, '_blank');
|
||||||
}).catch(err => {
|
}).catch(err => {
|
||||||
if (err) {
|
if (err) {
|
||||||
swal("Uh oh...", `Unable to start console for ${vmname}. Please try again later.`, "error");
|
swal("Uh oh...", `Unable to start console for ${vmname}. Please try again later.`, "error");
|
||||||
|
|
|
@ -274,9 +274,7 @@ class VM:
|
||||||
def configure_vnc_in_vm_config(self, ssh_user, ssh_pass):
|
def configure_vnc_in_vm_config(self, ssh_user, ssh_pass):
|
||||||
""" Sets the vm up for VNC. Enables it to open a socket on localhost
|
""" Sets the vm up for VNC. Enables it to open a socket on localhost
|
||||||
with a pre-determined password, which proxstar can then proxy to a noVNC
|
with a pre-determined password, which proxstar can then proxy to a noVNC
|
||||||
instance.
|
instance.
|
||||||
|
|
||||||
TODO (willnilges): Current password is "chomchom1", but should be changed lol
|
|
||||||
"""
|
"""
|
||||||
# proxmox = connect_proxmox()
|
# proxmox = connect_proxmox()
|
||||||
config = f'args: -object secret,id=secvnc{self.id},data={self.id} -vnc 127.0.0.1:{int(self.id)+5900},password-secret=secvnc{self.id}'
|
config = f'args: -object secret,id=secvnc{self.id},data={self.id} -vnc 127.0.0.1:{int(self.id)+5900},password-secret=secvnc{self.id}'
|
||||||
|
|
|
@ -5,6 +5,7 @@ import time
|
||||||
import requests
|
import requests
|
||||||
from flask import current_app as app
|
from flask import current_app as app
|
||||||
from sshtunnel import SSHTunnelForwarder
|
from sshtunnel import SSHTunnelForwarder
|
||||||
|
import urllib.parse
|
||||||
|
|
||||||
from proxstar import logging
|
from proxstar import logging
|
||||||
from proxstar.util import gen_password
|
from proxstar.util import gen_password
|
||||||
|
@ -31,36 +32,69 @@ def get_vnc_targets():
|
||||||
target_dict = {}
|
target_dict = {}
|
||||||
values = line.strip().split(':')
|
values = line.strip().split(':')
|
||||||
target_dict['token'] = values[0]
|
target_dict['token'] = values[0]
|
||||||
target_dict['port'] = values[2]
|
target_dict['host'] = values[1] + values[2]
|
||||||
targets.append(target_dict)
|
targets.append(target_dict)
|
||||||
target_file.close()
|
target_file.close()
|
||||||
return targets
|
return targets
|
||||||
|
|
||||||
|
def add_vnc_target(node, port):
|
||||||
def add_vnc_target(port):
|
|
||||||
# TODO (willnilges): This doesn't throw an error if the target file is wrong.
|
# TODO (willnilges): This doesn't throw an error if the target file is wrong.
|
||||||
targets = get_vnc_targets()
|
targets = get_vnc_targets()
|
||||||
target = next((target for target in targets if target['port'] == port), None)
|
target = next((target for target in targets if target['host'] == f'{node}:{port}'), None)
|
||||||
if target:
|
if target:
|
||||||
return target['token']
|
return target['token']
|
||||||
else:
|
else:
|
||||||
target_file = open(app.config['WEBSOCKIFY_TARGET_FILE'], 'a')
|
target_file = open(app.config['WEBSOCKIFY_TARGET_FILE'], 'a')
|
||||||
token = gen_password(32, 'abcdefghijklmnopqrstuvwxyz0123456789')
|
token = gen_password(32, 'abcdefghijklmnopqrstuvwxyz0123456789')
|
||||||
target_file.write('{}: 127.0.0.1:{}\n'.format(token, str(port)))
|
target_file.write(f'{token}: {node}:{port}\n')
|
||||||
target_file.close()
|
target_file.close()
|
||||||
return token
|
return token
|
||||||
|
|
||||||
|
def delete_vnc_target(node, port):
|
||||||
def delete_vnc_target(port):
|
|
||||||
targets = get_vnc_targets()
|
targets = get_vnc_targets()
|
||||||
target = next((target for target in targets if target['port'] == str(port)), None)
|
target = next((target for target in targets if target['host'] == f'{node}:{port}'), None)
|
||||||
if target:
|
if target:
|
||||||
targets.remove(target)
|
targets.remove(target)
|
||||||
target_file = open(app.config['WEBSOCKIFY_TARGET_FILE'], 'w')
|
target_file = open(app.config['WEBSOCKIFY_TARGET_FILE'], 'w')
|
||||||
for target in targets:
|
for target in targets:
|
||||||
target_file.write('{}: 127.0.0.1:{}\n'.format(target['token'], target['port']))
|
target_file.write(f"{target['token']}: {target['host']}\n")
|
||||||
target_file.close()
|
target_file.close()
|
||||||
|
|
||||||
|
def open_vnc_session(vmid, node, proxmox_user, proxmox_pass):
|
||||||
|
""" Pings the Proxmox API to request a VNC Proxy connection. Authenticates
|
||||||
|
against the API using a Uname/Pass, gets a few tokens back, then uses those
|
||||||
|
tokens to open the VNC Proxy. Use these to connect to the VM's host with
|
||||||
|
websockify proxy.
|
||||||
|
Returns: Ticket to use as the noVNC password, and a port.
|
||||||
|
"""
|
||||||
|
# Get Proxmox API ticket and CSRF_Prevention_Token
|
||||||
|
# TODO: Use Proxmoxer to get this information?
|
||||||
|
# TODO: Report errors!?
|
||||||
|
data = {"username": proxmox_user, "password": proxmox_pass}
|
||||||
|
response_data = requests.post(
|
||||||
|
f"https://{node}.csh.rit.edu:8006/" + "api2/json/access/ticket",
|
||||||
|
verify=False,
|
||||||
|
data=data,
|
||||||
|
).json()["data"]
|
||||||
|
if response_data is None:
|
||||||
|
raise AuthenticationError(
|
||||||
|
"Could not authenticate against `ticket` endpoint! Check uname/password"
|
||||||
|
)
|
||||||
|
csrf_prevention_token = response_data['CSRFPreventionToken']
|
||||||
|
ticket = response_data['ticket']
|
||||||
|
|
||||||
|
proxy_params = {"node": node, "vmid": str(vmid), "websocket": '1', "generate-password": '0'}
|
||||||
|
|
||||||
|
vncproxy_response_data = requests.post(
|
||||||
|
"https://proxmox01-nrh.csh.rit.edu:8006" + f"/api2/json/nodes/{node}/qemu/{vmid}/vncproxy",
|
||||||
|
verify=False,
|
||||||
|
timeout=5,
|
||||||
|
params=proxy_params,
|
||||||
|
headers={"CSRFPreventionToken": csrf_prevention_token},
|
||||||
|
cookies={"PVEAuthCookie": ticket}
|
||||||
|
).json()["data"]
|
||||||
|
|
||||||
|
return urllib.parse.quote_plus(vncproxy_response_data['ticket']), vncproxy_response_data['port']
|
||||||
|
|
||||||
def start_ssh_tunnel(node, port):
|
def start_ssh_tunnel(node, port):
|
||||||
"""Forwards a port on a node
|
"""Forwards a port on a node
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue