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:
80
README.md
80
README.md
@@ -1,71 +1,53 @@
|
||||
# Endpoint Monitor Service
|
||||
# Endpoint Monitor
|
||||
|
||||
A typed FastAPI service that stores endpoint monitors in concurrency-safe process memory and
|
||||
runs SSRF-aware on-demand HTTP checks.
|
||||
A typed, unauthenticated FastAPI service for process-local monitor CRUD and secure on-demand HTTP checks. See [SERVICE_DESIGN.md](SERVICE_DESIGN.md) for the complete contract and [VERIFICATION.md](VERIFICATION.md) for honest generation-time evidence.
|
||||
|
||||
## Quick start
|
||||
## Layout
|
||||
|
||||
- `app/main.py`: API composition and lifecycle
|
||||
- `app/models.py`, `app/store.py`: schemas and lock-protected memory
|
||||
- `app/security.py`, `app/checker.py`: SSRF policy, redirects, timing, HTTP
|
||||
- `tests/`: API, checker/security, store, and redaction tests
|
||||
|
||||
## Local development
|
||||
|
||||
Requires Python 3.12.
|
||||
|
||||
```sh
|
||||
```bash
|
||||
python -m venv .venv
|
||||
. .venv/bin/activate
|
||||
pip install -e '.[dev]'
|
||||
uvicorn app.main:app --reload
|
||||
```
|
||||
|
||||
OpenAPI is at `http://localhost:8000/docs`.
|
||||
|
||||
```sh
|
||||
curl -s -X POST http://localhost:8000/monitors \
|
||||
-H 'content-type: application/json' \
|
||||
-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
|
||||
```
|
||||
|
||||
See `docs/service-contract.md` for routes, schemas, status semantics, error behavior, security,
|
||||
and architecture.
|
||||
|
||||
## Configuration
|
||||
|
||||
All settings are validated at startup and use the `MONITOR_` prefix:
|
||||
|
||||
| Variable | Default | Constraint |
|
||||
|---|---:|---|
|
||||
| `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
|
||||
|
||||
```sh
|
||||
ruff format --check .
|
||||
ruff check .
|
||||
mypy app
|
||||
pytest
|
||||
./scripts/verify.sh
|
||||
uvicorn app.main:app --reload
|
||||
```
|
||||
|
||||
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.
|
||||
Create and check a monitor:
|
||||
|
||||
## Containers
|
||||
```bash
|
||||
curl -sS -X POST http://localhost:8000/v1/monitors \
|
||||
-H 'content-type: application/json' \
|
||||
-d '{"name":"example","url":"https://example.com/"}'
|
||||
curl -sS -X POST http://localhost:8000/v1/monitors/UUID_FROM_ABOVE/check
|
||||
curl -sS http://localhost:8000/v1/monitors/UUID_FROM_ABOVE/status
|
||||
```
|
||||
|
||||
```sh
|
||||
OpenAPI is at `/docs` and `/openapi.json`.
|
||||
|
||||
## Configuration
|
||||
|
||||
All settings are validated at startup. Variables are `MONITOR_REQUEST_TIMEOUT_SECONDS` (default 5, max 30), `MONITOR_CONNECT_TIMEOUT_SECONDS` (default 2, max 10), `MONITOR_MAX_REDIRECTS` (default 5, max 10), and `MONITOR_LOG_LEVEL` (default `INFO`).
|
||||
|
||||
## Container
|
||||
|
||||
```bash
|
||||
docker build -t endpoint-monitor .
|
||||
docker run --rm -p 8000:8000 endpoint-monitor
|
||||
# or
|
||||
docker compose up --build
|
||||
curl -f http://localhost:8000/readyz
|
||||
```
|
||||
|
||||
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.
|
||||
The image runs as a non-root user and intentionally starts one worker. Memory is lost on restart, is not shared between workers/containers, and has no durability or horizontal consistency. The API has no authentication and should not be exposed directly to untrusted networks. DNS re-resolution by the underlying HTTP transport leaves a DNS-rebinding window after policy validation; use network-level egress controls in production.
|
||||
|
||||
Reference in New Issue
Block a user