2023-11-26 23:31:32 -05:00

368 lines
10 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/uwt.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().strip()
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()
description = self.execute_shell_return_stdout("mocha suv shell " + instanceId + " -c 'mocha suv description'")
if description == "":
description = "(none)"
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()
upTimeStr = ""
buttonsHtml = ""
if startTimeStr != '':
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"
else:
upTimeStr = "(not running)"
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,
description,
"<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 build_self_service_details(self, instance_id):
tenantsHtml = ""
tenantsStr = self.execute_shell_return_stdout("mocha suv shell " + instance_id + " -c 'mocha oms tenant list names'")
tenants = tenantsStr.split('\n')
for tenant in tenants:
if tenant != "":
tenantsHtml += "<a target=\"_blank\" href=\"https://" + instance_id + ".privatesuv.com/" + tenant + "\">" + tenant + " <i class=\"uwt-icon fa fa-arrow-up-right-from-square\"></i></a>"
if (tenants.index(tenant) < len(tenants) - 1):
tenantsHtml += ", "
return [
{
"title": "General",
"actions": [
{
"icon": "",
"title": "SUV Logs",
"href": "#"
}
],
"properties": {
"Name": "suv",
"Instance ID": instance_id,
"Host Name": instance_id + ".privatesuv.com",
"Environment Version": "584026",
"Confidence Level": "prod",
"Status": { "backgroundColor": "#aaffaa", "value": "completed" }
}
},
{
"title": "Data Manager",
"actions": [
{
"icon": "",
"title": "Reset Tenants",
"href": "#"
}
],
"properties": {
"Tenants": tenantsHtml,
"Tenant Version": "2023.11.12"
}
},
{
"title": "MySQL",
"properties": {
"User": "root",
"Host": "localhost",
"Port": 3306,
"Status": { "backgroundColor": "#aaffaa", "value": "running" }
}
}
]
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] == "uwt.css":
self.write_file_text("/usr/share/mocha/suv-manager/css/uwt.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()
elif 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()
elif path[2] == "self-service":
suv_inst_id = path[1]
suv_confidence_level = 'prod'
self.send_response(200)
self.send_header("Content-Type", "application/xhtml+xml")
self.end_headers()
self.write(self.get_master_page_header("SUV Self Service - " + self.get_application_title()))
self.write("<h1>SUV Self Service</h1>")
self_service = self.build_self_service_details(path[1])
for self_service_panel in self_service:
self.write("""<div class="uwt-panel"><div class="uwt-header"><h2>""" + self_service_panel["title"] + """</h2></div><div class="uwt-content"><div class="uwt-toolbar">""")
if "actions" in self_service_panel:
for self_service_action in self_service_panel["actions"]:
self.write("""<a href=\"""" + self_service_action["href"] + """\" class="uwt-button uwt-color-primary"><i class="uwt-icon fa fa-""" + self_service_action["icon"] + """\"></i><span class="uwt-title">""" + self_service_action["title"] + """</span></a>""")
self.write("</div>")
self.write("""<table class="uwt-listview uwt-expand"><thead><tr><th style="width: 50%">Property</th><th>Value</th></tr></thead><tbody>""")
if "properties" in self_service_panel:
for name in self_service_panel["properties"]:
value = self_service_panel["properties"][name]
val = ""
if (isinstance(value, dict)):
self.write("<tr><td>" + name + "</td>")
if "backgroundColor" in value:
self.write("<td style=\"background-color: " + value["backgroundColor"] + "\">")
else:
self.write("<td>")
self.write(str(value["value"]) + "</td></tr>")
else:
self.write("<tr><td>" + name + "</td><td>" + str(value) + "</td></tr>")
self.write("</tbody></table></div></div>")
self.write(self.get_master_page_footer())
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()