Enterprise-Backup-, Recovery-, Verification-, Security- und Monitoring-Plattform fuer Proxmox VE, Windows, Linux und Dateisysteme. Der Leitsatz, der fast jede Entscheidung erklaert: Ein Backup gilt erst als vertrauenswuerdig, wenn Integritaet geprueft und Wiederherstellbarkeit nachgewiesen wurde. Deshalb steigt ein Wiederherstellungspunkt erst nach einem tatsaechlich durchgefuehrten Restore-Test auf "recoverable", und Unbekanntes geht in keine Bewertung als "gut" ein. Umfang (Phasen 0-23): - Repository Engine: inhaltsadressierte Bloecke, atomares Commit-Protokoll, Katalogaufbau allein aus den Manifesten — ohne Datenbank - Backup Engine: inhaltsabhaengiges Chunking, Deduplizierung trotz Verschluesselung, zstd, AES-256-GCM, Streaming mit Gegendruck - Agenten fuer Windows und Linux mit Auftragsabholung (Pull-Modell) - Proxmox-Provider mit beiden Zugriffswegen auf die Sicherungsarchive - Scheduler, Recovery Engine mit Pruefpunkt, Verification, Unveraenderlichkeit - Weboberflaeche, Kennzahlen, Meldungen, Berichte, Security Center, Ransomware-Heuristik (meldet, handelt nie) - Disaster Recovery, Haertung, Leistungsmessung, Chaos Testing - Eingefrorene Vertraege fuer API, Migrationen, Backup-Format und Repository - Auslieferungspaket fuer linux/amd64, linux/arm64 und windows/amd64 Nicht enthalten und als solches gekennzeichnet: Kapazitaetsprognose, Backup Copy, Changed Block Tracking bei Proxmox, erweiterte Attribute und ACLs. Gebaut, aber nie auf echter Hardware gefahren: der Windows-Dienst, die systemd-Einheit und der verpflichtende Proxmox-Meilenstein — ob eine wiederhergestellte VM startet, ist ungeprueft. Einzelheiten in CHANGELOG.md und docs/release-candidate.md. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
95 lines
3.5 KiB
Go
95 lines
3.5 KiB
Go
package httpapi
|
|
|
|
import (
|
|
"log/slog"
|
|
"net/http"
|
|
|
|
"github.com/syncova/syncova/packages/platform/config"
|
|
"github.com/syncova/syncova/packages/platform/health"
|
|
)
|
|
|
|
// healthHandler bedient die Betriebs- und Systemzustands-Endpunkte
|
|
// (SYNCOVA_API.md §23, PROMPT.md §93/§94).
|
|
type healthHandler struct {
|
|
// healthRegistry liefert den Zustand aller überwachten Komponenten.
|
|
healthRegistry *health.Registry
|
|
// logger protokolliert Zustandsabfragen und Fehler.
|
|
logger *slog.Logger
|
|
// buildVersion ist die ausgelieferte Programmversion.
|
|
buildVersion string
|
|
// environment ist die Betriebsumgebung des Dienstes.
|
|
environment config.Environment
|
|
}
|
|
|
|
// livenessResponse ist die Antwort auf eine Liveness-Prüfung.
|
|
type livenessResponse struct {
|
|
// Status ist "alive", sobald der Prozess Requests bedienen kann.
|
|
Status string `json:"status"`
|
|
}
|
|
|
|
// readinessResponse ist die Antwort auf eine Readiness-Prüfung.
|
|
type readinessResponse struct {
|
|
// Ready meldet, ob der Dienst Verkehr annehmen darf.
|
|
Ready bool `json:"ready"`
|
|
// Status ist der Gesamtzustand über alle Komponenten.
|
|
Status health.Status `json:"status"`
|
|
}
|
|
|
|
// systemHealthResponse ist der ausführliche Systemzustand.
|
|
type systemHealthResponse struct {
|
|
// Status ist der schlechteste Zustand aller Komponenten.
|
|
Status health.Status `json:"status"`
|
|
// Components enthält das Ergebnis je Komponente.
|
|
Components map[string]health.CheckResult `json:"components"`
|
|
// Version ist die laufende Programmversion.
|
|
Version string `json:"version"`
|
|
// Environment ist die Betriebsumgebung.
|
|
Environment string `json:"environment"`
|
|
}
|
|
|
|
// handleLiveness beantwortet GET /health/live.
|
|
//
|
|
// Liveness beantwortet ausschließlich die Frage, ob der Prozess selbst arbeitet.
|
|
// Sie prüft bewusst keine Abhängigkeiten: sonst würde eine kurzzeitig nicht
|
|
// erreichbare Datenbank einen Neustart des Dienstes auslösen.
|
|
func (handler *healthHandler) handleLiveness(responseWriter http.ResponseWriter, request *http.Request) {
|
|
WriteSuccess(responseWriter, request, http.StatusOK, livenessResponse{Status: "alive"})
|
|
}
|
|
|
|
// handleReadiness beantwortet GET /health/ready.
|
|
//
|
|
// Readiness prüft alle als kritisch markierten Komponenten. Ist eine davon
|
|
// gestört, liefert der Endpunkt 503, damit kein Verkehr zugestellt wird.
|
|
func (handler *healthHandler) handleReadiness(responseWriter http.ResponseWriter, request *http.Request) {
|
|
isReady, systemReport := handler.healthRegistry.IsReady(request.Context())
|
|
|
|
responseStatusCode := http.StatusOK
|
|
if !isReady {
|
|
responseStatusCode = http.StatusServiceUnavailable
|
|
}
|
|
|
|
WriteSuccess(responseWriter, request, responseStatusCode, readinessResponse{
|
|
Ready: isReady,
|
|
Status: systemReport.Status,
|
|
})
|
|
}
|
|
|
|
// handleSystemHealth beantwortet GET /api/v1/health mit dem Komponentenbericht.
|
|
func (handler *healthHandler) handleSystemHealth(responseWriter http.ResponseWriter, request *http.Request) {
|
|
systemReport := handler.healthRegistry.Check(request.Context())
|
|
|
|
// Der HTTP-Status folgt dem Gesamtzustand: ein kritischer Bericht darf nicht
|
|
// mit 200 quittiert werden, sonst übersieht ihn jedes externe Monitoring.
|
|
responseStatusCode := http.StatusOK
|
|
if systemReport.Status == health.StatusCritical || systemReport.Status == health.StatusOffline {
|
|
responseStatusCode = http.StatusServiceUnavailable
|
|
}
|
|
|
|
WriteSuccess(responseWriter, request, responseStatusCode, systemHealthResponse{
|
|
Status: systemReport.Status,
|
|
Components: systemReport.Components,
|
|
Version: handler.buildVersion,
|
|
Environment: string(handler.environment),
|
|
})
|
|
}
|