readiness.go 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. package metrics
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. "net/http"
  6. "github.com/google/uuid"
  7. conn "github.com/cloudflare/cloudflared/connection"
  8. "github.com/cloudflare/cloudflared/tunnelstate"
  9. )
  10. // ReadyServer serves HTTP 200 if the tunnel can serve traffic. Intended for k8s readiness checks.
  11. type ReadyServer struct {
  12. clientID uuid.UUID
  13. tracker *tunnelstate.ConnTracker
  14. }
  15. // NewReadyServer initializes a ReadyServer and starts listening for dis/connection events.
  16. func NewReadyServer(
  17. clientID uuid.UUID,
  18. tracker *tunnelstate.ConnTracker,
  19. ) *ReadyServer {
  20. return &ReadyServer{
  21. clientID,
  22. tracker,
  23. }
  24. }
  25. func (rs *ReadyServer) OnTunnelEvent(c conn.Event) {
  26. rs.tracker.OnTunnelEvent(c)
  27. }
  28. type body struct {
  29. Status int `json:"status"`
  30. ReadyConnections uint `json:"readyConnections"`
  31. ConnectorID uuid.UUID `json:"connectorId"`
  32. }
  33. // ServeHTTP responds with HTTP 200 if the tunnel is connected to the edge.
  34. func (rs *ReadyServer) ServeHTTP(w http.ResponseWriter, r *http.Request) {
  35. statusCode, readyConnections := rs.makeResponse()
  36. w.WriteHeader(statusCode)
  37. body := body{
  38. Status: statusCode,
  39. ReadyConnections: readyConnections,
  40. ConnectorID: rs.clientID,
  41. }
  42. msg, err := json.Marshal(body)
  43. if err != nil {
  44. _, _ = fmt.Fprintf(w, `{"error": "%s"}`, err)
  45. }
  46. _, _ = w.Write(msg)
  47. }
  48. // This is the bulk of the logic for ServeHTTP, broken into its own pure function
  49. // to make unit testing easy.
  50. func (rs *ReadyServer) makeResponse() (statusCode int, readyConnections uint) {
  51. readyConnections = rs.tracker.CountActiveConns()
  52. if readyConnections > 0 {
  53. return http.StatusOK, readyConnections
  54. } else {
  55. return http.StatusServiceUnavailable, readyConnections
  56. }
  57. }