Add Kubernetes liveness/readiness probes and middleware order validation
- Split /health into /health/live (liveness) and /health/ready (readiness) following Kubernetes conventions. Combined /health retained for backward compatibility with existing Docker HEALTHCHECK definitions. - Add ReadyCheck and ReadyResponse models for structured readiness output. - Add _assert_middleware_order() startup check enforcing: RateLimit → Csrf → CorrelationId middleware chain. - Register CorrelationIdMiddleware, CsrfMiddleware, RateLimitMiddleware in create_app() with documented required order (reverse of processing). - Add correlation.py, csrf.py, rate_limit.py middleware modules. - Add health probe tests in test_health_probes.py. - Update test_main.py with middleware order assertion tests. - Update frontend useFetchData hook tests. - Docs: update Deployment.md with Kubernetes probe config examples.
This commit is contained in:
@@ -480,3 +480,53 @@ class FlushLogsResponse(BanGuiBaseModel):
|
||||
"""
|
||||
|
||||
message: str = Field(..., description="Human-readable result message from fail2ban.")
|
||||
|
||||
|
||||
class ReadyCheck(BanGuiBaseModel):
|
||||
"""Result of a single readiness subsystem check.
|
||||
|
||||
Fields:
|
||||
name: Subsystem name (e.g., "database", "fail2ban", "config_dir").
|
||||
healthy: True when the subsystem is reachable/operational.
|
||||
message: Optional error message describing the failure.
|
||||
"""
|
||||
|
||||
name: str = Field(..., description="Subsystem name.")
|
||||
healthy: bool = Field(..., description="True when the subsystem is operational.")
|
||||
message: str | None = Field(
|
||||
default=None,
|
||||
description="Error detail when the check fails.",
|
||||
)
|
||||
|
||||
|
||||
class ReadyResponse(BanGuiBaseModel):
|
||||
"""Structured readiness check response for the ``/health/ready`` endpoint.
|
||||
|
||||
Fields:
|
||||
status: "ok" when all checks pass, "error" when at least one failed.
|
||||
checks: Per-subsystem result list.
|
||||
failed_count: Number of checks that returned healthy=False.
|
||||
|
||||
Example:
|
||||
```python
|
||||
# All healthy (HTTP 200)
|
||||
{"status": "ok", "checks": [...], "failed_count": 0}
|
||||
|
||||
# Some failed (HTTP 503)
|
||||
{"status": "error", "checks": [...], "failed_count": 2}
|
||||
```
|
||||
"""
|
||||
|
||||
status: Literal["ok", "error"] = Field(
|
||||
...,
|
||||
description="'ok' when all checks pass, 'error' when at least one fails.",
|
||||
)
|
||||
checks: list[ReadyCheck] = Field(
|
||||
default_factory=list,
|
||||
description="Per-subsystem check results.",
|
||||
)
|
||||
failed_count: int = Field(
|
||||
...,
|
||||
ge=0,
|
||||
description="Number of checks that returned healthy=False.",
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user