52 lines
1.3 KiB
Go
52 lines
1.3 KiB
Go
// Copyright (c) Tailscale Inc & AUTHORS
|
|
// SPDX-License-Identifier: BSD-3-Clause
|
|
|
|
//go:build linux
|
|
|
|
package main
|
|
|
|
import (
|
|
"log"
|
|
"net"
|
|
"net/http"
|
|
"sync"
|
|
)
|
|
|
|
// healthz is a simple health check server, if enabled it returns 200 OK if
|
|
// this tailscale node currently has at least one tailnet IP address else
|
|
// returns 503.
|
|
type healthz struct {
|
|
sync.Mutex
|
|
hasAddrs bool
|
|
}
|
|
|
|
func (h *healthz) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|
h.Lock()
|
|
defer h.Unlock()
|
|
if h.hasAddrs {
|
|
w.Write([]byte("ok"))
|
|
} else {
|
|
http.Error(w, "node currently has no tailscale IPs", http.StatusInternalServerError)
|
|
}
|
|
}
|
|
|
|
// runHealthz runs a simple HTTP health endpoint on /healthz, listening on the
|
|
// provided address. A containerized tailscale instance is considered healthy if
|
|
// it has at least one tailnet IP address.
|
|
func runHealthz(addr string, h *healthz) {
|
|
lis, err := net.Listen("tcp", addr)
|
|
if err != nil {
|
|
log.Fatalf("error listening on the provided health endpoint address %q: %v", addr, err)
|
|
}
|
|
mux := http.NewServeMux()
|
|
mux.Handle("/healthz", h)
|
|
log.Printf("Running healthcheck endpoint at %s/healthz", addr)
|
|
hs := &http.Server{Handler: mux}
|
|
|
|
go func() {
|
|
if err := hs.Serve(lis); err != nil {
|
|
log.Fatalf("failed running health endpoint: %v", err)
|
|
}
|
|
}()
|
|
}
|