v0.8.0-rc
Pre-release
Pre-release
This release cycle was made possible thanks to the financial support of NLnet, whose funding enabled the development of the new checker subsystem, its integrations and the observability work that ships in this version.
Highlights
- New checker subsystem. happyDomain can now schedule, run and track recurring checks against your domains, zones and services. The subsystem ships with its own scheduler, execution history, retention policy, per-user quotas, rule engine, HTML/JSON/metrics reports, and a full frontend experience (list, configuration, schedule, rules, executions and charts).
- Pluggable checkers. External checkers can be distributed as
.soplugins and loaded at startup through the-plugins-directoryflag, or delegated to a remote HTTP endpoint via the new observation transport layer. Seven new checkers are bundled: ICMP ping, Zonemaster, Matrix federation, domain expiration, NS security restrictions, domain contact consistency, and domain lock status. - RDAP / WHOIS domain information. A new
/whoispage and a zone sidebar modal display registrar, important dates, nameservers and status for any domain, backed by a newDomainInfoUsecaseand/api/domaininfo/:domainendpoint. - Prometheus observability. happyDomain now exposes a
/metricsendpoint on the admin socket, covering HTTP traffic, the checker scheduler, DNS provider adapters, storage operations, business entity counts and build info. The admin dashboard has been rewritten on top of this feed.
Features
Checker subsystem
- Foundational domain model for checkers:
CheckTarget,CheckPlan,Execution,CheckEvaluation,CheckerDefinition,CheckerOptions,ObservationSnapshotand associated interfaces. - Observation collection engine with concurrent per-key gathering and a
WorstStatusAggregatorfor combining rule evaluation results. - Checker and observation provider registries, wrapping
checker-sdk-go. - Full business logic: scope-based option resolution, validation and auto-fill (
CheckerOptionsUsecase); CRUD for user scheduling configurations (CheckPlanUsecase); aggregated status queries and history (CheckStatusUsecase); full execution pipeline (CheckerEngine). - Background
Schedulerwith min-heap queue, worker pool, jitter and auto-discovery; incremental updates on domain/zone create, delete, import and publish, via a narrowSchedulerDomainNotifierinterface. - Persistence layer:
CheckPlanStorage,CheckerOptionsStorage,CheckEvaluationStorage,ExecutionStorage,ObservationSnapshotStorageandSchedulerStateStorage, with KV-based implementations for LevelDB / Oracle NoSQL / InMemory backends, tidy methods for every checker entity and secondary index cleanup. - HTTP API controllers and scoped routes at the user, domain and service levels, plus admin routes for checker configuration and scheduler management.
- External plugin loader:
.sofiles discovered in-plugins-directoryare opened viaplugin.Open,NewCheckerPluginis looked up fromchecker-sdk-go, and the returned definition and observation provider are registered in the global registries. - Remote observation transport: when an admin configures an
endpointoption, the engine substitutes the local provider with anHTTPObservationProviderthat POSTs to{endpoint}/collect. - Observation data pipeline stores
json.RawMessageend-to-end, eliminating double-serialization and enabling cross-checker reuse of cached observations. NoOverridefield on checker options prevents more specific scopes from overriding values locked at a higher scope (typically admin), with defense-in-depth stripping on Set/Add, merge-time preservation and frontend filtering.- Map-based option validation (
ValidateMapValues) for required fields, allowed choices and type checking.
Bundled checkers
- ICMP ping — RTT and packet-loss metrics.
- Zonemaster — full Zonemaster report rendering.
- Matrix federation — federation readiness checks.
- Domain expiration — monitors the registry expiration date.
- NS security restrictions — probes authoritative nameservers for AXFR/IXFR acceptance, recursion, RFC 8482 ANY handling and authoritative status, via the external
checker-ns-restrictionsplugin. - Domain contact consistency — compares RDAP/WHOIS registrant, admin and tech contacts against user-specified expected values, with redaction detection for privacy-protected domains.
- Domain lock status — reports registry lock flags.
Retention, quotas & safety
- Tiered
RetentionPolicy:- 0–1 day: every execution
- 1–7 days: one report per hour
- 7–30 days: 2 per day per (checker, target)
- 30–D/2 days: 1 per week per (checker, target)
- D/2–D days: 1 per month per (checker, target)
- beyond D: dropped
- Janitor goroutine enforces the retention policy on every
CheckPlan, honours per-user overrides and caches user lookups per
sweep. Default interval 6h; runs once at startup. UserQuotamodel for admin-controlled per-user limits and flags (max checks per day, retention days, inactivity pause days,
scheduling kill switch). Exposed through the admin user PUT endpoint and a new editor card under/users/[uid]; not reachable from user-facing settings.- Scheduler
UserGaterpauses scheduling for paused users and for users whoseLastSeenis older than their effective inactivity horizon, with 5 min caching and anInvalidatehook. MaxChecksPerDayenforcement with interval-aware throttling: short-interval jobs are skipped first once 80 % of the daily budget is consumed, so rare / important checks are not starved by frequent pings. Planned executions that breach the quota are surfaced with a newExecutionRateLimitedstatus; manual API triggers bypass the quota.
Frontend for checkers
- Checker list, configuration, schedule and rules pages.
- Execution list, detail, results and rules pages with sidebar view switching (HTML report / JSON / metrics / rules).
- Chart.js-based metrics chart on execution lists and per-execution detail pages.
- HTML report rendering via the new
CheckerHTMLReporterinterface; the Zonemaster provider ships with collapsible accordions and severity badges. - "Run check" modal with option overrides and rule selection.
- Domain-scoped and service-scoped check routes.
- Admin pages for checker configuration and scheduler management.
- Checks status summary badge in the zone viewer
PageHeader; worst check status badge on the domain list, with dynamic colour and icon. - Zone and service-level checkers visible on the domain checks page, with scheduling / rules hidden for non-domain checkers configured from the domain context.
- English translations for all checker UI strings.
RDAP / WHOIS
- New
domaininfopackage with RDAP and WHOIS getters. DomainInfoUsecaseand/api/domaininfo/:domainroute, also mounted under the domain scope./whoisfrontend page and zone sidebar modal.ContactInfoextracted from both RDAP and WHOIS responses; the WHOIS observation provider exposes contact data for reuse by thedomain_contactchecker.- Per-IP rate limiter on
/api/domaininfo/:domain(10 req/min, usinggin-rate-limit) to mitigate enumeration and proxy abuse on this unauthenticated endpoint.
Prometheus metrics
- New
internal/metricspackage with all metric variables registered viapromauto, a Gin HTTP middleware recording request count, duration and in-flight gauge (usingc.FullPath()to keep label cardinality bounded), and anInstrumentedStoragewrapper recording operation counts and durations for every entity. /metricsendpoint served viapromhttpon the admin socket.- App wiring: HTTP middleware on the public router, storage wrapped after initialisation, build info metric populated from
main()with the real version string;prometheus/client_golangpromoted to a direct dependency. - Storage stats collector exposes live gauges queried at each scrape:
happydomain_registered_users_total,happydomain_domains_total,happydomain_zones_total,happydomain_providers_total. - DNS provider adapter (
DNSControlAdapterNSProvider) recordshappydomain_provider_api_calls_totalandhappydomain_provider_api_duration_secondsforGetZoneRecords,GetZoneCorrections,CreateDomainandListZones. - Check scheduler tracks queue depth, active worker count, check execution duration per checker, and check result status counters.
- Checker metrics endpoints negotiate format via the
Acceptheader:application/jsonreturns the JSON array, anything else returns the Prometheus text exposition format. - Metrics endpoints skip incomplete / planned executions via a new
doneExecutionfilter onListExecutionsBy*, so only fully evaluated runs contribute to the Prometheus output. - Admin dashboard rewritten on top of
/metrics: a single scrape every 15 s replaces the three REST count calls, featured cards surface queue / workers / in-flight / RSS / version / uptime, and the full counter set + Go runtime stats are hidden under a "Show more metrics" collapse. - New link to the Prometheus metrics URL on the checker configuration page.
- Prometheus export documentation added under
docs/.
Improvements
- Tidy, scheduler and auto-fill now consider the WIP zone (
ZoneHistory[0]) in addition to the latest published zone, so services being drafted are not cleaned up or ignored and auto-fill resolves from the right zone for the best user experience. - JWT middleware now silently hands off to the session store when a bearer token is a valid session ID (base32, 103 chars) instead of logging a misleading "bad JWT claims" error.
IsValidSessionIDis exported, and the session ID length is derived from a constant tied to the key size in the usecase package. - Tests covering success, error and panic paths of
DNSControlAdapterNSProvidermetrics instrumentation forGetZoneRecords,GetZoneCorrections,CreateDomainandListZones.
Bug fixes
- Checker subsystem used the wrong zone snapshot.
ZoneHistoryis ordered[WIP, newest-published, …, oldest-published], but the tidy, scheduler and auto-fill code readZoneHistory[len-1](the oldest zone). This caused the scheduler to enumerate services from an outdated snapshot, tidy to check service existence against stale data, and auto-fill to resolve from the wrong zone. Fixed to useZoneHistory[1](the latest published zone).
Funding
This project is funded through NGI Zero Core, a fund established by NLnet with financial support from the European Commission's Next Generation Internet program. Learn more at the NLnet project page.
