feat (docs): voeg Swagger UI toe op /docs, lokaal gebundeld

- Swagger UI v5.32.1 lokaal in assets/swagger-ui/ (geen CDN, offline bruikbaar)
- webui/html/docs/index.html: custom pagina die /api/openapi.json laadt
  met requestInterceptor zodat Try it out via same-origin werkt
- Link toegevoegd aan dashboard "Snel acties": API docs ↗ (opent in nieuw tabblad)
- Docstrings toegevoegd aan destructieve endpoints (app_containers, app_images):
  container stop/restart, image remove (batch + single), image prune
  geven nu ⚠️-waarschuwingen in de Swagger UI beschrijving
- Backend rebuild nodig voor docstrings zichtbaar in spec

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-23 07:30:51 +01:00
parent c338955320
commit e469508570
6 changed files with 57 additions and 0 deletions
+9
View File
@@ -572,6 +572,15 @@ def init_containers_router(
@router.post("/containers/{action}/{name}")
def container_action(action: str, name: str):
"""
Voer een actie uit op een container.
- **start** — Start de container (of bijbehorende systemd-unit).
- **stop** — ⚠️ Destructief: stopt de container direct.
- **restart** — ⚠️ Destructief: herstart de container direct.
Gebruikt systemd als de container een beheerde unit heeft; anders Podman API direct.
"""
if action not in ("start", "stop", "restart"):
return {"error": "Invalid action"}, 400
+3
View File
@@ -73,6 +73,7 @@ def init_images_router(session, podman_api_base: str) -> APIRouter:
# --- STAP 2: remove selected (batch) ---
@router.post("/remove")
def remove_images(req: ImageRemoveRequest):
"""⚠️ Destructief: verwijdert één of meerdere images permanent. Niet terug te draaien."""
# Libpod heeft batch remove via query params (images=...).
url = f"{podman_api_base}/libpod/images/remove"
params = {
@@ -91,6 +92,7 @@ def init_images_router(session, podman_api_base: str) -> APIRouter:
force: bool = Query(False),
ignore: bool = Query(False),
):
"""⚠️ Destructief: verwijdert één image permanent op basis van naam of ID."""
url = f"{podman_api_base}/libpod/images/remove"
params = {
"images": [image_ref],
@@ -104,6 +106,7 @@ def init_images_router(session, podman_api_base: str) -> APIRouter:
# --- STAP 2: prune (dangling default, all=true => unused) ---
@router.post("/prune")
def prune_images(all: bool = Query(False)):
"""⚠️ Destructief: verwijdert dangling images (standaard) of alle ongebruikte images (`all=true`)."""
url = f"{podman_api_base}/libpod/images/prune"
params = {"all": str(all).lower()}
resp = session.post(url, params=params)
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+39
View File
@@ -0,0 +1,39 @@
<!doctype html>
<html lang="nl">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<title>API Documentatie — Podman MVP</title>
<link rel="stylesheet" href="../assets/swagger-ui/swagger-ui.css" />
<style>
body { margin: 0; }
.topbar { background: #1a1a2e; padding: 12px 20px; display: flex; align-items: center; gap: 16px; }
.topbar a { color: #ccc; text-decoration: none; font-size: 0.85rem; }
.topbar a:hover { color: #fff; }
.topbar-title { color: #fff; font-weight: 600; font-size: 1rem; }
</style>
</head>
<body>
<div class="topbar">
<span class="topbar-title">Podman MVP — API Documentatie</span>
<a href="/">← Terug naar UI</a>
</div>
<div id="swagger-ui"></div>
<script src="../assets/swagger-ui/swagger-ui-bundle.js"></script>
<script>
SwaggerUIBundle({
url: '/api/openapi.json',
dom_id: '#swagger-ui',
deepLinking: true,
presets: [SwaggerUIBundle.presets.apis, SwaggerUIBundle.SwaggerUIStandalonePreset],
layout: 'BaseLayout',
tryItOutEnabled: true,
requestInterceptor: (req) => {
// Zorg dat Try it out via dezelfde origin gaat (geen CORS issues)
req.url = req.url.replace(/^https?:\/\/[^/]+/, '');
return req;
},
});
</script>
</body>
</html>
+1
View File
@@ -110,6 +110,7 @@
<button class="btn" onclick="setTab('networks')">Ga naar netwerken</button>
<button class="btn" onclick="setTab('images')">Ga naar images</button>
<button class="btn" onclick="setTab('files')">Ga naar files</button>
<a class="btn ghost" href="/docs/" target="_blank">API docs ↗</a>
</div>
<div class="hint">Gebruik de zijbalk voor detailbeheer; deze acties geven snelle toegang tot de hoofdsecties.</div>
</div>