Files
onGuard24/onguard24/ingress/grafana.py
Alexandr 349cea85a3 v1.4.0: модули с веб-UI, правое меню, расширенные тесты
Реестр MODULE_MOUNTS: API, ui_router, фрагменты главной, EventBus.
Главная и страницы модулей с правой навигацией из реестра; wrap_module_html_page.
Ingress: публикация alert.received после сохранения в БД.
Документация MODULES.md; pytest покрывает API, UI и навигацию.

Made-with: Cursor
2026-04-03 08:45:19 +03:00

59 lines
1.9 KiB
Python

import json
import logging
from datetime import datetime, timezone
from fastapi import APIRouter, Depends, Header, HTTPException, Request
from starlette.responses import Response
from onguard24.domain.entities import Alert, Severity
logger = logging.getLogger(__name__)
router = APIRouter(tags=["ingress"])
async def get_pool(request: Request):
return getattr(request.app.state, "pool", None)
@router.post("/ingress/grafana", status_code=202)
async def grafana_webhook(
request: Request,
pool=Depends(get_pool),
x_onguard_secret: str | None = Header(default=None, alias="X-OnGuard-Secret"),
):
settings = request.app.state.settings
if settings.grafana_webhook_secret and x_onguard_secret != settings.grafana_webhook_secret:
raise HTTPException(status_code=401, detail="unauthorized")
raw = await request.body()
if len(raw) > 1_000_000:
raise HTTPException(status_code=400, detail="body too large")
try:
body = json.loads(raw.decode() or "{}")
except json.JSONDecodeError:
body = {}
if pool is None:
logger.warning("ingress: database not configured, event not persisted")
return Response(status_code=202)
async with pool.acquire() as conn:
row = await conn.fetchrow(
"INSERT INTO ingress_events (source, body) VALUES ($1, $2::jsonb) RETURNING id",
"grafana",
json.dumps(body),
)
raw_id = row["id"] if row else None
bus = getattr(request.app.state, "event_bus", None)
if bus and raw_id is not None:
title = str(body.get("title") or body.get("ruleName") or "")[:500]
alert = Alert(
source="grafana",
title=title,
severity=Severity.WARNING,
payload=body,
received_at=datetime.now(timezone.utc),
)
await bus.publish_alert_received(alert, raw_payload_ref=raw_id)
return Response(status_code=202)