From 43c75df1edd69caf651a27a17bc246d211ccc651 Mon Sep 17 00:00:00 2001 From: Thomas Stallinger Date: Fri, 7 Aug 2026 01:59:34 +0200 Subject: [PATCH] feat: Bereitstellungsvorlagen im Kunden-Admin-Bereich anlegen Neue Sektion auf der /admin/kunden/{id}-Detailseite: Liste bestehender Bereitstellungsvorlagen der Organisation + Formular zum Anlegen einer neuen (Workspace, Backend, Root-Dateisystem, Default/Diskverschluesselung/ Secure-Boot), ruft den neuen provisioning-server-Endpoint auf. Schliesst die in Phase 5 dokumentierte Luecke: bisher hatte eine frische Kundenorganisation keine Moeglichkeit, ueberhaupt eine Vorlage zu bekommen, und damit eine leere Auswahl auf der Installationsmedium-Selfservice-Seite. Lokal end-to-end verifiziert (siehe provisioning-server-Commit). Co-Authored-By: Claude Sonnet 5 --- routers/admin_kunden.py | 41 ++++++++++++++++++++ templates/admin/kunden_detail.html | 61 ++++++++++++++++++++++++++++++ 2 files changed, 102 insertions(+) diff --git a/routers/admin_kunden.py b/routers/admin_kunden.py index ab9dcad..c090389 100644 --- a/routers/admin_kunden.py +++ b/routers/admin_kunden.py @@ -51,6 +51,15 @@ def detail(request: Request, organization_id: str, user: dict = Depends(require_ benutzer = fetch_benutzer_fuer_organisation(organization_id) + vorlagen_result = anode_request("GET", f"/api/v1/organizations/{organization_id}/bereitstellungsvorlagen") + bereitstellungsvorlagen = vorlagen_result.get("bereitstellungsvorlagen", []) if vorlagen_result.get("success") else [] + + workspaces_result = anode_request("GET", "/api/v1/workspaces") + workspaces = workspaces_result.get("workspaces", []) if workspaces_result.get("success") else [] + + backends_result = anode_request("GET", "/api/v1/backends") + backends = backends_result.get("backends", []) if backends_result.get("success") else [] + return templates.TemplateResponse( request, "admin/kunden_detail.html", @@ -60,10 +69,42 @@ def detail(request: Request, organization_id: str, user: dict = Depends(require_ "organization_id": organization_id, "activation_codes": activation_codes, "benutzer": benutzer, + "bereitstellungsvorlagen": bereitstellungsvorlagen, + "workspaces": workspaces, + "backends": backends, }, ) +@router.post("/{organization_id}/bereitstellungsvorlagen") +def bereitstellungsvorlage_anlegen( + organization_id: str, + workspace_id: str = Form(...), + backend_id: str = Form(...), + label: str = Form(...), + is_default: str = Form(default=""), + disk_encryption: str = Form(default=""), + root_filesystem: str = Form(default="ext4"), + secure_boot_required: str = Form(default=""), + user: dict = Depends(require_admin), +): + anode_request( + "POST", + f"/api/v1/organizations/{organization_id}/bereitstellungsvorlagen", + json={ + "workspace_id": workspace_id, + "backend_id": backend_id, + "label": label, + "is_default": is_default == "on", + "disk_encryption": disk_encryption == "on", + "root_filesystem": root_filesystem, + "secure_boot_required": secure_boot_required == "on", + }, + ) + + return RedirectResponse(f"/admin/kunden/{organization_id}", status_code=303) + + @router.post("/{organization_id}/activation-codes") def aktivierungscode_anlegen(organization_id: str, user: dict = Depends(require_admin)): anode_request("POST", f"/api/v1/organizations/{organization_id}/activation-codes") diff --git a/templates/admin/kunden_detail.html b/templates/admin/kunden_detail.html index 14ecd72..f219f83 100644 --- a/templates/admin/kunden_detail.html +++ b/templates/admin/kunden_detail.html @@ -25,6 +25,67 @@ +
+

Bereitstellungsvorlagen

+
+ + + + {% for v in bereitstellungsvorlagen %} + + + + + + + {% endfor %} + +
BezeichnungWorkspaceBackendStandard
{{ v.label }}{{ v.workspace.name }}{{ v.backend.name }} {{ v.backend.version }}{{ "ja" if v.is_default else "nein" }}
+
+
+ Neue Bereitstellungsvorlage anlegen +
+ + + + + + + + + + + + + + + + + +
+
+
+

Kundenkonten