12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667 |
- package metrics
- import (
- "encoding/json"
- "fmt"
- "net/http"
- "github.com/google/uuid"
- conn "github.com/cloudflare/cloudflared/connection"
- "github.com/cloudflare/cloudflared/tunnelstate"
- )
- // ReadyServer serves HTTP 200 if the tunnel can serve traffic. Intended for k8s readiness checks.
- type ReadyServer struct {
- clientID uuid.UUID
- tracker *tunnelstate.ConnTracker
- }
- // NewReadyServer initializes a ReadyServer and starts listening for dis/connection events.
- func NewReadyServer(
- clientID uuid.UUID,
- tracker *tunnelstate.ConnTracker,
- ) *ReadyServer {
- return &ReadyServer{
- clientID,
- tracker,
- }
- }
- func (rs *ReadyServer) OnTunnelEvent(c conn.Event) {
- rs.tracker.OnTunnelEvent(c)
- }
- type body struct {
- Status int `json:"status"`
- ReadyConnections uint `json:"readyConnections"`
- ConnectorID uuid.UUID `json:"connectorId"`
- }
- // ServeHTTP responds with HTTP 200 if the tunnel is connected to the edge.
- func (rs *ReadyServer) ServeHTTP(w http.ResponseWriter, r *http.Request) {
- statusCode, readyConnections := rs.makeResponse()
- w.WriteHeader(statusCode)
- body := body{
- Status: statusCode,
- ReadyConnections: readyConnections,
- ConnectorID: rs.clientID,
- }
- msg, err := json.Marshal(body)
- if err != nil {
- _, _ = fmt.Fprintf(w, `{"error": "%s"}`, err)
- }
- _, _ = w.Write(msg)
- }
- // This is the bulk of the logic for ServeHTTP, broken into its own pure function
- // to make unit testing easy.
- func (rs *ReadyServer) makeResponse() (statusCode int, readyConnections uint) {
- readyConnections = rs.tracker.CountActiveConns()
- if readyConnections > 0 {
- return http.StatusOK, readyConnections
- } else {
- return http.StatusServiceUnavailable, readyConnections
- }
- }
|