checker-http/checker/rules_reachability.go

62 lines
1.9 KiB
Go

// 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"
)
func init() {
RegisterRule(&reachabilityRule{scheme: "http", code: "http.tcp_reachable"})
RegisterRule(&reachabilityRule{scheme: "https", code: "https.tcp_reachable"})
}
// 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}
}
okMsg := fmt.Sprintf("All %s probes responded successfully.", r.scheme)
return EvalAggregateByScheme(data, r.scheme, r.code, okMsg, func(p HTTPProbe, emit func(sdk.CheckState)) {
switch {
case !p.TCPConnected:
emit(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:
emit(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:
emit(sdk.CheckState{
Status: sdk.StatusWarn,
Code: r.code + ".server_error",
Subject: p.Address,
Message: fmt.Sprintf("%s returned %d", p.Address, p.StatusCode),
})
}
})
}