Intial commit
This commit is contained in:
parent
e3d27a1ba7
commit
d5282f1c99
|
@ -1,131 +1,5 @@
|
||||||
# ---> Python
|
public/
|
||||||
# Byte-compiled / optimized / DLL files
|
users.json
|
||||||
__pycache__/
|
.vscode/
|
||||||
*.py[cod]
|
frontend/node_modules/
|
||||||
*$py.class
|
frontend/.cache/
|
||||||
|
|
||||||
# C extensions
|
|
||||||
*.so
|
|
||||||
|
|
||||||
# Distribution / packaging
|
|
||||||
.Python
|
|
||||||
build/
|
|
||||||
develop-eggs/
|
|
||||||
dist/
|
|
||||||
downloads/
|
|
||||||
eggs/
|
|
||||||
.eggs/
|
|
||||||
lib/
|
|
||||||
lib64/
|
|
||||||
parts/
|
|
||||||
sdist/
|
|
||||||
var/
|
|
||||||
wheels/
|
|
||||||
pip-wheel-metadata/
|
|
||||||
share/python-wheels/
|
|
||||||
*.egg-info/
|
|
||||||
.installed.cfg
|
|
||||||
*.egg
|
|
||||||
MANIFEST
|
|
||||||
|
|
||||||
# PyInstaller
|
|
||||||
# Usually these files are written by a python script from a template
|
|
||||||
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
|
||||||
*.manifest
|
|
||||||
*.spec
|
|
||||||
|
|
||||||
# Installer logs
|
|
||||||
pip-log.txt
|
|
||||||
pip-delete-this-directory.txt
|
|
||||||
|
|
||||||
# Unit test / coverage reports
|
|
||||||
htmlcov/
|
|
||||||
.tox/
|
|
||||||
.nox/
|
|
||||||
.coverage
|
|
||||||
.coverage.*
|
|
||||||
.cache
|
|
||||||
nosetests.xml
|
|
||||||
coverage.xml
|
|
||||||
*.cover
|
|
||||||
*.py,cover
|
|
||||||
.hypothesis/
|
|
||||||
.pytest_cache/
|
|
||||||
|
|
||||||
# Translations
|
|
||||||
*.mo
|
|
||||||
*.pot
|
|
||||||
|
|
||||||
# Django stuff:
|
|
||||||
*.log
|
|
||||||
local_settings.py
|
|
||||||
db.sqlite3
|
|
||||||
db.sqlite3-journal
|
|
||||||
|
|
||||||
# Flask stuff:
|
|
||||||
instance/
|
|
||||||
.webassets-cache
|
|
||||||
|
|
||||||
# Scrapy stuff:
|
|
||||||
.scrapy
|
|
||||||
|
|
||||||
# Sphinx documentation
|
|
||||||
docs/_build/
|
|
||||||
|
|
||||||
# PyBuilder
|
|
||||||
target/
|
|
||||||
|
|
||||||
# Jupyter Notebook
|
|
||||||
.ipynb_checkpoints
|
|
||||||
|
|
||||||
# IPython
|
|
||||||
profile_default/
|
|
||||||
ipython_config.py
|
|
||||||
|
|
||||||
# pyenv
|
|
||||||
.python-version
|
|
||||||
|
|
||||||
# pipenv
|
|
||||||
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
|
||||||
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
|
||||||
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
|
||||||
# install all needed dependencies.
|
|
||||||
#Pipfile.lock
|
|
||||||
|
|
||||||
# PEP 582; used by e.g. github.com/David-OConnor/pyflow
|
|
||||||
__pypackages__/
|
|
||||||
|
|
||||||
# Celery stuff
|
|
||||||
celerybeat-schedule
|
|
||||||
celerybeat.pid
|
|
||||||
|
|
||||||
# SageMath parsed files
|
|
||||||
*.sage.py
|
|
||||||
|
|
||||||
# Environments
|
|
||||||
.env
|
|
||||||
.venv
|
|
||||||
env/
|
|
||||||
venv/
|
|
||||||
ENV/
|
|
||||||
env.bak/
|
|
||||||
venv.bak/
|
|
||||||
|
|
||||||
# Spyder project settings
|
|
||||||
.spyderproject
|
|
||||||
.spyproject
|
|
||||||
|
|
||||||
# Rope project settings
|
|
||||||
.ropeproject
|
|
||||||
|
|
||||||
# mkdocs documentation
|
|
||||||
/site
|
|
||||||
|
|
||||||
# mypy
|
|
||||||
.mypy_cache/
|
|
||||||
.dmypy.json
|
|
||||||
dmypy.json
|
|
||||||
|
|
||||||
# Pyre type checker
|
|
||||||
.pyre/
|
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
FROM python:3
|
||||||
|
|
||||||
|
RUN apt update && apt install -y python3-pip &&\
|
||||||
|
/usr/bin/python3 -m pip install aiohttp aiodocker docker
|
||||||
|
|
||||||
|
RUN mkdir /app
|
||||||
|
|
||||||
|
COPY ./public /app/public
|
||||||
|
COPY ./src /app/src
|
||||||
|
|
||||||
|
EXPOSE 8080
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
ENTRYPOINT [ "/usr/bin/python3", "/app/src/main.py" ]
|
|
@ -0,0 +1,37 @@
|
||||||
|
version: '3.7'
|
||||||
|
|
||||||
|
services:
|
||||||
|
console:
|
||||||
|
container_name: console
|
||||||
|
image: magmise/console
|
||||||
|
volumes:
|
||||||
|
- /var/run/docker.sock:/var/run/docker.sock
|
||||||
|
- ./users.json:/app/config/users.json
|
||||||
|
restart: unless-stopped
|
||||||
|
networks:
|
||||||
|
- caddy
|
||||||
|
labels:
|
||||||
|
caddy: console
|
||||||
|
caddy.reverse_proxy: "{{upstreams 8080}}"
|
||||||
|
#caddy.tls: "admin@chch.tech"
|
||||||
|
caddy.tls: "internal"
|
||||||
|
|
||||||
|
|
||||||
|
caddy:
|
||||||
|
image: lucaslorentz/caddy-docker-proxy:ci-alpine
|
||||||
|
ports:
|
||||||
|
- 80:80
|
||||||
|
- 443:443
|
||||||
|
labels: # Global options
|
||||||
|
caddy.email: caddy@jimmy.nz
|
||||||
|
volumes:
|
||||||
|
- /var/run/docker.sock:/var/run/docker.sock
|
||||||
|
networks:
|
||||||
|
- caddy
|
||||||
|
restart: unless-stopped
|
||||||
|
networks:
|
||||||
|
- caddy
|
||||||
|
|
||||||
|
networks:
|
||||||
|
caddy:
|
||||||
|
name: caddy
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,26 @@
|
||||||
|
{
|
||||||
|
"name": "client",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"dependencies": {
|
||||||
|
"console.js": "^2.0.1",
|
||||||
|
"parcel": "^1.12.4",
|
||||||
|
"xterm": "^4.9.0",
|
||||||
|
"xterm-addon-attach": "^0.6.0",
|
||||||
|
"xterm-addon-fit": "^0.4.0",
|
||||||
|
"xterm-addon-search": "^0.7.0"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"parcel-bundler": "latest"
|
||||||
|
},
|
||||||
|
"scripts": {
|
||||||
|
"build": "parcel build src/index.html --out-dir ../public",
|
||||||
|
"watch": "parcel watch src/index.html --out-dir ../public"
|
||||||
|
},
|
||||||
|
"browserslist": [
|
||||||
|
"last 3 and_chr versions",
|
||||||
|
"last 3 chrome versions",
|
||||||
|
"last 3 opera versions",
|
||||||
|
"last 3 ios_saf versions",
|
||||||
|
"last 3 safari versions"
|
||||||
|
]
|
||||||
|
}
|
|
@ -0,0 +1,30 @@
|
||||||
|
import { Terminal } from 'xterm';
|
||||||
|
import { AttachAddon } from 'xterm-addon-attach';
|
||||||
|
import { FitAddon } from 'xterm-addon-fit';
|
||||||
|
|
||||||
|
window.customElements.define('console-component', class extends HTMLElement {
|
||||||
|
constructor(host, server, token) {
|
||||||
|
super();
|
||||||
|
this.shadow = this.attachShadow({mode: 'open'});
|
||||||
|
this.render();
|
||||||
|
this.term = new Terminal();
|
||||||
|
const fitAddon = new FitAddon();
|
||||||
|
this.term.loadAddon(fitAddon);
|
||||||
|
fitAddon.fit();
|
||||||
|
term.open(document.getElementById('terminal'));
|
||||||
|
this.connect();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
connect() {
|
||||||
|
this.socket = new WebSocket(`wss://${host}/server/${server}/logs?token=${token}`);
|
||||||
|
const attachAddon = new AttachAddon(socket);
|
||||||
|
term.loadAddon(attachAddon);
|
||||||
|
}
|
||||||
|
render() {
|
||||||
|
this.shadow.innerHTML = `
|
||||||
|
<div id="terminal"></div>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
|
@ -0,0 +1,26 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>Document</title>
|
||||||
|
<link rel="stylesheet" href="../node_modules/xterm/css/xterm.css" />
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<select id="serverselect"></select>
|
||||||
|
<button id="start">Start</button>
|
||||||
|
<button id="stop">Stop</button>
|
||||||
|
<label id="server"></label>
|
||||||
|
<div id="terminal"></div>
|
||||||
|
|
||||||
|
<form id="send">
|
||||||
|
<input type="submit" value="Send">
|
||||||
|
<input type="text" name="send" value="">
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<console-component></console-component>
|
||||||
|
|
||||||
|
<script src="main.js"></script>
|
||||||
|
<script src="console.js"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -0,0 +1,156 @@
|
||||||
|
import { Terminal } from 'xterm';
|
||||||
|
import { AttachAddon } from 'xterm-addon-attach';
|
||||||
|
import { FitAddon } from 'xterm-addon-fit';
|
||||||
|
import { SearchAddon } from 'xterm-addon-search';
|
||||||
|
import 'console.js';
|
||||||
|
|
||||||
|
function main() {
|
||||||
|
const urlParams = new URLSearchParams(window.location.search);
|
||||||
|
const token = urlParams.get('token');
|
||||||
|
if(token==null) {
|
||||||
|
alert("You need a token to use this.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const host = `${window.location.hostname}`;
|
||||||
|
var server = window.location.hash.replace('#', '');
|
||||||
|
var serverselect = document.getElementById('serverselect')
|
||||||
|
var serverlabel = document.getElementById('server');
|
||||||
|
var socket;
|
||||||
|
var term = new Terminal();
|
||||||
|
const fitAddon = new FitAddon();
|
||||||
|
const searchAddon = new SearchAddon();
|
||||||
|
|
||||||
|
term.loadAddon(fitAddon);
|
||||||
|
term.loadAddon(searchAddon);
|
||||||
|
fitAddon.fit();
|
||||||
|
serverlabel.innerText = server;
|
||||||
|
getServers(token, host).then(servers => {
|
||||||
|
if(servers==null) {
|
||||||
|
alert("Invalid token");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
servers.forEach(element => {
|
||||||
|
let opt = document.createElement('option');
|
||||||
|
opt.text = element;
|
||||||
|
serverselect.add(opt);
|
||||||
|
});
|
||||||
|
if(server == "") {
|
||||||
|
server = serverselect.options[0].value;
|
||||||
|
window.location.hash = serverselect.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
serverselect.value = server;
|
||||||
|
|
||||||
|
console.log(server, servers, servers.includes(server));
|
||||||
|
if(servers.includes(server)) {
|
||||||
|
term.open(document.getElementById('terminal'));
|
||||||
|
try {
|
||||||
|
socket = new WebSocket(`wss://${host}/server/${server}/logs?token=${token}`);
|
||||||
|
const attachAddon = new AttachAddon(socket);
|
||||||
|
term.loadAddon(attachAddon);
|
||||||
|
} catch(err) {
|
||||||
|
alert("You are not allowed to use this server");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
serverselect.addEventListener("click", (event) => {
|
||||||
|
console.log(serverselect.value);
|
||||||
|
window.location.hash = serverselect.value;
|
||||||
|
socket.close();
|
||||||
|
location.reload();
|
||||||
|
})
|
||||||
|
|
||||||
|
window.onbeforeunload = function() {
|
||||||
|
socket.close();
|
||||||
|
console.log("Closing");
|
||||||
|
alert("Closing");
|
||||||
|
}
|
||||||
|
|
||||||
|
const start = document.getElementById('start');
|
||||||
|
const stop = document.getElementById('stop');
|
||||||
|
const send = document.getElementById('send');
|
||||||
|
|
||||||
|
start.addEventListener('click', async _ => {
|
||||||
|
try {
|
||||||
|
const response = await fetch(`https://${host}/server/${server}/start?token=${token}`, {
|
||||||
|
method: 'post',
|
||||||
|
body: {
|
||||||
|
// Your body
|
||||||
|
}
|
||||||
|
});
|
||||||
|
console.log('Completed!', response);
|
||||||
|
if(await response.status==401) {
|
||||||
|
alert("You are not allowed to start this server");
|
||||||
|
return
|
||||||
|
}
|
||||||
|
socket.close();
|
||||||
|
location.reload();
|
||||||
|
} catch(err) {
|
||||||
|
console.error(`Error: ${err}`);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
stop.addEventListener('click', async _ => {
|
||||||
|
try {
|
||||||
|
const response = await fetch(`https://${host}/server/${server}/stop?token=${token}`, {
|
||||||
|
method: 'post',
|
||||||
|
body: {
|
||||||
|
// Your body
|
||||||
|
}
|
||||||
|
});
|
||||||
|
console.log('Completed!', response);
|
||||||
|
if(await response.status==401) {
|
||||||
|
alert("You are not allowed to stop this server");
|
||||||
|
return
|
||||||
|
}
|
||||||
|
} catch(err) {
|
||||||
|
console.error(`Error: ${err}`);
|
||||||
|
}
|
||||||
|
socket.close();
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
send.onsubmit = async (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
let formdata = new FormData(send);
|
||||||
|
let command = btoa(formdata.get('send'));
|
||||||
|
console.log(command);
|
||||||
|
//let command = btoa('say hello')
|
||||||
|
try {
|
||||||
|
let response = await fetch(`https://${host}/server/${server}/command/${command}?token=${token}`, {
|
||||||
|
method: 'POST'
|
||||||
|
});
|
||||||
|
if(await response.status==401) {
|
||||||
|
alert("You are not allowed to send commands to this server");
|
||||||
|
return
|
||||||
|
}
|
||||||
|
} catch(err) {
|
||||||
|
console.error(`Error: ${err}`);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
async function getServers(token, host) {
|
||||||
|
try {
|
||||||
|
console.log(`https://${host}/user/servers?token=${token}`);
|
||||||
|
let response = await fetch(`https://${host}/user/servers?token=${token}`, {
|
||||||
|
method: 'GET'
|
||||||
|
});
|
||||||
|
if(response.ok)
|
||||||
|
return JSON.parse(await response.json());
|
||||||
|
else return null;
|
||||||
|
} catch(err) {
|
||||||
|
console.error(`Error: ${err}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
window.onload = main();
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,34 @@
|
||||||
|
import json
|
||||||
|
from aiohttp import web
|
||||||
|
|
||||||
|
def authenticate(request):
|
||||||
|
if('token' not in request.query):
|
||||||
|
return None
|
||||||
|
token = request.query['token']
|
||||||
|
user = loadUser(token)
|
||||||
|
return user
|
||||||
|
|
||||||
|
def authorise(request):
|
||||||
|
user = authenticate(request)
|
||||||
|
if(user is None):
|
||||||
|
return False
|
||||||
|
server = server = request.match_info['server']
|
||||||
|
return server in user['servers']
|
||||||
|
|
||||||
|
def loadUser(token):
|
||||||
|
with open('/app/config/users.json') as f:
|
||||||
|
data = json.load(f)['users']
|
||||||
|
if(token in data):
|
||||||
|
return data[token]
|
||||||
|
return None
|
||||||
|
|
||||||
|
def getServers(request):
|
||||||
|
user = authenticate(request)
|
||||||
|
if(user is not none):
|
||||||
|
return user['servers']
|
||||||
|
return none
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
app = web.Application()
|
||||||
|
app.add_routes([web.post('/{server}', authorise)])
|
||||||
|
web.run_app(app)
|
|
@ -0,0 +1,22 @@
|
||||||
|
from aiohttp import web
|
||||||
|
import server
|
||||||
|
|
||||||
|
|
||||||
|
def start(request):
|
||||||
|
#await server.start(request.match_info['server'])
|
||||||
|
pass
|
||||||
|
|
||||||
|
def stop(request):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def status(request):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def command(request):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def logs(request):
|
||||||
|
pass
|
||||||
|
|
||||||
|
async def index(request):
|
||||||
|
return web.FileResponse('/app/public/index.html')
|
|
@ -0,0 +1,26 @@
|
||||||
|
from aiohttp import web
|
||||||
|
import server
|
||||||
|
import base64
|
||||||
|
import handlers
|
||||||
|
import user
|
||||||
|
|
||||||
|
# client = docker.from_env()
|
||||||
|
# container = client.containers.get('mc')
|
||||||
|
# for line in container.logs(stream=True):
|
||||||
|
# print(line.decode('utf8'))
|
||||||
|
|
||||||
|
def main():
|
||||||
|
print(base64.urlsafe_b64encode(b"say Hello"))
|
||||||
|
app = web.Application()
|
||||||
|
app.add_routes([web.post('/server/{server}/start', server.start),
|
||||||
|
web.post('/server/{server}/stop', server.stop),
|
||||||
|
web.post('/server/{server}/status', server.status),
|
||||||
|
web.post('/server/{server}/command/{command}', server.command),
|
||||||
|
web.get('/server/{server}/logs', server.logs),
|
||||||
|
web.get('/user/servers', user.servers),
|
||||||
|
web.get('/', handlers.index)])
|
||||||
|
app.router.add_static('/', "/app/public")
|
||||||
|
web.run_app(app)
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
|
@ -0,0 +1,90 @@
|
||||||
|
from aiohttp import web
|
||||||
|
import docker
|
||||||
|
import aiodocker
|
||||||
|
import base64
|
||||||
|
import auth
|
||||||
|
|
||||||
|
client = docker.from_env()
|
||||||
|
docker = aiodocker.Docker()
|
||||||
|
|
||||||
|
async def start(request):
|
||||||
|
if(not auth.authorise(request)):
|
||||||
|
print("Not authorised")
|
||||||
|
return web.Response(status=401)
|
||||||
|
try:
|
||||||
|
container = await getContainer(request)
|
||||||
|
await container.start()
|
||||||
|
status=200
|
||||||
|
except:
|
||||||
|
status = 500
|
||||||
|
return web.Response(status=status)
|
||||||
|
|
||||||
|
async def stop(request):
|
||||||
|
if(not auth.authorise(request)):
|
||||||
|
print("Not authorised")
|
||||||
|
return web.Response(status=401)
|
||||||
|
try:
|
||||||
|
container = await getContainer(request)
|
||||||
|
await container.stop()
|
||||||
|
status=200
|
||||||
|
except:
|
||||||
|
status=500
|
||||||
|
return web.Response(status=status)
|
||||||
|
|
||||||
|
async def status(request):
|
||||||
|
# if(not auth.authorise(request)):
|
||||||
|
# print("Not authorised")
|
||||||
|
# return web.Response(status=401)
|
||||||
|
try:
|
||||||
|
running="error"
|
||||||
|
running = getContainer(request).status
|
||||||
|
s=200
|
||||||
|
except:
|
||||||
|
s=500
|
||||||
|
running = ""
|
||||||
|
finally:
|
||||||
|
return web.Response(status=s, body=running)
|
||||||
|
|
||||||
|
async def command(request):
|
||||||
|
if(not auth.authorise(request)):
|
||||||
|
print("Not authorised")
|
||||||
|
return web.Response(status=401)
|
||||||
|
server = request.match_info['server']
|
||||||
|
try:
|
||||||
|
container = client.containers.get(server)
|
||||||
|
b64cmd = request.match_info['command']
|
||||||
|
print(b64cmd)
|
||||||
|
cmd = base64.urlsafe_b64decode(b64cmd).decode('utf_8')
|
||||||
|
print(cmd)
|
||||||
|
container.exec_run(cmd="/usr/local/bin/cmd " + str(cmd))
|
||||||
|
s= 200
|
||||||
|
running="Success"
|
||||||
|
except:
|
||||||
|
s=500
|
||||||
|
print("Failed Command")
|
||||||
|
finally:
|
||||||
|
|
||||||
|
return web.Response(status=s)
|
||||||
|
|
||||||
|
async def logs(request):
|
||||||
|
if(not auth.authorise(request)):
|
||||||
|
print("Not authorised")
|
||||||
|
return web.Response(status=401)
|
||||||
|
ws = web.WebSocketResponse()
|
||||||
|
await ws.prepare(request)
|
||||||
|
server = request.match_info['server']
|
||||||
|
docker = aiodocker.Docker()
|
||||||
|
container = await docker.containers.get(server)
|
||||||
|
async for line in container.log(stdout=True, follow=True, tail=5000):
|
||||||
|
if ws.closed:
|
||||||
|
break
|
||||||
|
#print(line)
|
||||||
|
await ws.send_str(line)
|
||||||
|
await docker.close()
|
||||||
|
print("Closed")
|
||||||
|
return ws
|
||||||
|
|
||||||
|
async def getContainer(request):
|
||||||
|
server = request.match_info['server']
|
||||||
|
return await docker.containers.get(server)
|
||||||
|
|
|
@ -0,0 +1,57 @@
|
||||||
|
import unittest
|
||||||
|
import docker
|
||||||
|
import aiohttp
|
||||||
|
import asyncio
|
||||||
|
import server
|
||||||
|
import time
|
||||||
|
|
||||||
|
|
||||||
|
class TestServer(unittest.IsolatedAsyncioTestCase):
|
||||||
|
async def testStart(self):
|
||||||
|
self.container.stop()
|
||||||
|
time.sleep(5)
|
||||||
|
async with self.session.post('http://localhost:8080/mc_test/start') as resp:
|
||||||
|
assert(resp.status == 200)
|
||||||
|
|
||||||
|
async def testStop(self):
|
||||||
|
async with self.session.post('http://localhost:8080/mc_test/stop') as resp:
|
||||||
|
assert(resp.status == 200)
|
||||||
|
|
||||||
|
|
||||||
|
async def testStatus(self):
|
||||||
|
async with self.session.post('http://localhost:8080/mc_test/status') as resp:
|
||||||
|
assert(resp.status == 200)
|
||||||
|
|
||||||
|
async def testCommand(self):
|
||||||
|
async with self.session.post('http://localhost:8080/mc_test/command/c2F5IEhlbGxv') as resp:
|
||||||
|
assert(resp.status == 200)
|
||||||
|
|
||||||
|
async def testLogs(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
async def asyncSetUp(self):
|
||||||
|
self.client = docker.from_env()
|
||||||
|
self.container = self.client.containers.run("mc",detach=True, name="mc_test")
|
||||||
|
self.session = aiohttp.ClientSession()
|
||||||
|
#self.req = make_mocked_request('POST', '/{server}/start', match_info={"server": "mc_test"})
|
||||||
|
|
||||||
|
|
||||||
|
async def asyncTearDown(self):
|
||||||
|
|
||||||
|
self.container.stop()
|
||||||
|
self.container.remove(force=True)
|
||||||
|
await self.session.close()
|
||||||
|
self.client.close()
|
||||||
|
|
||||||
|
async def fetch(session, url):
|
||||||
|
async with session.get(url) as response:
|
||||||
|
return await response.text()
|
||||||
|
|
||||||
|
|
||||||
|
async def startServer(command):
|
||||||
|
return await command()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
unittest.main()
|
|
@ -0,0 +1,10 @@
|
||||||
|
from aiohttp import web
|
||||||
|
import auth
|
||||||
|
import json
|
||||||
|
|
||||||
|
async def servers(request):
|
||||||
|
user = auth.authenticate(request)
|
||||||
|
if(user is not None):
|
||||||
|
data = json.dumps(user['servers'])
|
||||||
|
return web.json_response(data=data ,status=200)
|
||||||
|
return web.json_response(status=403)
|
Loading…
Reference in New Issue