Context
The DNSDriver.upsertRecords path only adds and updates records. Records that exist upstream in Hover but are NOT in the desired config are detected by Diff (flagged as NeedsUpdate: true) but never deleted on apply. Result: an apply against a config where the user removed a record never converges; the orphan record stays in Hover until manually removed via the UI.
Documented in README "Limitations" section as of PR #2, but the gap should be closed.
Proposed fix
In internal/drivers/dns.go upsertRecords, after the upsert pass, iterate existingByKey and call d.client.DeleteRecord(ctx, leftover.ID) for every remaining unmatched candidate.
Carefully think about whether Diff should split adds/removes into two distinct FieldChange entries so Plan output makes the prune visible to operators before apply — not a silent side effect.
Acceptance
- After
Apply, the upstream record set matches the desired set exactly (no extras).
- A new test
TestUpsertRecords_PrunesExtraRecords covers the case.
- README "Limitations" section updated to remove the "No prune on apply" caveat (keep the "No zone delete" caveat — Hover genuinely has no API for that).
Discovered in
PR #2 (#2), Copilot round-3 review.
Context
The
DNSDriver.upsertRecordspath only adds and updates records. Records that exist upstream in Hover but are NOT in the desired config are detected byDiff(flagged asNeedsUpdate: true) but never deleted on apply. Result: an apply against a config where the user removed a record never converges; the orphan record stays in Hover until manually removed via the UI.Documented in README "Limitations" section as of PR #2, but the gap should be closed.
Proposed fix
In
internal/drivers/dns.goupsertRecords, after the upsert pass, iterateexistingByKeyand calld.client.DeleteRecord(ctx, leftover.ID)for every remaining unmatched candidate.Carefully think about whether
Diffshould split adds/removes into two distinctFieldChangeentries so Plan output makes the prune visible to operators before apply — not a silent side effect.Acceptance
Apply, the upstream record set matches the desired set exactly (no extras).TestUpsertRecords_PrunesExtraRecordscovers the case.Discovered in
PR #2 (#2), Copilot round-3 review.