Files
headscale/cmd/gen-openapi/main.go
T
Kristoffer Dalby c9bbb5bdec api/v1: add code-first Huma implementation of the v1 API
Reimplement the v1 API as a code-first Huma service in hscontrol/api/v1,
a thin adapter over the state layer. Huma emits the OpenAPI 3.1 document
(openapi/v1/headscale.yaml) from the Go operation and type definitions;
cmd/gen-openapi writes it and the 3.0.3 downgrade the client is generated
from. Responses reproduce the protojson wire contract (string-encoded
64-bit IDs, all fields emitted, RFC3339/null timestamps); errors map to
the correct HTTP status (404/400/409, 500 for server faults) via mapError.

Serve it on the chi router at /api/v1 behind the existing API-key
middleware, and point /swagger at the emitted spec.
2026-06-19 15:21:00 +02:00

51 lines
1.2 KiB
Go

// Command gen-openapi emits the Headscale v1 OpenAPI document from the
// authoritative Huma definitions in hscontrol/api/v1. The server also serves the
// spec live at /openapi.yaml; this tool emits it on demand, and with -downgrade
// the 3.0.3 form used to generate the client. The output is not committed.
//
// Usage:
//
// go run ./cmd/gen-openapi # write the 3.1 spec to openapi/v1/headscale.yaml
// go run ./cmd/gen-openapi -downgrade <path> # write the 3.0.3 downgrade (for client gen)
package main
import (
"log"
"os"
"path/filepath"
apiv1 "github.com/juanfont/headscale/hscontrol/api/v1"
)
// outPath is relative to the repository root.
const outPath = "openapi/v1/headscale.yaml"
func main() {
if len(os.Args) == 3 && os.Args[1] == "-downgrade" {
writeSpec(os.Args[2], apiv1.Spec30)
return
}
writeSpec(outPath, apiv1.Spec)
}
func writeSpec(path string, gen func() ([]byte, error)) {
spec, err := gen()
if err != nil {
log.Fatalf("generating OpenAPI spec: %v", err)
}
err = os.MkdirAll(filepath.Dir(path), 0o755)
if err != nil {
log.Fatalf("creating output directory: %v", err)
}
err = os.WriteFile(path, spec, 0o600)
if err != nil {
log.Fatalf("writing %s: %v", path, err)
}
log.Printf("wrote %s", path)
}