This commit is contained in:
2025-11-13 11:52:09 +01:00
parent a0eac46de2
commit bfd19299ab
6 changed files with 586 additions and 0 deletions

View File

@@ -0,0 +1,177 @@
# API Endpoints — WebUI für AnsibleTUI
Hinweis zur Authentifizierung
- HTTPBasic wird extern via .htpasswd gepflegt; Webserver setzt Auth und ggf. REMOTE_USER.
- Die Applikation verifiziert keine internen Benutzer, erwartet ggf. REMOTE_USER zur AuditZuordnung.
Endpunkte (MVP)
GET /health
- Beschreibung: Simple HealthCheck
- Antwort: 200 OK
GET /playbooks
- Beschreibung: Liste aller hochgeladenen Playbooks (Metadaten)
- Query: ?limit=&offset=
- Antwort: JSON Array [{id,name,filename,uploaded_by,uploaded_at}]
POST /uploads
- Beschreibung: Upload eines ZIP/TAR mit Playbook(s)
- Konsumiert: multipart/form-data file=...
- Validierung: MIME und Dateiendung (zip,tar,tgz), Größenlimit
- Antwort: 201 Created + Metadaten
GET /playbooks/{id}
- Beschreibung: Metadaten zu einem Playbook
- Antwort: JSON
POST /playbooks/{id}/run
- Beschreibung: Startet einen Run via systemweiter ansible-playbook CLI. Keine Nutzung von ansible-runner.
- Body: optional JSON {inventory: string, extra_vars: object, tags: [string], become: bool}
- Behaviour: Prozess wird vom Service gestartet; stdout/stderr werden in temporäre Dateien geschrieben.
- Antwort: 202 Accepted {run_id}
GET /runs/{run_id}/status
- Beschreibung: Statusabfrage (queued,running,success,failed)
- Antwort: JSON {run_id,status,exit_code,started_at,finished_at}
GET /runs/{run_id}/output
- Beschreibung: Holt vollständiges stdout/stderr des Runs (Text/stream)
- Antwort: text/plain (oder chunked)
GET /keys
- Beschreibung: Listet referenzierbare SSHKeys (nur lesend)
- Antwort: JSON [{key_id,filename,description}]
GET /logs?limit=&offset=
- Beschreibung: Zugriff auf RunLogs / AuditEinträge (keine sensiblen Daten)
- Antwort: JSON
SicherheitsHinweis
- Die Applikation führt keine Änderung an SSHKeys oder .htpasswd durch.
- Alle schreibenden Betriebsaufgaben (Permissions, KeyRollout, TLS) sind außerhalb des MVPScopes.
## Erweiterung: Onboarding API — Endpoints für automatisches HostOnboarding
Authentifizierung / Autorisierung
- Auth via vorhandene HTTPBasic/.htpasswdIntegration; Webserver stellt REMOTE_USER zur Verfügung.
- Opsspezifische Endpoints (z. B. Approve) erfordern REMOTE_USER ∈ OpsGruppe (OpsPolicy).
- Transport: Produktion erfordert TLS (OpsDeploymentVoraussetzung).
Zusätzliche Endpoints (Übersicht)
- POST /onboard/requests
- GET /onboard/requests
- GET /onboard/requests/{id}/status
- POST /onboard/requests/{id}/approve
- POST /onboard/requests/{id}/cancel
- GET /onboard/jobs
- GET /onboard/keys
- GET /onboard/requests/{id}/logs
POST /onboard/requests
- Zweck: Erstellt eine OnboardingAnfrage / startet ein OnboardingJob (sofern PreChecks erfolgreich sind).
- Auth: REMOTE_USER (any authenticated user)
- Konsumiert: application/json
- Payload:
{
"host": "192.0.2.10", // host oder IP
"port": 22, // optional, default 22
"login_user": "ubuntu", // Account zur initialen LoginPhase (sudofähig)
"login_password": "secret", // nur intransit; wird nicht persistiert
"desired_user": "ansible", // Benutzer, der angelegt/wenn nötig benutzt wird
"generate_key": true, // true => Server erzeugt Schlüsselpaar (Ed25519/RSA4096 fallback)
"public_key": null, // optional, wenn false und Nutzer eigenen Schlüssel liefert
"description": "Kurzinfo",
"options": { // optional: z. B. {"force_approve":false}
"force_approve": false
}
}
- Verhalten:
- Validierung von Pflichtfeldern.
- Erzeugt OnboardRequest und OnboardJob, reply enthält { "job_id": "...", "status": "created" }.
- Wenn Fingerprint nicht mit Ops known_hosts übereinstimmt, wird status = "awaiting_approval".
- Antwort: 201 Created
{
"job_id": "uuid",
"status": "created" | "awaiting_approval" | "queued"
}
- Fehlercodes:
- 400 Bad Request (Validierungsfehler)
- 401 Unauthorized
- 429 Too Many Requests (RateLimit pro User/Host)
GET /onboard/requests
- Zweck: Listet OnboardingRequests (nur Metadaten)
- Query: ?limit=&offset=&status=
- Antwort: JSON Array [{job_id, host, requested_by, status, created_at, fingerprint_sha256?}]
GET /onboard/requests/{id}/status
- Zweck: Statusabfrage für einen Request
- Antwort:
{
"job_id": "...",
"host": "...",
"status": "created|queued|running|awaiting_approval|approved|onboarded|failed|cancelled",
"retries": 0,
"started_at": "...",
"finished_at": "...",
"error_message": "kurze Fehlerdiagnose (sensitivitätsgefiltert)"
}
POST /onboard/requests/{id}/approve
- Zweck: OpsEndpoint zur Freigabe eines abweichenden HostFingerprints
- Auth: REMOTE_USER muss Ops sein (ServerSide check)
- Payload:
{
"approve": true,
"operator_note": "Fingerprint validiert via call",
"operator_id": "ops-username"
}
- Verhalten: Wenn genehmigt, Job wird zur Fortsetzung freigegeben; AuditEintrag mit operator_id erzeugt.
- Antwort: 200 OK { "job_id": "...", "status": "approved" }
- Fehler: 403 Forbidden (wenn nicht Ops), 404 Not Found
POST /onboard/requests/{id}/cancel
- Zweck: Bricht laufenden/queued OnboardingJob ab (z. B. User Abbruch)
- Auth: Requester oder Ops
- Antwort: 200 OK { "job_id": "...", "status": "cancelled" }
GET /onboard/jobs
- Zweck: Admin/Operator Sicht auf OnboardJobs (Metadaten)
- Filters: status, requested_by, host
- Antwort: Array von jobMetadaten (keine sensitiven Inhalte)
GET /onboard/keys
- Zweck: Listet erzeugte PublicKeys (Metadaten only)
- Antwort: [{ "key_id": "...", "host_id": "...", "public_key_fingerprint": "...", "created_at": "..." }]
GET /onboard/requests/{id}/logs
- Zweck: Liefert redigierte Logs des OnboardingJobs (Ausgaben, Schritte)
- SicherheitsHinweis: Logs sind gesäubert; keine Passwörter oder private KeyMaterial enthalten.
- Antwort: text/plain oder JSON { "lines":[ ... ] }
SicherheitsHinweise für APIDesign
- LoginPassword darf niemals geloggt werden; im APIServer mittelbar nur inmemory übergeben.
- API darf niemals privaten Schlüssel in Responses zurückliefern.
- Alle Endpoints, die sensible Ablaufsteuerung erlauben (approve, cancel), müssen REMOTE_USERChecks durchführen.
- RateLimits: Schutz gegen bruteforce / DOS.
- InputSanitization: host/username dürfen keine ShellInjection ermöglichen; SSHInteraktionen erfolgen kontrolliert.
- Audit: Jeder statewechsel (created, awaiting_approval, approved, onboarded, failed, cancelled) schreibt ein MetadatenAudit (siehe [`webapp/entwicklung/schema.sql`](webapp/entwicklung/schema.sql:1) Anpassungen).
Mapping UI ↔ API
- UIForm "Host Onboarding" ↟ POST /onboard/requests
- UIOps Dashboard ↟ GET /onboard/requests?status=awaiting_approval
- UIOps Approve Button ↟ POST /onboard/requests/{id}/approve
- UIUser Status Polling ↟ GET /onboard/requests/{id}/status
- UILogs ↟ GET /onboard/requests/{id}/logs
BeispielFlow (Kurz)
1. User sendet POST /onboard/requests mit login_password.
2. API antwortet job_id.
3. Onboarding Service führt PreCheck aus; bei FingerprintMismatch → awaiting_approval.
4. Ops Approver ruft POST /onboard/requests/{id}/approve → Service fährt fort.
5. Job schreibt audit_logs und setzt Host Status auf onboarded oder failed.
Referenzen zur weiteren Anpassung
- Architektur: [`webapp/entwicklung/architektur.md`](webapp/entwicklung/architektur.md:1)
- DB Schema: [`webapp/entwicklung/schema.sql`](webapp/entwicklung/schema.sql:1)
- Roadmap: [`webapp/entwicklung/roadmap.md`](webapp/entwicklung/roadmap.md:1)