From 84f8c42f3aa976a32595ee3cc89792bb18d85676 Mon Sep 17 00:00:00 2001 From: Chris Guidry Date: Wed, 4 Mar 2026 20:59:58 -0500 Subject: [PATCH] Add /_health endpoint for k8s liveness/readiness probes Returns 204 No Content, keeping it simple so the kubelet doesn't need to parse anything. Co-Authored-By: Claude Opus 4.6 --- server.go | 5 +++++ server_test.go | 19 +++++++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/server.go b/server.go index a7308a2..9f8afc5 100644 --- a/server.go +++ b/server.go @@ -27,6 +27,11 @@ func NewServer(broker *Broker, config *atomic.Pointer[Configuration]) http.Handl func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) { setCORSHeaders(w) + if r.Method == "GET" && r.URL.Path == "/_health" { + w.WriteHeader(http.StatusNoContent) + return + } + switch r.Method { case "OPTIONS": w.WriteHeader(http.StatusNoContent) diff --git a/server_test.go b/server_test.go index b285d11..b3418e9 100644 --- a/server_test.go +++ b/server_test.go @@ -22,6 +22,25 @@ func newTestServer(cfg *Configuration) (*httptest.Server, *Broker) { return httptest.NewServer(handler), broker } +func TestServer_healthEndpoint(t *testing.T) { + ts, _ := newTestServer(nil) + defer ts.Close() + + resp, err := http.Get(ts.URL + "/_health") + if err != nil { + t.Fatalf("GET /_health failed: %v", err) + } + defer resp.Body.Close() + if resp.StatusCode != http.StatusNoContent { + t.Errorf("expected 204, got %d", resp.StatusCode) + } + buf := make([]byte, 1) + n, _ := resp.Body.Read(buf) + if n != 0 { + t.Errorf("expected empty body, got %d bytes", n) + } +} + func TestServer_postPublishesEvent(t *testing.T) { ts, _ := newTestServer(nil) defer ts.Close() -- 2.51.2