c730cfaa45
Add flexible DNS management to Docker Watcher. By default, wildcard DNS is assumed (current behavior). When disabled, users can configure a Cloudflare DNS provider with API token and zone selection. DNS A records are automatically created/updated/deleted in sync with proxy consumers (deployed instances and standalone proxies). - Settings: wildcard_dns toggle, dns_provider, cloudflare credentials - Cloudflare client: Provider interface with EnsureRecord/DeleteRecord/ListRecords - DNS lifecycle hooks in deployer and proxy manager (best-effort) - Settings UI: DNS config section with provider picker, zone selector, test button - DNS Records page at /dns with filtering, sync status, reconciliation - Records visible in both wildcard and managed modes - Cleanup on provider change: removes old records when switching modes
2.6 KiB
2.6 KiB
Phase 6: DNS Sync & Reconciliation
Status: ⬜ Not Started Parent plan: PLAN.md Domain: backend
Objective
Implement reconciliation logic that compares expected DNS records (from active consumers) with actual Cloudflare records, and provides a sync endpoint to fix discrepancies.
Tasks
- Task 1: Add
POST /api/dns/syncendpoint- Computes expected records from: active instances with proxy + standalone proxies
- Fetches actual records from Cloudflare via ListRecords
- Creates missing records (consumer exists, no CF record)
- Deletes orphaned records (CF record exists, no consumer) — only for records in dns_records table
- Updates dns_records table to reflect current state
- Returns sync report: created N, deleted N, already_synced N
- Task 2: Add helper to compute expected records
- Query all instances where npm_proxy_id > 0 and status = "running" → extract FQDN
- Query all standalone proxies → extract domain
- Return list of expected FQDNs
- Task 3: Add
DELETE /api/dns/records/{fqdn}endpoint- Manual deletion of a specific DNS record (for orphan cleanup)
- Calls provider.DeleteRecord + removes from dns_records
- Task 4: Wire sync endpoint in
internal/api/dns.goand router - Task 5: Add frontend sync button handler in DNS Records page
- Call POST /api/dns/sync
- Show sync report (toast or inline)
- Refresh records list after sync
Files to Modify/Create
internal/api/dns.go— add sync + delete endpointsinternal/api/router.go— register new routesinternal/store/dns_records.go— add helper queries (list consumers with FQDNs)web/src/lib/api.ts— add syncDnsRecords(), deleteDnsRecord() functionsweb/src/routes/dns/+page.svelte— wire sync button
Acceptance Criteria
- POST /api/dns/sync creates missing and removes orphaned records
- Sync report returned with counts
- Manual delete endpoint works for individual records
- Frontend sync button triggers reconciliation and refreshes view
- Only records tracked in dns_records table are candidates for orphan deletion (don't delete unrelated Cloudflare records)
Notes
- Safety: only delete Cloudflare records that are tracked in our dns_records table (never touch records we didn't create)
- Rate limiting: Cloudflare API has rate limits, batch operations where possible
- Expected records query needs to join instances + standalone_proxies with settings.domain
Review Checklist
- All tasks completed
- Code follows project conventions
- No unintended side effects
- Build passes
- Tests pass (new + existing)