Add /healthz endpoint via mcdsl/health

Database ping health check at /healthz, no auth required. Seal state
is still reported via the existing /v1/status endpoint.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-03-26 14:18:09 -07:00
parent c5dcb63165
commit d308db8598
4 changed files with 11 additions and 4 deletions

View File

@@ -88,7 +88,7 @@ func runServer(cmd *cobra.Command, args []string) error {
engineRegistry.RegisterFactory(engine.EngineTypeTransit, transit.NewTransitEngine) engineRegistry.RegisterFactory(engine.EngineTypeTransit, transit.NewTransitEngine)
engineRegistry.RegisterFactory(engine.EngineTypeUser, user.NewUserEngine) engineRegistry.RegisterFactory(engine.EngineTypeUser, user.NewUserEngine)
srv := server.New(cfg, sealMgr, authenticator, policyEngine, engineRegistry, auditLog, logger, version) srv := server.New(cfg, database, sealMgr, authenticator, policyEngine, engineRegistry, auditLog, logger, version)
grpcSrv := grpcserver.New(cfg, sealMgr, authenticator, policyEngine, engineRegistry, auditLog, logger) grpcSrv := grpcserver.New(cfg, sealMgr, authenticator, policyEngine, engineRegistry, auditLog, logger)
ctx, stop := signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM) ctx, stop := signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM)

View File

@@ -11,6 +11,7 @@ import (
"git.wntrmute.dev/kyle/mcdsl/health"
"git.wntrmute.dev/kyle/metacrypt/internal/audit" "git.wntrmute.dev/kyle/metacrypt/internal/audit"
"git.wntrmute.dev/kyle/metacrypt/internal/auth" "git.wntrmute.dev/kyle/metacrypt/internal/auth"
"git.wntrmute.dev/kyle/metacrypt/internal/barrier" "git.wntrmute.dev/kyle/metacrypt/internal/barrier"
@@ -23,6 +24,9 @@ import (
) )
func (s *Server) registerRoutes(r chi.Router) { func (s *Server) registerRoutes(r chi.Router) {
// Health check (database ping, no auth required).
r.Get("/healthz", health.Handler(s.database))
// REST API routes — web UI served by metacrypt-web. // REST API routes — web UI served by metacrypt-web.
r.Get("/v1/status", s.handleStatus) r.Get("/v1/status", s.handleStatus)
r.Post("/v1/init", s.handleInit) r.Post("/v1/init", s.handleInit)

View File

@@ -3,6 +3,7 @@ package server
import ( import (
"context" "context"
"database/sql"
"log/slog" "log/slog"
"sync" "sync"
@@ -21,6 +22,7 @@ import (
// Server is the Metacrypt HTTP server. // Server is the Metacrypt HTTP server.
type Server struct { type Server struct {
cfg *config.Config cfg *config.Config
database *sql.DB
seal *seal.Manager seal *seal.Manager
auth *auth.Authenticator auth *auth.Authenticator
policy *policy.Engine policy *policy.Engine
@@ -35,10 +37,11 @@ type Server struct {
} }
// New creates a new server. // New creates a new server.
func New(cfg *config.Config, sealMgr *seal.Manager, authenticator *auth.Authenticator, func New(cfg *config.Config, database *sql.DB, sealMgr *seal.Manager, authenticator *auth.Authenticator,
policyEngine *policy.Engine, engineRegistry *engine.Registry, auditLog *audit.Logger, logger *slog.Logger, version string) *Server { policyEngine *policy.Engine, engineRegistry *engine.Registry, auditLog *audit.Logger, logger *slog.Logger, version string) *Server {
s := &Server{ s := &Server{
cfg: cfg, cfg: cfg,
database: database,
seal: sealMgr, seal: sealMgr,
auth: authenticator, auth: authenticator,
policy: policyEngine, policy: policyEngine,

View File

@@ -65,7 +65,7 @@ func setupTestServer(t *testing.T) (*Server, *seal.Manager, chi.Router) {
} }
logger := slog.Default() logger := slog.Default()
srv := New(cfg, sealMgr, authenticator, policyEngine, engineRegistry, nil, logger, "test") srv := New(cfg, database, sealMgr, authenticator, policyEngine, engineRegistry, nil, logger, "test")
r := chi.NewRouter() r := chi.NewRouter()
srv.registerRoutes(r) srv.registerRoutes(r)