diff options
| -rw-r--r-- | .dockerignore | 6 | ||||
| -rw-r--r-- | Dockerfile | 20 | ||||
| -rw-r--r-- | PLAN.md | 14 | ||||
| -rw-r--r-- | README.md | 86 | ||||
| -rw-r--r-- | internal/version/version.go | 2 |
5 files changed, 127 insertions, 1 deletions
diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..ddc0bae --- /dev/null +++ b/.dockerignore @@ -0,0 +1,6 @@ +.git +.cursor +goprecords +tmp +*.db +*.log diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..6158745 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,20 @@ +FROM golang:1.21-alpine AS build +WORKDIR /src + +RUN apk add --no-cache ca-certificates + +COPY go.mod go.sum ./ +RUN go mod download + +COPY . . +RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -trimpath -ldflags="-s -w" -o /out/goprecords ./cmd/goprecords + +FROM alpine:3.20 +RUN apk add --no-cache ca-certificates + +WORKDIR /app +COPY --from=build /out/goprecords /usr/local/bin/goprecords + +EXPOSE 8080 + +ENTRYPOINT ["/usr/local/bin/goprecords"] @@ -0,0 +1,14 @@ +# mage goprecords a microservice + +* Should run as a daemon, e.g. `goprecords --daemon` +* Should have a configurable database path to a local directory +* Local database is simply the input dir of the current goprecords CLI tool +* Introduce an API to generate the available output formats, also include a HTML output format. All should be configurable using a query-parameter to the API. +* Introduce an API to let clients upload new uprecords. see example database at /home/paul/git/uprecords/stats so every client should be able to upload 5 different files, HOSTNAME.{txt,cur.txt,records,os.txt,cpuinfo.txt}. +* Use token-based authentication (e.g. API keys or JWT) for upload endpoints. +* Upload should simply work using a curl CLI command given the auth is provided in the HTTP header. +* have a way to manage different auth keys per client. not via API but via a local database and a `goprecords --create-client-key HOSTNAME`. + + + + @@ -79,6 +79,92 @@ goprecords --daemon -stats-dir="$HOME/git/uprecords/stats" -listen=":8080" - **`stats-order`**: comma-separated **`Category:Metric`** list when **`all`** is true - **`PUT /upload/{HOSTNAME}/{kind}`** — Writes one file under the stats directory; **`204`** on success. The **`HOSTNAME`** path segment must match the hostname the client key was issued for when auth is enforced. +**HTTP API reference with curl** + +- **`GET /health`** + - Purpose: basic liveness probe. + - Success: `200 OK`, body `ok`. + - Example: + +```bash +curl -i "http://127.0.0.1:8080/health" +``` + +- **`GET /livez`** + - Purpose: Kubernetes-style liveness probe (same semantics as `/health`). + - Success: `200 OK`, body `ok`. + - Example: + +```bash +curl -i "http://127.0.0.1:8080/livez" +``` + +- **`GET /readyz`** + - Purpose: readiness probe (verifies required directories are readable and writable). + - Success: `200 OK`, body `ok`. + - Not ready: `503 Service Unavailable`. + - Example: + +```bash +curl -i "http://127.0.0.1:8080/readyz" +``` + +- **`GET /report`** + - Purpose: generate reports from the daemon stats directory. + - Method: only `GET` (`405` for other methods). + - Main query parameters: + - `category`: `Host`, `Kernel`, `KernelMajor`, `KernelName` + - `metric`: `Boots`, `Uptime`, `Score`, `Downtime`, `Lifespan` + - `output-format`: `Plaintext`, `Markdown`, `Gemtext`, `HTML` + - `limit`: integer (default `20`) + - `all`, `include-kernel`: booleans + - `stats-order`: comma-separated `Category:Metric` + - aliases: `Category`, `Metric`, `OutputFormat` + - Content types: + - `Plaintext`/`Markdown`: `text/plain; charset=utf-8` + - `Gemtext`: `text/gemini; charset=utf-8` + - `HTML`: `text/html; charset=utf-8` + - Examples: + +```bash +curl -fsS "http://127.0.0.1:8080/report?category=Host&metric=Uptime&limit=10&output-format=Plaintext" +curl -fsS "http://127.0.0.1:8080/report?category=Kernel&metric=Boots&output-format=Gemtext" +curl -fsS "http://127.0.0.1:8080/report?Category=Host&Metric=Score&OutputFormat=HTML&limit=5" +curl -fsS "http://127.0.0.1:8080/report?all=true&include-kernel=true&output-format=Markdown" +``` + +- **`PUT /upload/{HOSTNAME}/{kind}`** + - Purpose: upload host files into the daemon stats directory. + - Method: only `PUT` (`405` for other methods). + - Success: `204 No Content`. + - Auth behavior: + - If no keys exist in auth DB: upload is accepted without `Authorization`. + - If one or more keys exist: requires `Authorization: Bearer <token>`. + - Missing/invalid header: `401 Unauthorized` (with `WWW-Authenticate: Bearer ...`). + - Wrong host/token pair: `403 Forbidden`. + - Examples: + +```bash +# without auth (works only when no client keys exist in auth DB) +curl -i -X PUT --data-binary @./myhost.records \ + "http://127.0.0.1:8080/upload/myhost/records" + +# with auth (required when keys exist) +TOKEN="..." # from --create-client-key +curl -i -X PUT --data-binary @./myhost.records \ + -H "Authorization: Bearer $TOKEN" \ + "http://127.0.0.1:8080/upload/myhost/records" +``` + +- **Create upload client key (CLI companion flow)** + - This is not an HTTP API endpoint. Key creation is intentionally CLI-only. + - Command examples: + +```bash +goprecords --create-client-key myhost -stats-dir="$HOME/git/uprecords/stats" +goprecords --create-client-key otherbox -auth-db=/var/lib/goprecords/goprecords-auth.db +``` + **`GET /report` examples** ```bash diff --git a/internal/version/version.go b/internal/version/version.go index db740bd..c2e9b9f 100644 --- a/internal/version/version.go +++ b/internal/version/version.go @@ -1,4 +1,4 @@ package version // Tag is the application release version. -const Tag = "0.2.4" +const Tag = "0.3.0" |
