From e873a31b21049bd80ce83823f0081a69c08ae557 Mon Sep 17 00:00:00 2001 From: Eric Chiang Date: Tue, 4 Oct 2016 16:45:52 -0700 Subject: [PATCH] server: add health check endpoint --- server/handlers.go | 30 ++++++++++++++++++++++++++++++ server/server.go | 1 + 2 files changed, 31 insertions(+) diff --git a/server/handlers.go b/server/handlers.go index ef3e9af5..40621adc 100644 --- a/server/handlers.go +++ b/server/handlers.go @@ -20,6 +20,36 @@ import ( "github.com/coreos/dex/storage" ) +func (s *Server) handleHealth(w http.ResponseWriter, r *http.Request) { + start := s.now() + err := func() error { + // Instead of trying to introspect health, just try to use the underlying storage. + a := storage.AuthRequest{ + ID: storage.NewID(), + ClientID: storage.NewID(), + + // Set a short expiry so if the delete fails this will be cleaned up quickly by garbage collection. + Expiry: s.now().Add(time.Minute), + } + + if err := s.storage.CreateAuthRequest(a); err != nil { + return fmt.Errorf("create auth request: %v", err) + } + if err := s.storage.DeleteAuthRequest(a.ID); err != nil { + return fmt.Errorf("delete auth request: %v", err) + } + return nil + }() + + t := s.now().Sub(start) + if err != nil { + log.Printf("Storage health check failed: %v", err) + http.Error(w, "Health check failed", http.StatusInternalServerError) + return + } + fmt.Fprintf(w, "Health check passed in %s", t) +} + func (s *Server) handlePublicKeys(w http.ResponseWriter, r *http.Request) { // TODO(ericchiang): Cache this. keys, err := s.storage.GetKeys() diff --git a/server/server.go b/server/server.go index 2e3c00af..6eb16b33 100644 --- a/server/server.go +++ b/server/server.go @@ -159,6 +159,7 @@ func newServer(c Config, rotationStrategy rotationStrategy) (*Server, error) { handleFunc("/auth/{connector}", s.handleConnectorLogin) handleFunc("/callback/{connector}", s.handleConnectorCallback) handleFunc("/approval", s.handleApproval) + handleFunc("/healthz", s.handleHealth) s.mux = r return s, nil