decomposer: generate deliverable files for Define the service contract and project architecture for the FastAPI endpoint monitoring service.; Implement the typed monitor CRUD API and concurrency-safe in-memory state according to the service design.; Implement secure on-demand endpoint checks with status updates, latency measurement, robust error handling, and redacted structured logs.; Add operational API endpoints and environment-driven runtime configuration to the monitoring service.; Create automated tests for the monitoring service.; Package the service with Docker and developer documentation.; Validate the complete project.
Some checks failed
ci / validate (push) Has been cancelled
Some checks failed
ci / validate (push) Has been cancelled
This commit is contained in:
84
README.md
84
README.md
@@ -1,77 +1,71 @@
|
||||
# Endpoint Monitor API
|
||||
# Endpoint Monitor Service
|
||||
|
||||
A typed FastAPI service for process-local endpoint monitors and secure, on-demand HTTP checks.
|
||||
A typed FastAPI service that stores endpoint monitors in concurrency-safe process memory and
|
||||
runs SSRF-aware on-demand HTTP checks.
|
||||
|
||||
## Features
|
||||
## Quick start
|
||||
|
||||
- CRUD monitor resources and current-status retrieval
|
||||
- bounded HTTP/HTTPS checks with latency measurement
|
||||
- SSRF protection on every DNS lookup and redirect hop
|
||||
- JSON logs with URL credentials, query strings, and fragments redacted
|
||||
- health/readiness endpoints and validated `MONITOR_` environment settings
|
||||
- concurrency-safe in-memory state
|
||||
Requires Python 3.12.
|
||||
|
||||
## Layout
|
||||
|
||||
- `docs/service-contract.md` — API and architecture contract
|
||||
- `app/` — settings, models, store, checker, logging, and FastAPI routes
|
||||
- `tests/` — API and checker/security tests using mocked outbound HTTP
|
||||
- `docs/verification.md` — validation commands and expected evidence
|
||||
|
||||
## Run locally
|
||||
|
||||
```bash
|
||||
python -m venv .venv && . .venv/bin/activate
|
||||
```sh
|
||||
python -m venv .venv
|
||||
. .venv/bin/activate
|
||||
pip install -e '.[dev]'
|
||||
uvicorn app.main:app --reload
|
||||
```
|
||||
|
||||
Open `http://127.0.0.1:8000/docs`.
|
||||
OpenAPI is at `http://localhost:8000/docs`.
|
||||
|
||||
## Examples
|
||||
|
||||
```bash
|
||||
curl -sS -X POST http://127.0.0.1:8000/monitors \
|
||||
```sh
|
||||
curl -s -X POST http://localhost:8000/monitors \
|
||||
-H 'content-type: application/json' \
|
||||
-d '{"name":"example","url":"https://example.com/"}'
|
||||
curl -sS http://127.0.0.1:8000/monitors
|
||||
curl -sS -X POST http://127.0.0.1:8000/monitors/MONITOR_ID/check
|
||||
curl -sS http://127.0.0.1:8000/monitors/MONITOR_ID/status
|
||||
curl -sS http://127.0.0.1:8000/healthz
|
||||
curl -sS http://127.0.0.1:8000/readyz
|
||||
-d '{"name":"Example","url":"https://example.com","expected_status":200}'
|
||||
curl -s -X POST http://localhost:8000/monitors/UUID/check
|
||||
curl -s http://localhost:8000/monitors/UUID/status
|
||||
```
|
||||
|
||||
PUT accepts the same body as POST and replaces the mutable fields. DELETE returns 204. Unknown IDs return the JSON error envelope documented in the service contract.
|
||||
See `docs/service-contract.md` for routes, schemas, status semantics, error behavior, security,
|
||||
and architecture.
|
||||
|
||||
## Configuration
|
||||
|
||||
All settings are validated at startup.
|
||||
All settings are validated at startup and use the `MONITOR_` prefix:
|
||||
|
||||
| Variable | Default | Meaning |
|
||||
| Variable | Default | Constraint |
|
||||
|---|---:|---|
|
||||
| `MONITOR_REQUEST_TIMEOUT_SECONDS` | `5.0` | Total check timeout, range 0.1–30 |
|
||||
| `MONITOR_MAX_REDIRECTS` | `5` | Manual redirect limit, range 0–10 |
|
||||
| `MONITOR_MAX_MONITORS` | `1000` | Process-local monitor capacity |
|
||||
| `MONITOR_LOG_LEVEL` | `INFO` | Python log level |
|
||||
|
||||
Private, loopback, link-local, multicast, reserved, and otherwise non-global resolved addresses are rejected. URL userinfo is rejected. Only HTTP and HTTPS are accepted.
|
||||
| `MONITOR_HOST` | `0.0.0.0` | bind host |
|
||||
| `MONITOR_PORT` | `8000` | 1..65535 |
|
||||
| `MONITOR_LOG_LEVEL` | `INFO` | logging level |
|
||||
| `MONITOR_CHECK_TIMEOUT_SECONDS` | `5` | >0, <=30 |
|
||||
| `MONITOR_MAX_REDIRECTS` | `3` | 0..10 |
|
||||
|
||||
## Quality checks
|
||||
|
||||
```bash
|
||||
```sh
|
||||
ruff format --check .
|
||||
ruff check .
|
||||
mypy app
|
||||
pytest -q
|
||||
pytest
|
||||
./scripts/verify.sh
|
||||
```
|
||||
|
||||
## Container
|
||||
Tests use mocked HTTP transports and cover typed CRUD/error behavior, concurrent state changes,
|
||||
status persistence, timeout-safe checking, DNS/private-address blocking, redirect revalidation,
|
||||
and log redaction. No test sends outbound traffic.
|
||||
|
||||
```bash
|
||||
## Containers
|
||||
|
||||
```sh
|
||||
docker build -t endpoint-monitor .
|
||||
docker run --rm -p 8000:8000 endpoint-monitor
|
||||
# or
|
||||
docker compose up --build
|
||||
```
|
||||
|
||||
The container has a non-root user and one worker intentionally. State is process-local and is lost on restart; multiple workers/replicas do not share monitors. Use a durable shared database before horizontal scaling or production persistence is required.
|
||||
The image runs as an unprivileged user, uses one worker, and has a health check.
|
||||
|
||||
## Important limitation
|
||||
|
||||
Storage is deliberately process-local and ephemeral. Restarting loses every monitor. Multiple
|
||||
workers or replicas each have independent data and readiness only establishes that the local
|
||||
process can serve requests. Use one worker; add a shared database before scaling horizontally.
|
||||
|
||||
Reference in New Issue
Block a user