package checker import ( "context" "fmt" "sort" sdk "git.happydns.org/checker-sdk-go/checker" ) // Rules returns the full list of CheckRules exposed by the TLS checker. // Each rule covers a single concern (reachability, handshake, chain, hostname, // expiry, TLS version, STARTTLS advertisement, cipher suite, …) so the UI can // surface a passing-list rather than a single aggregated code. func Rules() []sdk.CheckRule { return []sdk.CheckRule{ &endpointsDiscoveredRule{}, &reachabilityRule{}, &tlsHandshakeRule{}, &starttlsAdvertisedRule{}, &starttlsSupportedRule{}, &peerCertificateRule{}, &chainValidityRule{}, &hostnameMatchRule{}, &expiryRule{}, &tlsVersionRule{}, &cipherSuiteRule{}, } } // loadData fetches the TLS observation. On error, returns a single error // state the caller should emit. func loadData(ctx context.Context, obs sdk.ObservationGetter) (*TLSData, *sdk.CheckState) { var data TLSData if err := obs.Get(ctx, ObservationKeyTLSProbes, &data); err != nil { return nil, &sdk.CheckState{ Status: sdk.StatusError, Message: fmt.Sprintf("failed to load tls_probes observation: %v", err), Code: "tls.observation_error", } } return &data, nil } // sortedRefs returns the probe refs in deterministic order. Rules iterate // this sorted list so CheckState output is stable. func sortedRefs(data *TLSData) []string { refs := make([]string, 0, len(data.Probes)) for ref := range data.Probes { refs = append(refs, ref) } sort.Strings(refs) return refs } // subjectOf formats the UI-facing subject for a single probe. func subjectOf(p TLSProbe) string { return fmt.Sprintf("%s://%s", p.Type, p.Endpoint) } // metaOf returns a compact meta map to attach to a CheckState. func metaOf(p TLSProbe) map[string]any { m := map[string]any{ "type": p.Type, "host": p.Host, "port": p.Port, "sni": p.SNI, } if p.TLSVersion != "" { m["tls_version"] = p.TLSVersion } return m } // passState / infoState / unknownState helpers. func passState(code, message string) sdk.CheckState { return sdk.CheckState{Status: sdk.StatusOK, Code: code, Message: message} } func unknownState(code, message string) sdk.CheckState { return sdk.CheckState{Status: sdk.StatusUnknown, Code: code, Message: message} } // emptyCaseState returns a single state describing "no probes to evaluate". // Rules call this when len(data.Probes) == 0 to avoid returning an empty // slice (see CheckRule.Evaluate contract). func emptyCaseState(code string) sdk.CheckState { return unknownState(code, "No TLS endpoints have been discovered for this target yet.") }