[grade=B urn:ump:wokpmecjfauc7jvnxyyyu4fq3zkkvwge455a5mxlmi3pdzkfdw3a] feat(DC-171): DNS provider plug-in parity phase 1 — BIND 9 AXFR listing + capability honesty
RFC2136/BIND9 adapter gains listRecords via AXFR zone transfer (dig with the same TSIG identity as nsupdate; temp 0600 keyfile, always cleaned up; transfer-denial errors carry the exact allow-transfer fix). TSIG fields validated (name charset, HMAC algorithm whitelist, base64 secret) before keyfile interpolation. Capability honesty at every surface: GET /dns/records 501s name the active provider + its supported capabilities + zone-transfer pointer; MCP dashcaddy_list_dns attaches actionable guidance for AI clients; setup wizard shows per-provider capability hints at choice time (parity-pinned by tests against the adapters). Also fixed a latent rfc2136 bug: this._log instance property shadowed the prototype logging method — every nsupdate call threw since the DC-170-era refactor. CHANGELOG stale 'protocol-impossible' DC-171 entry superseded. Judge: grade B, zero blockers (urn:ump:wokpmecjfauc7jvnxyyyu4fq3zkkvwge455a5mxlmi3pdzkfdw3a). Polish applied post-grade: stale changelog entry corrected, TSIG field validation + 4 extra failure-path tests (exact dig argv, ENOENT install hint, non-denial failure passthrough, hostile-field rejection), dns-records 501 test strengthened to pin provider name + capabilities. Suite: backend 174 suites / 3754 tests, frontend 68/68.
This commit is contained in:
10 files changed
+704
-238
No files matched your search
@@ -73,7 +73,16 @@ module.exports = function({
|
||||
const zone = req.query.zone || (siteConfig.tld ? String(siteConfig.tld).replace(/^\./, '') : '');
|
||||
const provider = dns.getActiveProvider ? dns.getActiveProvider() : null;
|
||||
if (!provider || (provider.supportsCapability && !provider.supportsCapability('list-records'))) {
|
||||
return errorResponse(res, 'Record listing not supported by current DNS provider', 501);
|
||||
// DC-171: actionable guidance — name the provider and what it CAN do
|
||||
const providerId = dns.getProviderId ? dns.getProviderId() : 'unknown';
|
||||
const caps = provider && provider.getCapabilities ? provider.getCapabilities() : [];
|
||||
return errorResponse(res,
|
||||
`Record listing is not supported by the active DNS provider (${providerId}). `
|
||||
+ `Supported capabilities: ${caps.join(', ') || 'none'}. `
|
||||
+ `Push-only protocols (RFC 2136/BIND dynamic updates) can create, delete and `
|
||||
+ `resolve records but cannot enumerate them server-side — list them with the `
|
||||
+ `server's own tools (e.g. dig, the provider's web UI) or enable zone transfers.`,
|
||||
501);
|
||||
}
|
||||
const result = await provider.listRecords({ zone });
|
||||
const records = Array.isArray(result) ? result : (result && result.records) || [];
|
||||
|
||||
Reference in new issue
Block a user