259 lines
6.8 KiB
Python
259 lines
6.8 KiB
Python
from functools import cached_property
|
|
from http.cookies import SimpleCookie
|
|
from http.server import BaseHTTPRequestHandler
|
|
from urllib.parse import parse_qsl, urlparse
|
|
import json
|
|
|
|
from http.server import HTTPServer, BaseHTTPRequestHandler
|
|
|
|
class WebRequestHandler(BaseHTTPRequestHandler):
|
|
def __init__(self, request, client_address, server):
|
|
BaseHTTPRequestHandler.__init__(self, request, client_address, server)
|
|
|
|
@cached_property
|
|
def url(self):
|
|
return urlparse(self.path)
|
|
|
|
@cached_property
|
|
def query_data(self):
|
|
return dict(parse_qsl(self.url.query))
|
|
|
|
@cached_property
|
|
def post_data(self):
|
|
content_length = int(self.headers.get("Content-Length", 0))
|
|
return self.rfile.read(content_length)
|
|
|
|
@cached_property
|
|
def form_data(self):
|
|
return dict(parse_qsl(self.post_data.decode("utf-8")))
|
|
|
|
@cached_property
|
|
def cookies(self):
|
|
return SimpleCookie(self.headers.get("Cookie"))
|
|
|
|
def get_master_page_header(self, page_title):
|
|
return """<!DOCTYPE html>
|
|
<html xmlns="http://www.w3.org/1999/xhtml">
|
|
<head>
|
|
<title>""" + page_title + """</title>
|
|
<link rel="stylesheet" type="text/css" href="/css/main.css" />
|
|
</head>
|
|
<body>"""
|
|
|
|
def get_master_page_footer(self):
|
|
return "</body></html>"
|
|
|
|
def write(self, text):
|
|
self.wfile.write(text.encode("utf-8"))
|
|
|
|
def write_file(self, filename):
|
|
with open(filename, mode='rb') as f:
|
|
lines = f.read()
|
|
|
|
self.wfile.write(lines)
|
|
|
|
def write_file_text(self, filename):
|
|
with open(filename, mode='r') as f:
|
|
lines = f.read()
|
|
|
|
self.wfile.write(lines.encode("utf-8"))
|
|
|
|
def execute_shell_return_stdout(self, command):
|
|
import os
|
|
p = os.popen(command)
|
|
ret = p.read()
|
|
return ret
|
|
|
|
def get_column_headings(self):
|
|
return [
|
|
'Instance ID',
|
|
'Description',
|
|
'State',
|
|
# Orch Manager
|
|
'Tenants',
|
|
'Info',
|
|
'Disposition Time',
|
|
'Up Time',
|
|
'Password',
|
|
'Actions'
|
|
]
|
|
|
|
def get_column_data(self, instanceId):
|
|
status = self.execute_shell_return_stdout("mocha suv status " + instanceId).split(':')
|
|
primaryStatus = status[0].strip()
|
|
secondaryStatus = ""
|
|
if len(status) > 1:
|
|
secondaryStatus = status[1].strip()
|
|
|
|
tenantsHtml = ""
|
|
tenantsStr = self.execute_shell_return_stdout("mocha suv shell " + instanceId + " -c 'mocha oms tenant list names'")
|
|
tenants = tenantsStr.split('\n')
|
|
for tenant in tenants:
|
|
if tenant != "":
|
|
tenantsHtml += "<a target=\"_blank\" href=\"https://" + instanceId + ".privatesuv.com/" + tenant + "\">" + tenant + " <i class=\"uwt-icon fa fa-arrow-up-right-from-square\"></i></a><br />"
|
|
|
|
|
|
startTimeStr = self.execute_shell_return_stdout("mocha suv shell " + instanceId + " -c 'cat /etc/mocha/suvstart'").strip()
|
|
print("startTimeStr = '" + startTimeStr + "'")
|
|
from datetime import datetime
|
|
startTime = datetime.fromisoformat(startTimeStr)
|
|
currentTime = datetime.now()
|
|
|
|
upTime = (currentTime - startTime)
|
|
|
|
from math import floor
|
|
|
|
secs = floor(upTime.seconds % 60)
|
|
mins = floor((upTime.seconds / 60) % 60)
|
|
hrs = floor((upTime.seconds / (60 * 60)) % 24)
|
|
|
|
|
|
upTimeStr = str(upTime.days) + "d " + str(hrs) + "h " + str(mins) + "m " + str(secs) + "s"
|
|
buttonsHtml = ""
|
|
|
|
if primaryStatus == "stopped":
|
|
buttonsHtml += "<a href=\"/my-suvs/" + instanceId + "/start\">Start</a>"
|
|
else:
|
|
buttonsHtml += "<a href=\"/my-suvs/" + instanceId + "/stop\">Stop</a>"
|
|
|
|
buttonsHtml += " <a href=\"/my-suvs/" + instanceId + "/restart\">Restart</a> <a href=\"/my-suvs/" + instanceId + "/terminate\">Terminate</a>"
|
|
|
|
return [
|
|
instanceId,
|
|
'None',
|
|
"<strong>" + primaryStatus + "</strong><br />" + secondaryStatus,
|
|
# "Orch Manager",
|
|
tenantsHtml,
|
|
"2023.11.10<br />master",
|
|
# Disposition Time
|
|
"Stops In: none",
|
|
# Up Time
|
|
"<!-- " + startTimeStr + " -->" + upTimeStr,
|
|
"<div style=\"text-align: center;\"><a href=\"#\"><i class=\"fa fa-key\"></i></a></div>",
|
|
buttonsHtml
|
|
]
|
|
def get_application_title(self) -> str:
|
|
return "SUV Manager"
|
|
|
|
def write_suv_entry(self, instanceId):
|
|
columns = self.get_column_data(instanceId)
|
|
self.write("<tr>")
|
|
for column in columns:
|
|
self.write("<td>" + column + "</td>")
|
|
self.write("</tr>")
|
|
|
|
def do_GET(self):
|
|
|
|
path = self.url.path.split('/')
|
|
path = path[1:]
|
|
|
|
if path[0] == "":
|
|
|
|
self.send_response(200)
|
|
self.send_header("Content-Type", "application/xhtml+xml")
|
|
self.end_headers()
|
|
|
|
self.write(self.get_master_page_header(self.get_application_title()))
|
|
self.write("<h1>It works</h1>")
|
|
self.write(self.get_master_page_footer())
|
|
|
|
elif path[0] == "css":
|
|
|
|
if path[1] == "main.css":
|
|
|
|
self.write_file_text("/usr/share/mocha/suv-manager/css/main.css")
|
|
|
|
elif path[0] == "common":
|
|
|
|
if path[1] == "fonts":
|
|
|
|
if path[2] == "awesome":
|
|
|
|
if path[3] == "css":
|
|
|
|
if path[4] == "all.min.css":
|
|
|
|
self.write_file("/usr/share/mocha/suv-manager/common/fonts/awesome/css/all.min.css")
|
|
|
|
elif path[3] == "webfonts":
|
|
|
|
self.write_file("/usr/share/mocha/suv-manager/common/fonts/awesome/webfonts/" + path[4])
|
|
|
|
elif path[0] == "my-suvs":
|
|
|
|
if (len(path) == 1 or (len(path) == 2 and path[1] == "")):
|
|
|
|
self.send_response(200)
|
|
self.send_header("Content-Type", "application/xhtml+xml")
|
|
self.end_headers()
|
|
|
|
self.write(self.get_master_page_header("My SUVs - " + self.get_application_title()))
|
|
self.write("""
|
|
<div class="uwt-panel">
|
|
<div class="uwt-content">
|
|
<h1>My SUVs</h1>
|
|
<div class="uwt-toolbar">
|
|
<a href="#" class="uwt-button uwt-color-primary"><i class="uwt-icon fa fa-add"></i><span class="uwt-title">Create SUV</span></a>
|
|
</div>
|
|
<table class="uwt-listview uwt-expand">
|
|
<thead>
|
|
<tr>""")
|
|
|
|
for column in self.get_column_headings():
|
|
self.write("<th> " + column + "</th>")
|
|
|
|
self.write("""</tr></thead><tbody>""")
|
|
|
|
suv_list = self.execute_shell_return_stdout("mocha suv list").split('\n')
|
|
for suv in suv_list:
|
|
if suv != "":
|
|
self.write_suv_entry(suv)
|
|
|
|
self.write("""
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
""")
|
|
self.write(self.get_master_page_footer())
|
|
|
|
elif len(path) == 2:
|
|
|
|
self.write("My SUVs SUV Page for " + path[1])
|
|
|
|
elif len(path) == 3:
|
|
|
|
if path[2] == "stop":
|
|
|
|
self.execute_shell_return_stdout("mocha suv down " + path[1])
|
|
self.send_response(302)
|
|
self.send_header("Location", "/my-suvs")
|
|
self.end_headers()
|
|
|
|
if path[2] == "start":
|
|
|
|
self.execute_shell_return_stdout("mocha suv up " + path[1])
|
|
self.send_response(302)
|
|
self.send_header("Location", "/my-suvs")
|
|
self.end_headers()
|
|
|
|
else:
|
|
|
|
self.write("My SUVs Action (" + path[2] + ") Page for " + path[1])
|
|
|
|
|
|
else:
|
|
|
|
self.send_response(404)
|
|
self.end_headers()
|
|
self.write("Not Found")
|
|
|
|
if __name__ == "__main__":
|
|
|
|
port = 61381
|
|
print("Mocha User Interface Service - running on port", port)
|
|
|
|
server = HTTPServer(("127.0.0.1", port), WebRequestHandler)
|
|
server.serve_forever()
|
|
|