DB-configured DNS providers + OVH reverse DNS#157
Open
v0l wants to merge 4 commits into
Open
Conversation
Move DNS provider configuration out of static config.yaml into the database,
mirroring the router pattern, and add an OVH reverse-DNS provider.
- New `dns_server` table + model (`DnsServer`/`DnsServerKind`), base-trait CRUD,
and admin API at `/api/admin/v1/dns_servers` (`dns_server` permission resource).
- IP ranges gain `forward_dns_server_id`, `reverse_dns_server_id`, `forward_zone_id`
(alongside the existing `reverse_zone_id`) selecting the forward/reverse provider
+ zone per range.
- Generalize the `DnsServer` trait: zone/record ids modelled as a `DnsRef` enum
(`Implicit` | `Id(String)`) instead of stuffing the IP into a string; factory
`dns::get_dns_server(db, id)` dispatches on kind.
- New `ovh` DNS provider: reverse DNS via `POST/DELETE /ip/{ip}/reverse` (reverse
only). Shared OVH signing extracted to `crate::ovh` and reused by the router.
- `vm_network` resolves DNS servers per range from the DB; `Settings.dns` is now a
legacy migration-only field.
- Startup data migration imports the legacy Cloudflare config and OVH additional-IP
routers into `dns_server` rows, auto-maps reverse DNS on OVH-routed ranges, and
force-refreshes stale Cloudflare reverse records to real OVH PTRs (idempotent,
best-effort so a permission error never blocks startup).
- New `PatchIpRangeDns` job + `POST /api/admin/v1/ip_ranges/{id}/patch_dns` to
re-apply forward/reverse DNS for a whole range on demand.
Fixes #78
Add docs/agents/testing-db-backups.md describing how to safely restore a prod mariadb dump into an isolated DB and test branch migrations/startup against it: swap all hosts to the Dummy/mock kind, wipe user contact preferences, neutralise ENC: encrypted secrets, repoint external integrations to inert endpoints, seed the dummy-host state so VMs report running, and apply migrations. Linked from AGENTS.md.
Ran the full lnvps_api binary against a restored 1577-VM prod snapshot (Polar regtest LND + redis). It boots cleanly to "Listening on 0.0.0.0:8000" and serves HTTP 200; the vm_subscription backfill (1577 subs / 3429 payments, 0 errors), encryption re-encrypt, and the DNS data migration (OVH dns_server rows + reverse wiring on the OVH-routed ranges) all run. Key finding folded into the doc: read-only mode does NOT stop startup data migrations or the worker (expired-VM cleanup, DNS reverse backfill, arp_ref_fixer) from making real router/DNS API calls, so repointing all router URLs to an inert endpoint is mandatory. Expanded step 5 with the verified full-run procedure and an "expected output" section.
test_admin_create_ip_space_persists_company_id sent min_prefix_size=24 / max_prefix_size=32, which the pre-existing to_available_ip_space() validation rejects (requires min >= max; for a /24 RIPE block: min=/32, max=/24, matching dev_setup.sql). The endpoint returned 500 "min_prefix_size must be greater than or equal to max_prefix_size", so the test asserted != 200 and failed. This was a latent failure introduced when the test was added (135258c), unrelated to the DNS changes on this branch; reproduced by POSTing to a locally-run admin server against a freshly-migrated DB (503 -> 200 after the swap).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #78. Also finishes the DB-driven zone-id move started in #16 and lays groundwork for #110.
What & why
DNS provider config was split awkwardly: the provider + credentials + forward zone lived in static
config.yaml(Settings.dns), while reverse zones lived per-range in the DB. OVH reverse DNS (issue #78) doesn't fit the Cloudflare zone+record-id model at all (it's per-IP, no zones, no record ids), so the DNS layer needed a refactor to make providers fully DB-configurable.Changes
DB / model
dns_servertable + migration,DnsServer/DnsServerKindmodel, base-trait CRUD.ip_rangegainsforward_dns_server_id,reverse_dns_server_id,forward_zone_id(alongside existingreverse_zone_id).dns_serveradmin permission resource (AdminResource::DnsServer).DNS layer (
lnvps_api)DnsServertrait; zone/record ids are now aDnsRefenum (Implicit|Id(String)) rather than stuffing the IP into a string field.dns::get_dns_server(db, id)dispatches on kind.ovhDNS provider — reverse DNS viaPOST/DELETE /ip/{ip}/reverse(reverse only). Shared OVH request signing extracted tocrate::ovhand reused by the additional-IP router.vm_networkresolves forward/reverse DNS servers per range from the DB.Settings.dnsis now legacy (migration-only).Admin API
/api/admin/v1/dns_serversCRUD.POST /api/admin/v1/ip_ranges/{id}/patch_dns— queue aPatchIpRangeDnsjob to re-apply forward/reverse DNS for a whole range on demand.Startup migration
config.yamlblock into adns_serverrow and points existing ranges at it (forward everywhere; reverse where a reverse zone was set).OvhDNS servers (reusing their url + token) and auto-maps reverse DNS onto the ranges they route./ip/*/reversepermission logs a warning instead of blocking startup.Notes / caveats
dnsblock still inconfig.yamlso the migration can read it once; it can be removed afterward./ip/*/reversepermission granted for reverse calls to succeed.vm-{id}.lnvps.cloud); only reverse switches to OVH.Testing
cargo test --workspace --exclude lnvps_e2e -- --test-threads=1), clippy clean on new code.DnsRef/stored_ref, record constructors, mock factory, OVHfqdn_with_dot,AdminResourceround-trip, migration bootstrap + OVH import + idempotency, reverse force-refresh decision logic,PatchIpRangeDnsdisplay.