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
63 lines
2.6 KiB
Markdown
63 lines
2.6 KiB
Markdown
# Phase 6: DNS Sync & Reconciliation
|
|
|
|
**Status:** ⬜ Not Started
|
|
**Parent plan:** [PLAN.md](./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/sync` endpoint
|
|
- 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.go` and 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 endpoints
|
|
- `internal/api/router.go` — register new routes
|
|
- `internal/store/dns_records.go` — add helper queries (list consumers with FQDNs)
|
|
- `web/src/lib/api.ts` — add syncDnsRecords(), deleteDnsRecord() functions
|
|
- `web/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)
|
|
|
|
## Handoff to Next Phase
|
|
<!-- Filled in after completion -->
|