140 lines
5.7 KiB
Python
140 lines
5.7 KiB
Python
import html
|
|
|
|
from fastapi import APIRouter, Depends
|
|
|
|
from ..auth import require_user
|
|
from ..templates.layout import page
|
|
|
|
router = APIRouter()
|
|
|
|
|
|
# Portal sections (the admin/agenda links shown in the navigation). role: minimum role that can
|
|
# actually use the section; viewers may see read-only data where a section allows it.
|
|
PORTAL_SECTIONS = [
|
|
("fa-server", "Služby", "/portal/apps",
|
|
"Přehled nasazených služeb: stav, dokumentace, prostředky (RAM/CPU), Git a akce.", "viewer (čtení) / developer / admin"),
|
|
("fa-list-check", "Úlohy", "/portal/jobs",
|
|
"Fronta a historie úloh (nasazení, skripty) včetně stavů a logů.", "developer / admin"),
|
|
("fa-calendar-days", "Plánované skripty", "/portal/scheduled-scripts",
|
|
"Cron-like skripty spouštěné na pozadí; úpravy jen pro administrátory.", "developer / admin"),
|
|
("fa-bell", "Alerting", "/portal/alerting/rules",
|
|
"Pravidla alertů a jejich skripty; úpravy jen pro administrátory.", "developer / admin"),
|
|
("fa-gauge-high", "Přehled", "/portal/operations",
|
|
"Operační přehled systému, běžící nasazení a stav služeb.", "admin"),
|
|
("fa-diagram-project", "Migration Readiness", "/portal/migration-readiness",
|
|
"Připravenost a deploy core služeb AppFactory.", "admin"),
|
|
("fa-rocket", "Nasazení", "/portal/deployments",
|
|
"Historie deploy běhů, stavů a výstupů z deploy procesu.", "developer / admin"),
|
|
("fa-triangle-exclamation", "Incidenty", "/portal/incidents",
|
|
"Evidované incidenty služeb.", "developer / admin"),
|
|
("fa-gears", "Workery", "/portal/workers",
|
|
"Stav workerů zpracovávajících úlohy.", "admin"),
|
|
("fa-users", "Users", "/portal/admin/users",
|
|
"Správa uživatelů a rolí (viewer / developer / admin).", "admin"),
|
|
("fa-clipboard-list", "Audit", "/portal/audit",
|
|
"Auditní log akcí provedených v portálu.", "admin"),
|
|
("fa-box-archive", "Zálohy", "/portal/backups",
|
|
"Vytváření, stažení a obnova záloh AppFactory. Obnova je jen pro administrátory.", "admin"),
|
|
]
|
|
|
|
# Public / API endpoints not gated by the portal login.
|
|
PUBLIC_ENDPOINTS = [
|
|
("GET", "/apps", "Veřejný JSON katalog služeb (název + odkaz na dokumentaci). Routuje se přes Caddy."),
|
|
("GET", "/portal/health", "Health endpoint portálu (HTTP 200, pokud portál běží)."),
|
|
("GET", "/apps/<app-id>/docs", "Swagger/OpenAPI dokumentace konkrétní služby."),
|
|
("GET", "/apps/<app-id>/health", "Health endpoint konkrétní služby."),
|
|
]
|
|
|
|
# Roles model.
|
|
ROLES = [
|
|
("viewer", "Pouze pro čtení: vidí jaké služby běží a jejich dokumentaci (Swagger). Bez Gitu, úprav, nasazení a mazání."),
|
|
("developer", "Vše co viewer + provozní workflow služeb: Git/klonování, nasazení, proměnné, prostředky, metadata. Nemůže mazat služby ani do Administrace."),
|
|
("admin", "Plný přístup: vše co developer + mazání služeb, správa záloh a jejich obnova, správa uživatelů, audit a admin-only operace."),
|
|
]
|
|
|
|
|
|
@router.get("/developers")
|
|
def developers_page(user=Depends(require_user)):
|
|
section_rows = ""
|
|
for icon, title, href, desc, roles in PORTAL_SECTIONS:
|
|
section_rows += f"""
|
|
<tr>
|
|
<td><a href="{href}"><i class="fa-solid {icon}" aria-hidden="true"></i> {html.escape(title)}</a></td>
|
|
<td><code>{html.escape(href)}</code></td>
|
|
<td>{html.escape(desc)}</td>
|
|
<td><span class="muted">{html.escape(roles)}</span></td>
|
|
</tr>
|
|
"""
|
|
|
|
endpoint_rows = ""
|
|
for method, path, desc in PUBLIC_ENDPOINTS:
|
|
endpoint_rows += f"""
|
|
<tr>
|
|
<td><span class="pill">{html.escape(method)}</span></td>
|
|
<td><code>{path}</code></td>
|
|
<td>{html.escape(desc)}</td>
|
|
</tr>
|
|
"""
|
|
|
|
role_rows = ""
|
|
for role, desc in ROLES:
|
|
role_rows += f"""
|
|
<tr>
|
|
<td><span class="pill pill-muted">{html.escape(role)}</span></td>
|
|
<td>{html.escape(desc)}</td>
|
|
</tr>
|
|
"""
|
|
|
|
return page(
|
|
"Pro vývojáře",
|
|
f"""
|
|
<div class="card">
|
|
<h2><i class="fa-solid fa-code" aria-hidden="true"></i> Pro vývojáře</h2>
|
|
<p class="muted">
|
|
Přehled všech sekcí portálu, veřejných endpointů a rolí. Portál běží za reverzní proxy
|
|
na cestě <code>/portal</code>; jednotlivé služby na <code>/apps/<app-id></code>.
|
|
</p>
|
|
</div>
|
|
|
|
<div class="card">
|
|
<h2><i class="fa-solid fa-diagram-project" aria-hidden="true"></i> Sekce portálu (agendy)</h2>
|
|
<table>
|
|
<tr>
|
|
<th>Sekce</th>
|
|
<th>Odkaz</th>
|
|
<th>Popis</th>
|
|
<th>Role</th>
|
|
</tr>
|
|
{section_rows}
|
|
</table>
|
|
</div>
|
|
|
|
<div class="card">
|
|
<h2><i class="fa-solid fa-plug" aria-hidden="true"></i> Veřejné / API endpointy</h2>
|
|
<table>
|
|
<tr>
|
|
<th>Metoda</th>
|
|
<th>Cesta</th>
|
|
<th>Popis</th>
|
|
</tr>
|
|
{endpoint_rows}
|
|
</table>
|
|
<p class="muted">
|
|
Veřejný katalog <code>/apps</code> vrací JSON se seznamem služeb a odkazy na jejich dokumentaci.
|
|
</p>
|
|
</div>
|
|
|
|
<div class="card">
|
|
<h2><i class="fa-solid fa-user-shield" aria-hidden="true"></i> Role a oprávnění</h2>
|
|
<table>
|
|
<tr>
|
|
<th>Role</th>
|
|
<th>Co může</th>
|
|
</tr>
|
|
{role_rows}
|
|
</table>
|
|
</div>
|
|
""",
|
|
user=user,
|
|
)
|