// This file is part of the happyDomain (R) project. // Copyright (c) 2020-2026 happyDomain // Authors: Pierre-Olivier Mercier, et al. package checker import ( "context" "fmt" sdk "git.happydns.org/checker-sdk-go/checker" ) // reachabilityRule reports per-IP reachability for one scheme. type reachabilityRule struct { scheme string // "http" or "https" code string } func (r *reachabilityRule) Name() string { return r.code } func (r *reachabilityRule) Description() string { return fmt.Sprintf("Verifies that every probed IP accepts a %s connection on the standard port.", r.scheme) } func (r *reachabilityRule) Evaluate(ctx context.Context, obs sdk.ObservationGetter, _ sdk.CheckerOptions) []sdk.CheckState { data, errSt := loadHTTPData(ctx, obs) if errSt != nil { return []sdk.CheckState{*errSt} } probes := probesByScheme(data.Probes, r.scheme) if len(probes) == 0 { return []sdk.CheckState{unknownState(r.code+".no_probes", "No probes were attempted.")} } var states []sdk.CheckState for _, p := range probes { switch { case !p.TCPConnected: states = append(states, sdk.CheckState{ Status: sdk.StatusCrit, Code: r.code + ".unreachable", Subject: p.Address, Message: fmt.Sprintf("Cannot reach %s://%s on %s: %s", r.scheme, p.Host, p.Address, p.Error), }) case p.StatusCode == 0: states = append(states, sdk.CheckState{ Status: sdk.StatusCrit, Code: r.code + ".no_response", Subject: p.Address, Message: fmt.Sprintf("TCP open but no HTTP response from %s: %s", p.Address, p.Error), }) case p.StatusCode >= 500: states = append(states, sdk.CheckState{ Status: sdk.StatusWarn, Code: r.code + ".server_error", Subject: p.Address, Message: fmt.Sprintf("%s returned %d", p.Address, p.StatusCode), }) } } if len(states) == 0 { return []sdk.CheckState{passState(r.code+".ok", fmt.Sprintf("All %s probes responded successfully.", r.scheme))} } return states }