checker: split monolithic rule into per-concern rules
Replace the single matrix_federation rule with individual rules for federation status, well-known delegation, SRV records, connection reachability, TLS checks, and homeserver version, so the UI surfaces a clear checklist. Drop the incorrect well-known/server_name equality check: m.server points at the delegated federation endpoint, which is intentionally distinct from server_name.
This commit is contained in:
parent
2bd0ae99bd
commit
e4b6481d32
8 changed files with 346 additions and 60 deletions
107
checker/rule.go
107
checker/rule.go
|
|
@ -3,79 +3,62 @@ package checker
|
|||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
sdk "git.happydns.org/checker-sdk-go/checker"
|
||||
)
|
||||
|
||||
// Rule returns a new matrix federation check rule.
|
||||
// Rules returns the full list of CheckRules exposed by the Matrix checker.
|
||||
// Each rule covers a single concern so the UI can show a clear checklist
|
||||
// rather than a single monolithic pass/fail line.
|
||||
func Rules() []sdk.CheckRule {
|
||||
return []sdk.CheckRule{
|
||||
&federationOKRule{},
|
||||
&wellKnownRule{},
|
||||
&srvRecordsRule{},
|
||||
&connectionReachableRule{},
|
||||
&tlsChecksRule{},
|
||||
&versionRule{},
|
||||
}
|
||||
}
|
||||
|
||||
// Rule returns the aggregate federation rule.
|
||||
//
|
||||
// Deprecated: prefer Rules() which exposes every concern individually. Kept
|
||||
// for backward compatibility with callers that embed a single rule.
|
||||
func Rule() sdk.CheckRule {
|
||||
return &matrixRule{}
|
||||
return &federationOKRule{}
|
||||
}
|
||||
|
||||
type matrixRule struct{}
|
||||
|
||||
func (r *matrixRule) Name() string {
|
||||
return "matrix_federation"
|
||||
}
|
||||
|
||||
func (r *matrixRule) Description() string {
|
||||
return "Checks whether Matrix federation is working correctly"
|
||||
}
|
||||
|
||||
func (r *matrixRule) ValidateOptions(opts sdk.CheckerOptions) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *matrixRule) Evaluate(ctx context.Context, obs sdk.ObservationGetter, opts sdk.CheckerOptions) []sdk.CheckState {
|
||||
// loadMatrixData fetches the Matrix observation. On error returns a
|
||||
// CheckState the caller should emit to short-circuit its rule.
|
||||
func loadMatrixData(ctx context.Context, obs sdk.ObservationGetter) (*MatrixFederationData, *sdk.CheckState) {
|
||||
var data MatrixFederationData
|
||||
if err := obs.Get(ctx, ObservationKeyMatrix, &data); err != nil {
|
||||
return []sdk.CheckState{{
|
||||
return nil, &sdk.CheckState{
|
||||
Status: sdk.StatusError,
|
||||
Message: fmt.Sprintf("Failed to get Matrix federation data: %v", err),
|
||||
Code: "matrix_federation_error",
|
||||
}}
|
||||
}
|
||||
|
||||
domain, _ := opts["serviceDomain"].(string)
|
||||
domain = strings.TrimSuffix(domain, ".")
|
||||
|
||||
if data.FederationOK {
|
||||
version := strings.TrimSpace(data.Version.Name + " " + data.Version.Version)
|
||||
return []sdk.CheckState{{
|
||||
Status: sdk.StatusOK,
|
||||
Message: fmt.Sprintf("Running %s", version),
|
||||
Code: "matrix_federation_ok",
|
||||
Meta: map[string]any{
|
||||
"version": version,
|
||||
},
|
||||
}}
|
||||
}
|
||||
|
||||
var statusLine string
|
||||
|
||||
if data.DNSResult.SRVError != nil && data.WellKnownResult.Result != "" {
|
||||
statusLine = fmt.Sprintf("%s OR %s", data.DNSResult.SRVError.Message, data.WellKnownResult.Result)
|
||||
} else if len(data.ConnectionErrors) > 0 {
|
||||
var msg strings.Builder
|
||||
for srv, cerr := range data.ConnectionErrors {
|
||||
if msg.Len() > 0 {
|
||||
msg.WriteString("; ")
|
||||
}
|
||||
msg.WriteString(srv)
|
||||
msg.WriteString(": ")
|
||||
msg.WriteString(cerr.Message)
|
||||
Code: "matrix.observation_error",
|
||||
}
|
||||
statusLine = fmt.Sprintf("Connection errors: %s", msg.String())
|
||||
} else if data.WellKnownResult.Server != domain {
|
||||
statusLine = fmt.Sprintf("Bad homeserver_name: got %s, expected %s", data.WellKnownResult.Server, domain)
|
||||
} else {
|
||||
statusLine = fmt.Sprintf("Federation broken. Check https://federationtester.matrix.org/#%s", domain)
|
||||
}
|
||||
|
||||
return []sdk.CheckState{{
|
||||
Status: sdk.StatusCrit,
|
||||
Message: statusLine,
|
||||
Code: "matrix_federation_fail",
|
||||
}}
|
||||
return &data, nil
|
||||
}
|
||||
|
||||
func passState(code, message string) sdk.CheckState {
|
||||
return sdk.CheckState{Status: sdk.StatusOK, Message: message, Code: code}
|
||||
}
|
||||
|
||||
func infoState(code, message string) sdk.CheckState {
|
||||
return sdk.CheckState{Status: sdk.StatusInfo, Message: message, Code: code}
|
||||
}
|
||||
|
||||
func warnState(code, message string) sdk.CheckState {
|
||||
return sdk.CheckState{Status: sdk.StatusWarn, Message: message, Code: code}
|
||||
}
|
||||
|
||||
func critState(code, message string) sdk.CheckState {
|
||||
return sdk.CheckState{Status: sdk.StatusCrit, Message: message, Code: code}
|
||||
}
|
||||
|
||||
func unknownState(code, message string) sdk.CheckState {
|
||||
return sdk.CheckState{Status: sdk.StatusUnknown, Message: message, Code: code}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue