Files
ITWorx_MCP_Hub-Public/services/runtime/synthetic_monitor.py
T

89 lines
3.5 KiB
Python

"""Permanent, secret-free synthetic monitoring for the governed Gitea surface."""
from __future__ import annotations
import json
import re
import urllib.error
import urllib.request
from dataclasses import dataclass
from pathlib import Path
from typing import Any
import yaml # type: ignore[import-untyped]
_GITEA_READY_URL = "http://connector-gitea:8080/health/ready"
_FINGERPRINT = re.compile(r"^[0-9a-f]{64}$")
_MAX_RESPONSE_BYTES = 32 * 1024
@dataclass(frozen=True)
class SyntheticSnapshot:
tool_count: int
capability_fingerprint: str
upstream: str
def expected_gitea_wire_tools(catalog_root: Path) -> frozenset[str]:
names: set[str] = set()
for path in sorted((catalog_root / "tools").glob("*.yaml")):
value = yaml.safe_load(path.read_text(encoding="utf-8"))
spec = value.get("spec", {}) if isinstance(value, dict) else {}
if spec.get("connectorType") != "gitea":
continue
name = spec.get("connectorToolName", spec.get("canonicalName"))
if not isinstance(name, str) or not name:
raise ValueError("Gitea catalog carries an invalid connector tool name")
names.add(name)
if not names:
raise ValueError("Gitea synthetic monitor has no expected tools")
return frozenset(names)
class GiteaSyntheticMonitor:
"""Probe upstream reachability and detect capability drift every worker cycle."""
def __init__(self, catalog_root: Path) -> None:
self.expected_tools = expected_gitea_wire_tools(catalog_root)
self._baseline_fingerprint: str | None = None
def probe(self) -> SyntheticSnapshot:
request = urllib.request.Request( # noqa: S310 - fixed internal allowlisted endpoint
_GITEA_READY_URL,
headers={"Accept": "application/json"},
method="GET",
)
try:
with urllib.request.urlopen(request, timeout=5) as response: # noqa: S310
raw = response.read(_MAX_RESPONSE_BYTES + 1)
status = int(response.status)
except (OSError, urllib.error.URLError) as exc:
raise RuntimeError("Gitea synthetic readiness probe failed") from exc
if status != 200 or len(raw) > _MAX_RESPONSE_BYTES:
raise RuntimeError("Gitea synthetic readiness response is invalid")
try:
payload: Any = json.loads(raw)
except (UnicodeDecodeError, json.JSONDecodeError) as exc:
raise RuntimeError("Gitea synthetic readiness response is invalid") from exc
if not isinstance(payload, dict):
raise RuntimeError("Gitea synthetic readiness response is invalid")
fingerprint = payload.get("capabilityFingerprint")
tool_count = payload.get("toolCount")
if (
payload.get("status") != "ready"
or payload.get("upstream") != "reachable"
or not isinstance(tool_count, int)
or tool_count != len(self.expected_tools)
or not isinstance(fingerprint, str)
or not _FINGERPRINT.fullmatch(fingerprint)
):
raise RuntimeError("Gitea synthetic capability contract drifted")
if self._baseline_fingerprint is not None and fingerprint != self._baseline_fingerprint:
raise RuntimeError("Gitea synthetic capability fingerprint changed unexpectedly")
self._baseline_fingerprint = fingerprint
return SyntheticSnapshot(
tool_count=tool_count,
capability_fingerprint=fingerprint,
upstream="reachable",
)