checker-dnsviz/checker/rule.go

75 lines
1.8 KiB
Go

// SPDX-License-Identifier: MIT
package checker
import (
"context"
"fmt"
"sort"
"strings"
sdk "git.happydns.org/checker-sdk-go/checker"
)
// Rules returns the full rule set evaluated against a DNSVizData observation.
// Subject is the zone FQDN so a fault at the TLD is never silently merged with a leaf fault.
func Rules() []sdk.CheckRule {
return []sdk.CheckRule{
&overallStatusRule{},
&perZoneStatusRule{},
&zoneErrorsRule{},
&zoneWarningsRule{},
&commonFailuresRule{},
}
}
func loadData(ctx context.Context, obs sdk.ObservationGetter, code string) (*DNSVizData, []sdk.CheckState) {
var data DNSVizData
if err := obs.Get(ctx, ObservationKeyDNSViz, &data); err != nil {
return nil, []sdk.CheckState{{
Status: sdk.StatusError,
Code: code,
Message: fmt.Sprintf("Failed to load DNSViz observation: %v", err),
}}
}
return &data, nil
}
func orderedZones(data *DNSVizData) []string {
if len(data.Order) > 0 {
return data.Order
}
keys := make([]string, 0, len(data.Zones))
for k := range data.Zones {
keys = append(keys, k)
}
sort.Slice(keys, func(i, j int) bool {
return labelDepth(keys[i]) > labelDepth(keys[j])
})
return keys
}
func statusFromGrok(s string) sdk.Status {
switch strings.ToUpper(strings.TrimSpace(s)) {
case "SECURE":
return sdk.StatusOK
case "INSECURE":
// "INSECURE" means "no DNSSEC and no parent DS": informational, not
// a failure. Rules elsewhere can still flag a missing chain.
return sdk.StatusInfo
case "BOGUS":
return sdk.StatusCrit
case "INDETERMINATE":
return sdk.StatusWarn
case "NON_EXISTENT":
return sdk.StatusInfo
case "NOERROR":
// DNS-level OK with no DNSSEC chain status reported. The zone
// resolves but isn't signed (or grok didn't classify it).
return sdk.StatusInfo
case "":
return sdk.StatusUnknown
default:
return sdk.StatusUnknown
}
}