feat: S07 operations hardening and OpenConnector integration
Deploy Claude Dev (Dev) / deploy-claude-dev-dev (push) Failing after 2m3s
Deploy Dashboard (Main) / Backend Tests (push) Successful in 3m7s
Deploy Dashboard (Main) / Frontend Tests (push) Successful in 6s
Deploy Dashboard (Main) / Deploy to Production (push) Has been cancelled
Deploy Dashboard (Main) / Build Main Image (push) Has been cancelled
Deploy Dashboard (Dev) / Backend Tests (push) Successful in 1m18s
Deploy Dashboard (Dev) / Frontend Tests (push) Successful in 51s
Deploy Dashboard (Dev) / Build Dev Image (push) Successful in 1m42s
Deploy Dashboard (Dev) / Deploy to Dev (push) Successful in 58s
Deploy Claude Dev (Dev) / deploy-claude-dev-dev (push) Failing after 2m3s
Deploy Dashboard (Main) / Backend Tests (push) Successful in 3m7s
Deploy Dashboard (Main) / Frontend Tests (push) Successful in 6s
Deploy Dashboard (Main) / Deploy to Production (push) Has been cancelled
Deploy Dashboard (Main) / Build Main Image (push) Has been cancelled
Deploy Dashboard (Dev) / Backend Tests (push) Successful in 1m18s
Deploy Dashboard (Dev) / Frontend Tests (push) Successful in 51s
Deploy Dashboard (Dev) / Build Dev Image (push) Successful in 1m42s
Deploy Dashboard (Dev) / Deploy to Dev (push) Successful in 58s
This commit is contained in:
@@ -72,6 +72,7 @@ EXTERNAL_SERVICES = {
|
||||
"vaultwarden": os.environ.get("VAULTWARDEN_URL", "https://vault.jimmygan.com"),
|
||||
"n8n": os.environ.get("N8N_URL", "https://n8n.jimmygan.com"),
|
||||
"speedtest": os.environ.get("SPEEDTEST_URL", "https://speed.jimmygan.com"),
|
||||
"openconnector": os.environ.get("OPENCONNECTOR_URL", "https://connector.jimmygan.com"),
|
||||
}
|
||||
|
||||
# Network addresses (used by frontend for LAN/Tailscale direct access)
|
||||
|
||||
@@ -143,12 +143,13 @@ async def security_headers(request: Request, call_next):
|
||||
|
||||
# Audit logger
|
||||
import os
|
||||
from logging.handlers import RotatingFileHandler
|
||||
|
||||
_audit_log_path = os.path.join(VOLUME_ROOT, "docker/nas-dashboard/audit.log")
|
||||
os.makedirs(os.path.dirname(_audit_log_path), exist_ok=True)
|
||||
_audit_logger = logging.getLogger("audit")
|
||||
_audit_logger.setLevel(logging.INFO)
|
||||
_audit_handler = logging.FileHandler(_audit_log_path)
|
||||
_audit_handler = RotatingFileHandler(_audit_log_path, maxBytes=10 * 1024 * 1024, backupCount=5)
|
||||
_audit_handler.setFormatter(logging.Formatter("%(message)s"))
|
||||
_audit_logger.addHandler(_audit_handler)
|
||||
_audit_logger.propagate = False
|
||||
@@ -229,7 +230,48 @@ async def monitor_containers():
|
||||
|
||||
@app.get("/api/health")
|
||||
async def health():
|
||||
return {"status": "ok"}
|
||||
import shutil
|
||||
import docker
|
||||
import logging
|
||||
from fastapi.responses import JSONResponse
|
||||
from fastapi import status
|
||||
from db import opc_db
|
||||
from config import DOCKER_HOST, VOLUME_ROOT
|
||||
|
||||
db_ok = False
|
||||
try:
|
||||
pool = await opc_db.get_pool()
|
||||
async with pool.acquire() as conn:
|
||||
await conn.execute("SELECT 1")
|
||||
db_ok = True
|
||||
except Exception as e:
|
||||
logging.getLogger(__name__).error("Health check DB connection failed: %s", e)
|
||||
|
||||
docker_ok = False
|
||||
try:
|
||||
client = docker.DockerClient(base_url=DOCKER_HOST)
|
||||
docker_ok = client.ping()
|
||||
except Exception as e:
|
||||
logging.getLogger(__name__).error("Health check Docker connection failed: %s", e)
|
||||
|
||||
free_gb = 0.0
|
||||
try:
|
||||
total, used, free = shutil.disk_usage(VOLUME_ROOT)
|
||||
free_gb = round(free / (1024 ** 3), 2)
|
||||
except Exception as e:
|
||||
logging.getLogger(__name__).error("Health check disk usage failed: %s", e)
|
||||
|
||||
status_code = status.HTTP_200_OK if (db_ok and docker_ok) else status.HTTP_503_SERVICE_UNAVAILABLE
|
||||
|
||||
return JSONResponse(
|
||||
status_code=status_code,
|
||||
content={
|
||||
"status": "ok" if (db_ok and docker_ok) else "degraded",
|
||||
"db": "connected" if db_ok else "disconnected",
|
||||
"docker": "healthy" if docker_ok else "unhealthy",
|
||||
"disk": {"free_gb": free_gb}
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
@app.get("/api/client-ip")
|
||||
|
||||
Reference in New Issue
Block a user