From e873a31b21049bd80ce83823f0081a69c08ae557 Mon Sep 17 00:00:00 2001
From: Eric Chiang <eric.chiang@coreos.com>
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
-- 
GitLab