chore: initial commit of Go API gateway
Baseline for the Kong replacement on api.riotpiao.com. Brings the working tree under version control for the first time: gateway source, the task board that drives the agent runs, test fixtures, and K8s manifests. Anchor the gateway ignore rule to the repo root. Unanchored, "gateway" also matched the cmd/gateway/ source directory, so the program entrypoint was excluded from every commit. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
This commit is contained in:
@@ -0,0 +1,104 @@
|
||||
# homelab-frontend
|
||||
|
||||
A Go API gateway for the homelab cluster. One capability per subdomain, one auth
|
||||
implementation, one routing table.
|
||||
|
||||
Replaces Kong OSS entirely — see
|
||||
[ADR-0001](docs/adr/ADR-0001-retire-kong-for-go-gateway.md) for why, and
|
||||
[docs/MIGRATION-kong.md](docs/MIGRATION-kong.md) for the cutover.
|
||||
|
||||
## Position in the stack
|
||||
|
||||
```
|
||||
browser / SDK ──▶ Cloudflare ──▶ ingress-nginx (TLS, edge)
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────┐
|
||||
│ homelab-frontend │
|
||||
│ routing · authn · budgets │
|
||||
└──────────────┬──────────────┘
|
||||
│
|
||||
/v1 /sqs /workflow /cluster
|
||||
│ │ │ │
|
||||
▼ ▼ ▼ ▼
|
||||
llm-serving kmsvc/Kafka temporal atlas
|
||||
(predictors) (sqs ns) (temporal ns) (riotpiao-backend)
|
||||
|
||||
└──── in-cluster Services ────┘
|
||||
```
|
||||
|
||||
ingress-nginx keeps TLS and the edge. The gateway owns everything after it.
|
||||
|
||||
Backend services are reached through the gateway rather than published
|
||||
individually — a single place for authentication, budgets, timeouts and
|
||||
observability, and a single hostname surface to reason about.
|
||||
|
||||
## Capability map
|
||||
|
||||
One host, one path prefix per capability.
|
||||
|
||||
| Prefix on `api.riotpiao.com` | Backs onto | Status |
|
||||
|---|---|---|
|
||||
| `/v1/*` | `llm-serving` predictors (vLLM, Ollama, TEI) | migrating off Kong |
|
||||
| `/sqs/*` | kmsvc management-service + Kafka/Strimzi (`sqs` ns) | future |
|
||||
| `/workflow/*` | Temporal (`temporal` ns) | future |
|
||||
| `/cluster/*` | atlas — cluster topology / Argo delivery (separate repo) | future |
|
||||
| `/db/*` | CloudNativePG, MinIO, monitoring/metrics reads | future |
|
||||
|
||||
`/v1/*` is reserved for the OpenAI-compatible surface. An SDK expects
|
||||
`/v1/chat/completions` at the base URL, so that prefix cannot be repurposed.
|
||||
|
||||
Paths rather than subdomains: one DNS record, one tunnel hostname, one Ingress.
|
||||
Promoting a prefix to its own subdomain later is additive and can run alongside the
|
||||
path — the reverse is not, because clients hardcode hostnames.
|
||||
|
||||
atlas lives in its own repo (`riotpiao-backend`) and keeps its own informers and
|
||||
RBAC. The gateway routes to it; it does not absorb it. Cluster-read permissions
|
||||
stay out of the public edge process.
|
||||
|
||||
## Design rules
|
||||
|
||||
1. **Standard protocol shapes.** `POST /v1/chat/completions` selects its model from
|
||||
the request body, like every OpenAI-compatible server. No path-per-model, no
|
||||
bespoke client configuration. Kong OSS could not do this; that limitation does
|
||||
not survive into the replacement.
|
||||
2. **Bearer tokens, validated against Authentik.** JWKS is fetched at runtime and
|
||||
cached, so key rotation needs no runbook and no pinned PEM.
|
||||
3. **Policy lives where the state is.** GPU slot semaphores, per-caller budgets,
|
||||
queue depth and disconnect propagation are application concerns. They belong
|
||||
here, not in a proxy plugin.
|
||||
4. **Streaming is first-class.** SSE and WebSocket pass through unbuffered, and a
|
||||
client disconnect cancels the upstream request rather than orphaning it.
|
||||
5. **The gateway holds no cluster credentials.** It proxies to services that do.
|
||||
|
||||
## Layout
|
||||
|
||||
```
|
||||
cmd/gateway/ entrypoint
|
||||
internal/
|
||||
auth/ Authentik OIDC, JWKS cache, service-account tokens
|
||||
llm/ model registry, body-based dispatch, upstream map
|
||||
queue/ sqs.riotpiao.com surface
|
||||
workflow/ workflow.riotpiao.com surface
|
||||
proxy/ reverse proxy, streaming, timeouts, disconnect propagation
|
||||
config/ upstream + route configuration
|
||||
observability/ Prometheus metrics, structured logging
|
||||
deploy/
|
||||
base/ Kubernetes manifests
|
||||
argocd/ Argo Application
|
||||
docs/adr/ architecture decision records
|
||||
tasks/ task board — see tasks/INDEX.md
|
||||
testdata/ fixtures for offline tests
|
||||
```
|
||||
|
||||
## Local development
|
||||
|
||||
The gateway must be runnable with no cluster, no kubeconfig and no credentials, so
|
||||
that changes can be verified in a closed loop before touching live traffic.
|
||||
Upstreams are configuration, so pointing them at local stubs is the whole
|
||||
mechanism. See [tasks/INDEX.md](tasks/INDEX.md).
|
||||
|
||||
## Status
|
||||
|
||||
Scaffolded 2026-08-19. Nothing is wired yet. Kong is still serving live traffic on
|
||||
`api.riotpiao.com`.
|
||||
Reference in New Issue
Block a user