mirror of
https://github.com/opencloud-eu/opencloud.git
synced 2026-05-24 16:41:35 -04:00
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
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,
|
||||
}
|
||||
return func(ctx context.Context) error {
|
||||
req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if !strings.HasPrefix(url, "http://") && !strings.HasPrefix(url, "https://") {
|
||||
url = "http://" + url
|
||||
}
|
||||
|
||||
c := http.Client{
|
||||
Timeout: 3 * time.Second,
|
||||
}
|
||||
resp, err := c.Get(url)
|
||||
resp, err := c.Do(req)
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not connect to http server: %v", err)
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
address, err := handlers.FailSaveAddress(address)
|
||||
if err != nil {
|
||||
return func(context.Context) error {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
conn, err := net.DialTimeout("tcp", address, 3*time.Second)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = conn.Close()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
return conn.Close()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
if strings.Contains(address, "::") {
|
||||
return strings.Replace(strings.Replace(address, "[::]", "localhost", 1), "::", "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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return "", fmt.Errorf("no IP found")
|
||||
}
|
||||
|
||||
@@ -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(
|
||||
|
||||
Reference in New Issue
Block a user