From 2f04639a52b9704e7f4a71a1db1802f22426fde5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rn=20Friedrich=20Dreyer?= Date: Tue, 24 Mar 2026 13:11:18 +0100 Subject: [PATCH] revisit checks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Jörn Friedrich Dreyer --- pkg/checks/checkgrpc.go | 23 +++++++++++----- pkg/checks/checkhttp.go | 27 +++++++++++-------- pkg/checks/checknats.go | 14 +++++----- pkg/checks/checktcp.go | 19 ++++++-------- pkg/handlers/checker.go | 32 ++++------------------- services/proxy/pkg/server/debug/server.go | 6 ++--- 6 files changed, 56 insertions(+), 65 deletions(-) diff --git a/pkg/checks/checkgrpc.go b/pkg/checks/checkgrpc.go index c67c6f7853..9e5e9e369c 100644 --- a/pkg/checks/checkgrpc.go +++ b/pkg/checks/checkgrpc.go @@ -6,22 +6,31 @@ import ( "github.com/opencloud-eu/opencloud/pkg/handlers" "google.golang.org/grpc" + "google.golang.org/grpc/connectivity" "google.golang.org/grpc/credentials/insecure" ) // NewGRPCCheck checks the reachability of a grpc server. func NewGRPCCheck(address string) func(context.Context) error { - return func(_ context.Context) error { - address, err := handlers.FailSaveAddress(address) - if err != nil { - return err + address, err := handlers.FailSaveAddress(address) + if err != nil { + return func(context.Context) error { + return fmt.Errorf("invalid address: %v", err) } + } - conn, err := grpc.NewClient(address, grpc.WithTransportCredentials(insecure.NewCredentials())) - if err != nil { + conn, err := grpc.NewClient(address, grpc.WithTransportCredentials(insecure.NewCredentials())) + if err != nil { + return func(context.Context) error { return fmt.Errorf("could not connect to grpc server: %v", err) } - _ = conn.Close() + } + + return func(ctx context.Context) error { + s := conn.GetState() + if s == connectivity.TransientFailure || s == connectivity.Shutdown { + return fmt.Errorf("grpc connection in bad state: %v", s) + } return nil } } diff --git a/pkg/checks/checkhttp.go b/pkg/checks/checkhttp.go index d40e272d9c..eed3cea535 100644 --- a/pkg/checks/checkhttp.go +++ b/pkg/checks/checkhttp.go @@ -12,20 +12,25 @@ import ( // NewHTTPCheck checks the reachability of a http server. func NewHTTPCheck(url string) func(context.Context) error { - return func(_ context.Context) error { - url, err := handlers.FailSaveAddress(url) - if err != nil { - return err - } - - if !strings.HasPrefix(url, "http://") && !strings.HasPrefix(url, "https://") { - url = "http://" + url + url, err := handlers.FailSaveAddress(url) + if err != nil { + return func(context.Context) error { + return fmt.Errorf("invalid url: %v", err) } + } + if !strings.HasPrefix(url, "http://") && !strings.HasPrefix(url, "https://") { + url = "http://" + url + } - c := http.Client{ - Timeout: 3 * time.Second, + c := &http.Client{ + Timeout: 3 * time.Second, + } + return func(ctx context.Context) error { + req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil) + if err != nil { + return err } - resp, err := c.Get(url) + resp, err := c.Do(req) if err != nil { return fmt.Errorf("could not connect to http server: %v", err) } diff --git a/pkg/checks/checknats.go b/pkg/checks/checknats.go index 0424942c5f..718aaec88e 100644 --- a/pkg/checks/checknats.go +++ b/pkg/checks/checknats.go @@ -9,14 +9,16 @@ import ( // NewNatsCheck checks the reachability of a nats server. func NewNatsCheck(natsCluster string, options ...nats.Option) func(context.Context) error { - return func(_ context.Context) error { - n, err := nats.Connect(natsCluster, options...) - if err != nil { + conn, err := nats.Connect(natsCluster, options...) + if err != nil { + return func(context.Context) error { return fmt.Errorf("could not connect to nats server: %v", err) } - defer n.Close() - if n.Status() != nats.CONNECTED { - return fmt.Errorf("nats server not connected") + } + + return func(_ context.Context) error { + if conn.Status() != nats.CONNECTED { + return fmt.Errorf("nats server not connected: %v", conn.Status()) } return nil } diff --git a/pkg/checks/checktcp.go b/pkg/checks/checktcp.go index 1bff842bd3..2808ed4e22 100644 --- a/pkg/checks/checktcp.go +++ b/pkg/checks/checktcp.go @@ -10,22 +10,19 @@ import ( // NewTCPCheck returns a check that connects to a given tcp endpoint. func NewTCPCheck(address string) func(context.Context) error { - return func(_ context.Context) error { - address, err := handlers.FailSaveAddress(address) - if err != nil { - return err - } - - conn, err := net.DialTimeout("tcp", address, 3*time.Second) - if err != nil { + address, err := handlers.FailSaveAddress(address) + if err != nil { + return func(context.Context) error { return err } + } - err = conn.Close() + return func(ctx context.Context) error { + d := net.Dialer{Timeout: 3 * time.Second} + conn, err := d.DialContext(ctx, "tcp", address) if err != nil { return err } - - return nil + return conn.Close() } } diff --git a/pkg/handlers/checker.go b/pkg/handlers/checker.go index b7319ffbf0..15415dfda8 100644 --- a/pkg/handlers/checker.go +++ b/pkg/handlers/checker.go @@ -5,7 +5,6 @@ import ( "fmt" "io" "maps" - "net" "net/http" "strings" @@ -117,32 +116,11 @@ func (h *CheckHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { // FailSaveAddress replaces wildcard addresses with the outbound IP. func FailSaveAddress(address string) (string, error) { - if strings.Contains(address, "0.0.0.0") || strings.Contains(address, "::") { - outboundIp, err := getOutBoundIP() - if err != nil { - return "", err - } - address = strings.Replace(address, "0.0.0.0", outboundIp, 1) - address = strings.Replace(address, "::", "["+outboundIp+"]", 1) - address = strings.Replace(address, "[::]", "["+outboundIp+"]", 1) + if strings.Contains(address, "0.0.0.0") { + return strings.Replace(address, "0.0.0.0", "localhost", 1), nil } - return address, nil -} - -// getOutBoundIP returns the outbound IP address. -func getOutBoundIP() (string, error) { - interfacesAddresses, err := net.InterfaceAddrs() - if err != nil { - return "", err - } - - for _, address := range interfacesAddresses { - if ipNet, ok := address.(*net.IPNet); ok && !ipNet.IP.IsLoopback() { - if ipNet.IP.To4() != nil { - return ipNet.IP.String(), nil - } - } + if strings.Contains(address, "::") { + return strings.Replace(strings.Replace(address, "[::]", "localhost", 1), "::", "localhost", 1), nil } - - return "", fmt.Errorf("no IP found") + return address, nil } diff --git a/services/proxy/pkg/server/debug/server.go b/services/proxy/pkg/server/debug/server.go index 2a76c506d4..01bc43ec41 100644 --- a/services/proxy/pkg/server/debug/server.go +++ b/services/proxy/pkg/server/debug/server.go @@ -18,11 +18,11 @@ func Server(opts ...Option) (*http.Server, error) { options := newOptions(opts...) healthHandlerConfiguration := handlers.NewCheckHandlerConfiguration(). - WithLogger(options.Logger). - WithCheck("web reachability", checks.NewHTTPCheck(options.Config.HTTP.Addr)) + WithLogger(options.Logger) readyHandlerConfiguration := healthHandlerConfiguration. - WithCheck("nats reachability", checks.NewNatsCheck(options.Config.Events.Endpoint)) + WithCheck("nats reachability", checks.NewNatsCheck(options.Config.Events.Endpoint)). + WithCheck("web reachability", checks.NewHTTPCheck(options.Config.HTTP.Addr)) var configDumpFunc http.HandlerFunc = configDump(options.Config) return debug.NewService(