Problem
A customer runs two panel servers, both integrated with SecondDNS (same account). They migrate a domain: create it on the new server, move the data, then delete it on the old server.
What happens today:
- Create on the new server → API returns 409 "zone exists" → hook shrugs and skips. The zone still points to the old server's
masterIp.
- Delete on the old server → hook deletes the zone from SecondDNS entirely → the customer silently loses secondary DNS for a domain that is alive on the new server.
With the offline queue (PR #62 rework) this gets worse: the two servers' queues are independent, so delivery order is unpredictable — semantics must fix it, not ordering.
Proposed fix: master-IP ownership semantics in the delivery path
- Create on 409: fetch the existing zone's
masterIp. If it belongs to another server → this is a migration to me → PATCH masterIp to my own. If it is already mine → true duplicate, skip.
- Delete: before deleting, compare the zone's
masterIp with my master_ip from /etc/seconddns.conf. Match → delete. Mismatch → skip with a log line ("zone now owned by another server") — the old server can no longer kill a migrated zone.
These two rules converge to the correct final state regardless of delivery order:
- create(new) then delete(old): PATCH re-points the zone, delete is skipped ✓
- delete(old) then create(new): zone briefly disappears, create recreates it with the new masterIp ✓ (short gap, correct final state)
API prerequisites
GET /api/zones/by-name/<domain> must return masterIp (to compare)
PATCH /api/zones/{id} with masterIp must exist (the dashboard already exposes master-IP change, so this appears to hold — verify)
Notes
Problem
A customer runs two panel servers, both integrated with SecondDNS (same account). They migrate a domain: create it on the new server, move the data, then delete it on the old server.
What happens today:
masterIp.With the offline queue (PR #62 rework) this gets worse: the two servers' queues are independent, so delivery order is unpredictable — semantics must fix it, not ordering.
Proposed fix: master-IP ownership semantics in the delivery path
masterIp. If it belongs to another server → this is a migration to me →PATCH masterIpto my own. If it is already mine → true duplicate, skip.masterIpwith mymaster_ipfrom/etc/seconddns.conf. Match → delete. Mismatch → skip with a log line ("zone now owned by another server") — the old server can no longer kill a migrated zone.These two rules converge to the correct final state regardless of delivery order:
API prerequisites
GET /api/zones/by-name/<domain>must returnmasterIp(to compare)PATCH /api/zones/{id}withmasterIpmust exist (the dashboard already exposes master-IP change, so this appears to hold — verify)Notes
seconddns-queued) once PR feat(queue): offline operation queue for all panel integrations #62 is reworked to the daemon model.