mirror of
https://github.com/ComputerScienceHouse/proxstar.git
synced 2025-03-09 15:40:09 +00:00
Merge pull request #158 from ComputerScienceHouse/willnilges/remove-ssh
Remove SSH functionality from Proxstar
This commit is contained in:
commit
b3d43f8d21
9 changed files with 34 additions and 68 deletions
|
@ -7,5 +7,5 @@ COPY start_worker.sh start_scheduler.sh .
|
||||||
COPY .git ./.git
|
COPY .git ./.git
|
||||||
COPY *.py .
|
COPY *.py .
|
||||||
COPY proxstar ./proxstar
|
COPY proxstar ./proxstar
|
||||||
RUN touch proxmox_ssh_key targets && chmod a+w proxmox_ssh_key targets # This is some OKD shit.
|
RUN touch targets && chmod a+w targets # This is some OKD shit.
|
||||||
ENTRYPOINT ddtrace-run gunicorn proxstar:app --bind=0.0.0.0:8080
|
ENTRYPOINT ddtrace-run gunicorn proxstar:app --bind=0.0.0.0:8080
|
||||||
|
|
|
@ -26,9 +26,6 @@ PROXSTAR_PROXMOX_USER=api@pve
|
||||||
PROXSTAR_PROXMOX_PASS= # Password for proxstar user
|
PROXSTAR_PROXMOX_PASS= # Password for proxstar user
|
||||||
PROXSTAR_PROXMOX_ISO_STORAGE=nfs-iso
|
PROXSTAR_PROXMOX_ISO_STORAGE=nfs-iso
|
||||||
PROXSTAR_PROXMOX_VM_STORAGE=ceph
|
PROXSTAR_PROXMOX_VM_STORAGE=ceph
|
||||||
PROXSTAR_PROXMOX_SSH_USER=root
|
|
||||||
PROXSTAR_PROXMOX_SSH_KEY="" # Ask an RTP. This is gonna look like a certificate.
|
|
||||||
PROXSTAR_PROXMOX_SSH_KEY_PASS= # Password for above certificate
|
|
||||||
|
|
||||||
# STARRS
|
# STARRS
|
||||||
PROXSTAR_STARRS_DB_HOST=proxstar-postgres
|
PROXSTAR_STARRS_DB_HOST=proxstar-postgres
|
||||||
|
|
2
HACKING/build_env.sh
Executable file
2
HACKING/build_env.sh
Executable file
|
@ -0,0 +1,2 @@
|
||||||
|
#!/bin/bash
|
||||||
|
podman build . --tag=proxstar
|
|
@ -37,10 +37,6 @@ PROXMOX_USER = environ.get('PROXSTAR_PROXMOX_USER', '')
|
||||||
PROXMOX_PASS = environ.get('PROXSTAR_PROXMOX_PASS', '')
|
PROXMOX_PASS = environ.get('PROXSTAR_PROXMOX_PASS', '')
|
||||||
PROXMOX_ISO_STORAGE = environ.get('PROXSTAR_PROXMOX_ISO_STORAGE', 'nfs-iso')
|
PROXMOX_ISO_STORAGE = environ.get('PROXSTAR_PROXMOX_ISO_STORAGE', 'nfs-iso')
|
||||||
PROXMOX_VM_STORAGE = environ.get('PROXSTAR_PROXMOX_VM_STORAGE', 'ceph')
|
PROXMOX_VM_STORAGE = environ.get('PROXSTAR_PROXMOX_VM_STORAGE', 'ceph')
|
||||||
PROXMOX_SSH_USER = environ.get('PROXSTAR_PROXMOX_SSH_USER', '')
|
|
||||||
PROXMOX_SSH_KEY = environ.get('PROXSTAR_PROXMOX_SSH_KEY', '')
|
|
||||||
PROXMOX_SSH_KEY_PASS = environ.get('PROXSTAR_PROXMOX_SSH_KEY_PASS', '')
|
|
||||||
|
|
||||||
# STARRS
|
# STARRS
|
||||||
STARRS_DB_HOST = environ.get('PROXSTAR_STARRS_DB_HOST', '')
|
STARRS_DB_HOST = environ.get('PROXSTAR_STARRS_DB_HOST', '')
|
||||||
STARRS_DB_NAME = environ.get('PROXSTAR_DB_NAME', 'starrs')
|
STARRS_DB_NAME = environ.get('PROXSTAR_DB_NAME', 'starrs')
|
||||||
|
|
|
@ -77,12 +77,6 @@ sentry_sdk.init(
|
||||||
environment=app.config['SENTRY_ENV'],
|
environment=app.config['SENTRY_ENV'],
|
||||||
)
|
)
|
||||||
|
|
||||||
if not os.path.exists('proxmox_ssh_key'):
|
|
||||||
with open('proxmox_ssh_key', 'w') as ssh_key_file:
|
|
||||||
ssh_key_file.write(app.config['PROXMOX_SSH_KEY'])
|
|
||||||
|
|
||||||
ssh_tunnels = []
|
|
||||||
|
|
||||||
auth = get_auth(app)
|
auth = get_auth(app)
|
||||||
|
|
||||||
redis_conn = Redis(app.config['REDIS_HOST'], app.config['REDIS_PORT'])
|
redis_conn = Redis(app.config['REDIS_HOST'], app.config['REDIS_PORT'])
|
||||||
|
@ -258,6 +252,9 @@ def vm_power(vmid, action):
|
||||||
connect_proxmox()
|
connect_proxmox()
|
||||||
if user.rtp or int(vmid) in user.allowed_vms:
|
if user.rtp or int(vmid) in user.allowed_vms:
|
||||||
vm = VM(vmid)
|
vm = VM(vmid)
|
||||||
|
vnc_token_key = f'vnc_token|{vmid}'
|
||||||
|
# For deleting the token from redis later
|
||||||
|
vnc_token = redis_conn.get(vnc_token_key).decode('utf-8')
|
||||||
if action == 'start':
|
if action == 'start':
|
||||||
vmconfig = vm.config
|
vmconfig = vm.config
|
||||||
usage_check = user.check_usage(vmconfig['cores'], vmconfig['memory'], 0)
|
usage_check = user.check_usage(vmconfig['cores'], vmconfig['memory'], 0)
|
||||||
|
@ -266,16 +263,18 @@ def vm_power(vmid, action):
|
||||||
vm.start()
|
vm.start()
|
||||||
elif action == 'stop':
|
elif action == 'stop':
|
||||||
vm.stop()
|
vm.stop()
|
||||||
# TODO (willnilges): Replace with remove target function or something
|
delete_vnc_target(token=vnc_token)
|
||||||
# send_stop_ssh_tunnel(vmid)
|
redis_conn.delete(vnc_token_key)
|
||||||
elif action == 'shutdown':
|
elif action == 'shutdown':
|
||||||
vm.shutdown()
|
vm.shutdown()
|
||||||
# send_stop_ssh_tunnel(vmid)
|
delete_vnc_target(token=vnc_token)
|
||||||
|
redis_conn.delete(vnc_token_key)
|
||||||
elif action == 'reset':
|
elif action == 'reset':
|
||||||
vm.reset()
|
vm.reset()
|
||||||
elif action == 'suspend':
|
elif action == 'suspend':
|
||||||
vm.suspend()
|
vm.suspend()
|
||||||
# send_stop_ssh_tunnel(vmid)
|
delete_vnc_target(token=vnc_token)
|
||||||
|
redis_conn.delete(vnc_token_key)
|
||||||
elif action == 'resume':
|
elif action == 'resume':
|
||||||
vm.resume()
|
vm.resume()
|
||||||
return '', 200
|
return '', 200
|
||||||
|
@ -296,6 +295,7 @@ def vm_console(vmid):
|
||||||
)
|
)
|
||||||
node = f'{vm.node}.csh.rit.edu'
|
node = f'{vm.node}.csh.rit.edu'
|
||||||
token = add_vnc_target(node, vnc_port)
|
token = add_vnc_target(node, vnc_port)
|
||||||
|
redis_conn.set(f'vnc_token|{vmid}', str(token)) # Store the VNC token in Redis.
|
||||||
return {
|
return {
|
||||||
'host': app.config['VNC_HOST'],
|
'host': app.config['VNC_HOST'],
|
||||||
'port': app.config['VNC_PORT'],
|
'port': app.config['VNC_PORT'],
|
||||||
|
@ -630,11 +630,6 @@ def health():
|
||||||
|
|
||||||
def exit_handler():
|
def exit_handler():
|
||||||
stop_websockify()
|
stop_websockify()
|
||||||
for tunnel in ssh_tunnels:
|
|
||||||
try:
|
|
||||||
tunnel.stop()
|
|
||||||
except:
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
atexit.register(exit_handler)
|
atexit.register(exit_handler)
|
||||||
|
|
|
@ -23,24 +23,6 @@ def connect_proxmox():
|
||||||
raise
|
raise
|
||||||
|
|
||||||
|
|
||||||
def connect_proxmox_ssh():
|
|
||||||
for host in app.config['PROXMOX_HOSTS']:
|
|
||||||
try:
|
|
||||||
proxmox = ProxmoxAPI(
|
|
||||||
host,
|
|
||||||
user=app.config['PROXMOX_SSH_USER'],
|
|
||||||
private_key_file='proxmox_ssh_key',
|
|
||||||
password=app.config['PROXMOX_SSH_KEY_PASS'],
|
|
||||||
backend='ssh_paramiko',
|
|
||||||
)
|
|
||||||
proxmox.version.get()
|
|
||||||
return proxmox
|
|
||||||
except:
|
|
||||||
if app.config['PROXMOX_HOSTS'].index(host) == (len(app.config['PROXMOX_HOSTS']) - 1):
|
|
||||||
logging.error('unable to connect to any of the given Proxmox servers')
|
|
||||||
raise
|
|
||||||
|
|
||||||
|
|
||||||
def get_node_least_mem(proxmox):
|
def get_node_least_mem(proxmox):
|
||||||
nodes = proxmox.nodes.get()
|
nodes = proxmox.nodes.get()
|
||||||
sorted_nodes = sorted(nodes, key=lambda x: ('mem' not in x, x.get('mem', None)))
|
sorted_nodes = sorted(nodes, key=lambda x: ('mem' not in x, x.get('mem', None)))
|
||||||
|
|
|
@ -6,6 +6,7 @@ import psycopg2
|
||||||
import requests
|
import requests
|
||||||
from flask import Flask
|
from flask import Flask
|
||||||
from rq import get_current_job
|
from rq import get_current_job
|
||||||
|
from redis import Redis
|
||||||
from sqlalchemy import create_engine
|
from sqlalchemy import create_engine
|
||||||
from sqlalchemy.orm import sessionmaker
|
from sqlalchemy.orm import sessionmaker
|
||||||
|
|
||||||
|
@ -22,6 +23,7 @@ from proxstar.proxmox import connect_proxmox, get_pools
|
||||||
from proxstar.starrs import get_next_ip, register_starrs, delete_starrs
|
from proxstar.starrs import get_next_ip, register_starrs, delete_starrs
|
||||||
from proxstar.user import User, get_vms_for_rtp
|
from proxstar.user import User, get_vms_for_rtp
|
||||||
from proxstar.vm import VM, clone_vm, create_vm
|
from proxstar.vm import VM, clone_vm, create_vm
|
||||||
|
from proxstar.vnc import delete_vnc_target
|
||||||
|
|
||||||
logging.basicConfig(format='%(asctime)s %(levelname)s %(message)s', level=logging.INFO)
|
logging.basicConfig(format='%(asctime)s %(levelname)s %(message)s', level=logging.INFO)
|
||||||
|
|
||||||
|
@ -150,7 +152,16 @@ def process_expiring_vms_task():
|
||||||
vm.name, vm.id
|
vm.name, vm.id
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
# send_stop_ssh_tunnel(vm.id) # TODO (willnilges): Remove target from targets file
|
try:
|
||||||
|
redis_conn = Redis(app.config['REDIS_HOST'], app.config['REDIS_PORT'])
|
||||||
|
vmid = vm['vmid']
|
||||||
|
vnc_token_key = f'vnc_token|{vmid}'
|
||||||
|
vnc_token = redis_conn.get(vnc_token_key).decode('utf-8')
|
||||||
|
delete_vnc_target(token=vnc_token)
|
||||||
|
redis_conn.delete(vnc_token_key)
|
||||||
|
except Exception as e: # pylint: disable=W0703
|
||||||
|
print(f'ERROR: Could not delete target from targets file: {e}')
|
||||||
|
|
||||||
delete_vm_task(vm.id)
|
delete_vm_task(vm.id)
|
||||||
if expiring_vms:
|
if expiring_vms:
|
||||||
send_vm_expire_email(pool, expiring_vms)
|
send_vm_expire_email(pool, expiring_vms)
|
||||||
|
|
|
@ -3,10 +3,8 @@ import subprocess
|
||||||
import time
|
import time
|
||||||
import urllib.parse
|
import urllib.parse
|
||||||
|
|
||||||
from deprecated import deprecated
|
|
||||||
import requests
|
import requests
|
||||||
from flask import current_app as app
|
from flask import current_app as app
|
||||||
from sshtunnel import SSHTunnelForwarder
|
|
||||||
|
|
||||||
from proxstar import logging
|
from proxstar import logging
|
||||||
from proxstar.util import gen_password
|
from proxstar.util import gen_password
|
||||||
|
@ -45,7 +43,6 @@ def get_vnc_targets():
|
||||||
|
|
||||||
def add_vnc_target(node, port):
|
def add_vnc_target(node, 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.
|
||||||
# TODO (willnilges): This will duplicate targets
|
|
||||||
targets = get_vnc_targets()
|
targets = get_vnc_targets()
|
||||||
target = next((target for target in targets if target['host'] == f'{node}:{port}'), None)
|
target = next((target for target in targets if target['host'] == f'{node}:{port}'), None)
|
||||||
if target:
|
if target:
|
||||||
|
@ -59,15 +56,22 @@ def add_vnc_target(node, port):
|
||||||
return token
|
return token
|
||||||
|
|
||||||
|
|
||||||
def delete_vnc_target(node, port):
|
def delete_vnc_target(node=None, port=None, token=None):
|
||||||
targets = get_vnc_targets()
|
targets = get_vnc_targets()
|
||||||
target = next((target for target in targets if target['host'] == f'{node}:{port}'), None)
|
if node is not None and port is not None:
|
||||||
|
target = next((target for target in targets if target['host'] == f'{node}:{port}'), None)
|
||||||
|
elif token is not None:
|
||||||
|
target = next((target for target in targets if target['token'] == f'{token}'), None)
|
||||||
|
else:
|
||||||
|
raise ValueError('Need either a node and port, or a token.')
|
||||||
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(f"{target['token']}: {target['host']}\n")
|
target_file.write(f"{target['token']}: {target['host']}\n")
|
||||||
target_file.close()
|
target_file.close()
|
||||||
|
else:
|
||||||
|
raise LookupError('Target does not exist')
|
||||||
|
|
||||||
|
|
||||||
def open_vnc_session(vmid, node, proxmox_user, proxmox_pass):
|
def open_vnc_session(vmid, node, proxmox_user, proxmox_pass):
|
||||||
|
@ -103,22 +107,3 @@ def open_vnc_session(vmid, node, proxmox_user, proxmox_pass):
|
||||||
).json()['data']
|
).json()['data']
|
||||||
|
|
||||||
return urllib.parse.quote_plus(vncproxy_response_data['ticket']), vncproxy_response_data['port']
|
return urllib.parse.quote_plus(vncproxy_response_data['ticket']), vncproxy_response_data['port']
|
||||||
|
|
||||||
|
|
||||||
@deprecated('No longer in use')
|
|
||||||
def start_ssh_tunnel(node, port):
|
|
||||||
"""Forwards a port on a node
|
|
||||||
to the proxstar container
|
|
||||||
"""
|
|
||||||
port = int(port)
|
|
||||||
|
|
||||||
server = SSHTunnelForwarder(
|
|
||||||
node,
|
|
||||||
ssh_username=app.config['PROXMOX_SSH_USER'],
|
|
||||||
ssh_pkey='proxmox_ssh_key',
|
|
||||||
ssh_private_key_password=app.config['PROXMOX_SSH_KEY_PASS'],
|
|
||||||
remote_bind_address=('127.0.0.1', port),
|
|
||||||
local_bind_address=('127.0.0.1', port),
|
|
||||||
)
|
|
||||||
server.start()
|
|
||||||
return server
|
|
||||||
|
|
|
@ -2,7 +2,6 @@ black~=21.9b0
|
||||||
csh-ldap==2.4.0
|
csh-ldap==2.4.0
|
||||||
click~=7.1.2
|
click~=7.1.2
|
||||||
ddtrace~=1.2.1
|
ddtrace~=1.2.1
|
||||||
deprecated==1.2.13
|
|
||||||
flask==1.1.4
|
flask==1.1.4
|
||||||
jinja2==2.11.3
|
jinja2==2.11.3
|
||||||
flask-pyoidc==1.3.0
|
flask-pyoidc==1.3.0
|
||||||
|
@ -19,7 +18,6 @@ rq==1.10.1
|
||||||
rq-dashboard==0.6.1
|
rq-dashboard==0.6.1
|
||||||
rq-scheduler==0.10.0
|
rq-scheduler==0.10.0
|
||||||
sqlalchemy==1.3.22
|
sqlalchemy==1.3.22
|
||||||
sshtunnel==0.2.2
|
|
||||||
tenacity==5.0.2
|
tenacity==5.0.2
|
||||||
websockify==0.9.0
|
websockify==0.9.0
|
||||||
pylint==2.13.9
|
pylint==2.13.9
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue