IPAM was entirely manual — Tailscale device IPs never showed up there even though the Tailscale integration already lists them. Add an explicit sync action (matching this app's existing pattern of user-triggered syncs rather than silent background polling). - New source column on ipam_entries (null = manual, "tailscale" = auto-synced) so a re-sync only ever touches rows it created itself — a manually-entered IP that happens to collide with a tailnet address is left untouched and reported back as skipped, never overwritten. - POST /api/ipam/sync-tailscale pulls every enabled Tailscale integration's device list, upserting by primary IP (label, OS in notes, vendor "Tailscale"); one unreachable Tailscale integration doesn't block others. - New "Sync from Tailscale" button on the IP Addresses page, with a small "synced" badge marking which rows came from it. Also fixed a longstanding TODO found in the same file: the "DNS records" column always showed "-" because matchingDnsRecords was hardcoded to an empty array from before the DNS module existed. It now does the same content-based reverse lookup against the DNS module's record cache used elsewhere in the app. Verified end-to-end by running the real server with Tailscale's fetch call intercepted at the process level (its adapter hardcodes api.tailscale.com with no configurable URL, so it can't be pointed at a mock server the way Proxmox/Synology can): confirmed add, the manual-entry skip/never-overwrite behavior, idempotent re-sync (add -> update), and the DNS-matching fix, all against the real route and adapter code. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
1 line
45 B
SQL
1 line
45 B
SQL
ALTER TABLE `ipam_entries` ADD `source` text; |