• DcRouter v32.4.0
    Release / build-and-release (push) Successful in 21m9s
    Stable

    jkunz released this 2026-09-25 14:52:19 +00:00 | 20 commits to main since this release

    2026-09-25 - 32.4.0

    Features

    • Serve gateway-client hostname records and exact certificates, the @serve.zone/interfaces 32.21.0 contracts syncGatewayClientDnsRecord, getGatewayClientCertificate and releaseGatewayClientCertificate, and advertise them as dns.clientRecords and certificates.exactIssuance. A gateway client can now hold an exact hostname without a gateway route: one A or AAAA record at an address inside its new allowedDnsRecordAddresses policy field, and one certificate for exactly that name, which Cloudly needs for its cluster relay names. Only gateway-client credentials can call them, with the syncDnsRecords, requestCertificates and readCertificates capabilities, for hostnames inside the client's hostnamePatterns. A hostname has one holder: a testing reservation, an enabled gateway-client route, another client or app, or an address record dcrouter does not own is a conflict, and dcrouter never overwrites or adopts such a record. The route DNS reconciler in turn answers record-conflict for a hostname an ownership holds, also through a certificate alone. Records are managed as gateway-client-hostname under the route reconciler's DNS exclusion. Certificates need a zone with verified authority and are issued by SmartAcme's exact-identifier DNS-01 path in a namespace per client and app; a request answers pending while the issuance runs. A request for a hostname nobody holds yet first synchronizes a provider zone and is refused as hostname-conflict when the name carries an address record dcrouter does not own, or answers issuance-unavailable (retryable) when the synchronization fails; polls for a held hostname synchronize nothing. Releasing a certificate retires its stored material, and a sweep at start and every minute removes the records, certificates and claims of deleted clients, of hostnames outside the client's patterns and of addresses outside its allowance. The allowance is set through provisionGatewayClientCredential, createGatewayClient and updateGatewayClient, stored canonically, and left out of the policy digest while it is empty, so existing credentials keep matching. The exact-certificate issuance now takes its SmartAcme namespace from the caller, and testing grants keep theirs. @serve.zone/interfaces moves from 32.0.0 to 32.21.0 in the lockfile (^32.0.0 → ^32.21.0), which brings @push.rocks/smartlog 4.0.0 as its dependency. test/test.gateway-client-hostname.node.ts covers the record lifecycle, the conflicts in both directions, certificate issuance, release and the sweep against a real database and DNS manager, and the handlers' credential, pattern and capability checks.
    • Show and edit a gateway client's allowedDnsRecordAddresses in the Ops UI under Access > Gateway Clients: a DNS addresses column, a field in the create dialog and the row action Edit DNS Addresses. Both dialogs judge the comma separated list with @serve.zone/interfaces' validateGatewayAllowedDnsRecordAddresses, which the web bundle now imports, keep the dialog open with the reason when it or dcrouter refuses the value, and close only on success. The create dialog previously closed before the request and ignored a refusal, and updateGatewayClientAction ignored an unsuccessful answer; it now records dcrouter's message as the view's error. Changing the allowance through an admin update raises the client's policy generation like any policy change, so its credentials must be provisioned again. test/test.gateway-clients.chromium.ts renders the view and drives the edit dialog through a refused value, a refused update and a saved one.
    • Refuse a testing grant, on request and on approval, for a hostname a gateway-client hostname ownership holds, with ownership_conflict. The ownership is looked up by hostname under the DNS exclusion its writers take, so one that holds only a certificate, with no DNS record, is refused too. test/test.testing-access.node.ts covers the certificate-only case.

    Maintenance

    • Make test/test.email-domain-creation-progress.node.ts "domain observation switches from list discovery to id polling" independent of the wall clock; it failed on every run, also on v32.3.2. The test gave observeNewEmailDomain a 100 ms deadline with 1 ms polls and asserted two list and two id reads. tsx, which runs the test, scans its disk cache synchronously once per process (131,641 entries in the shared cache on the build host) and blocked the event loop for about 110 ms during the first 1 ms wait, so the deadline expired after one list read. observeNewEmailDomain now takes an optional now clock for its deadline (default Date.now), and the test passes a frozen one, so the reads alone decide the result and tstest's timeout still bounds a hang. The module's behaviour with the default clock is unchanged.
    Downloads