34 lines
2.5 KiB
Markdown
34 lines
2.5 KiB
Markdown
# Endpoint Monitor service contract
|
||
|
||
## Resource and lifecycle
|
||
|
||
A monitor has an immutable UUID, name, HTTP(S) URL, per-check timeout, timestamps, and current status (`unknown`, `up`, or `down`). Status also records the most recent check time, HTTP status, latency, and a sanitized error. New and materially updated monitors are `unknown`. State is process-local and protected by one `asyncio.Lock`; it is lost at restart and is not shared between workers.
|
||
|
||
## HTTP API
|
||
|
||
| Method | Path | Meaning |
|
||
|---|---|---|
|
||
| POST | `/monitors` | Create; `201` |
|
||
| GET | `/monitors` | List |
|
||
| GET | `/monitors/{id}` | Retrieve |
|
||
| PATCH | `/monitors/{id}` | Partial update |
|
||
| DELETE | `/monitors/{id}` | Delete; `204` |
|
||
| POST | `/monitors/{id}/check` | Run a check and atomically store its result |
|
||
| GET | `/monitors/{id}/status` | Current status only |
|
||
| GET | `/health/live` | Process liveness |
|
||
| GET | `/health/ready` | Readiness for traffic |
|
||
|
||
A final 200–399 response is `up`; other responses and transport failures are `down`. A transport failure is a completed check and returns `200` with a down result. A policy-rejected target returns `400` after recording a sanitized down result. A monitor changed or deleted while its check is in flight produces `409`/`404`, preventing a stale result from overwriting newer state.
|
||
|
||
Errors use `{"error":{"code":"...","message":"..."}}`; request validation adds `details`. No authentication is provided.
|
||
|
||
## Outbound security and observability
|
||
|
||
Only HTTP(S), hostnames without credentials, and configured ports are accepted. Every initial and redirect target is resolved immediately before its request; all returned addresses must be globally routable. Loopback, private, link-local, multicast, reserved, and unspecified addresses are blocked. Redirects are followed manually up to a bounded limit. Timeouts and response-body reads are bounded (checks stream no body). Operators should still enforce egress policy at the network layer because application DNS checks cannot eliminate every DNS rebinding/TOCTOU risk.
|
||
|
||
Logs are one-line JSON. URLs are normalized to remove user info, query strings, and fragments; exception text and response bodies are never logged.
|
||
|
||
## Layout
|
||
|
||
`app/` contains configuration, models, locked storage, SSRF policy, checking, logging, and FastAPI composition. `tests/` exercises API and checker policy. Packaging is in `pyproject.toml`, `Dockerfile`, and `compose.yaml`; exact root `.gitignore` and `.dockerignore` files prevent local/build artifacts from entering source control or build context.
|