Initial commit
This commit is contained in:
commit
19f8f764c9
25 changed files with 3732 additions and 0 deletions
109
checker/rule.go
Normal file
109
checker/rule.go
Normal file
|
|
@ -0,0 +1,109 @@
|
|||
package checker
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
sdk "git.happydns.org/checker-sdk-go/checker"
|
||||
)
|
||||
|
||||
// issue is a rule-internal description of a failed test. Rules return a
|
||||
// slice of issues from their check func; Evaluate converts them to
|
||||
// sdk.CheckState.
|
||||
type issue struct {
|
||||
Severity sdk.Status // StatusInfo / StatusWarn / StatusCrit
|
||||
Message string
|
||||
Hint string // remediation hint; surfaced as Meta["hint"]
|
||||
Subject string // optional; overrides default data.QueriedOwner
|
||||
}
|
||||
|
||||
// ruleFunc consumes the facts + runtime options and returns zero or more
|
||||
// issues. No issues means the test passed.
|
||||
type ruleFunc func(d *EmailKeyData, opts sdk.CheckerOptions) []issue
|
||||
|
||||
// rule is a data-driven CheckRule. All per-test rules share this type;
|
||||
// only name / description / applicable kinds / options / check differ.
|
||||
type rule struct {
|
||||
name string
|
||||
description string
|
||||
okMessage string // message for StatusOK returns
|
||||
kinds []string // applicable kinds; empty = both
|
||||
options sdk.CheckerOptionsDocumentation // per-rule options
|
||||
check ruleFunc
|
||||
}
|
||||
|
||||
func (r *rule) Name() string { return r.name }
|
||||
func (r *rule) Description() string { return r.description }
|
||||
func (r *rule) Options() sdk.CheckerOptionsDocumentation { return r.options }
|
||||
|
||||
func (r *rule) Evaluate(ctx context.Context, obs sdk.ObservationGetter, opts sdk.CheckerOptions) []sdk.CheckState {
|
||||
var data EmailKeyData
|
||||
if err := obs.Get(ctx, ObservationKey, &data); err != nil {
|
||||
return []sdk.CheckState{{
|
||||
Status: sdk.StatusError,
|
||||
Message: fmt.Sprintf("Failed to read observation %q: %v", ObservationKey, err),
|
||||
Code: "openpgpkey_observation_error",
|
||||
}}
|
||||
}
|
||||
|
||||
if len(r.kinds) > 0 && !containsString(r.kinds, data.Kind) {
|
||||
return []sdk.CheckState{{
|
||||
Status: sdk.StatusUnknown,
|
||||
Message: fmt.Sprintf("Not applicable for %s records.", data.Kind),
|
||||
Code: r.name,
|
||||
Subject: data.QueriedOwner,
|
||||
}}
|
||||
}
|
||||
|
||||
issues := r.check(&data, opts)
|
||||
if len(issues) == 0 {
|
||||
msg := r.okMessage
|
||||
if msg == "" {
|
||||
msg = "Check passed."
|
||||
}
|
||||
return []sdk.CheckState{{
|
||||
Status: sdk.StatusOK,
|
||||
Message: msg,
|
||||
Code: r.name,
|
||||
Subject: data.QueriedOwner,
|
||||
}}
|
||||
}
|
||||
|
||||
states := make([]sdk.CheckState, 0, len(issues))
|
||||
for _, iss := range issues {
|
||||
subject := iss.Subject
|
||||
if subject == "" {
|
||||
subject = data.QueriedOwner
|
||||
}
|
||||
var meta map[string]any
|
||||
if iss.Hint != "" {
|
||||
meta = map[string]any{"hint": iss.Hint}
|
||||
}
|
||||
states = append(states, sdk.CheckState{
|
||||
Status: iss.Severity,
|
||||
Message: iss.Message,
|
||||
Code: r.name,
|
||||
Subject: subject,
|
||||
Meta: meta,
|
||||
})
|
||||
}
|
||||
return states
|
||||
}
|
||||
|
||||
// Rules returns the full set of per-test rules for this checker.
|
||||
func Rules() []sdk.CheckRule {
|
||||
out := make([]sdk.CheckRule, len(allRules))
|
||||
for i := range allRules {
|
||||
out[i] = allRules[i]
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
func containsString(hay []string, needle string) bool {
|
||||
for _, v := range hay {
|
||||
if v == needle {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue