Add a phpIPAM import to the IP Addresses page
New "Sync from phpIPAM" action on IP Addresses, alongside the existing
"Sync from Tailscale" / "Sync from Proxmox" ones and built the same way:
a new integration type (config in-app, URL + API app ID + app token,
credentials encrypted at rest) that this page pulls from on demand.
Deliberately import-only, not a full integration -- no dedicated page,
dashboard widget, or nav entry, since that's all this was asked for.
Auth is phpIPAM's static "App token" method: create an API app under
Administration -> API with its security set to "SSL with App token", and
its one-time code goes straight in as the `token` header (also sent as
`phpipam-token`, in case a given version expects that name instead) --
no login call, no token to renew. The user/password "User token" method
isn't implemented.
Addresses are read the standard way: GET /subnets/, then GET
/subnets/{id}/addresses/ for each, rather than assuming a single
"all addresses" endpoint exists on every version. phpIPAM wraps every
response as {code, success, data} -- including an empty result: a subnet
with nothing in it answers success:false, message:"No addresses found"
rather than success:true, data:[]. That's read as "nothing here", not a
failure; anything else with success:false throws with phpIPAM's own
message. One subnet failing outright (e.g. the app lacks permission on
it) is skipped with a note rather than aborting the whole sync. Every
address field is read defensively -- optional, independently
type-checked -- so a field phpIPAM renames or drops in some version
leaves that value blank instead of breaking the import.
Imported entries: label from hostname or description, "phpIPAM" as
vendor, the subnet's own description (or its CIDR, if it has none) as
location, and description/note/MAC folded into notes. Existing sync
plumbing (upsertSyncedEntry) gained a location parameter so this and any
future sync can set it; the two existing syncs pass null, unchanged.
Endpoints, the token header, and the address/subnet field names are
cross-checked against phpIPAM's own published API documentation. Not
verified against a live instance -- there wasn't one available while
building this, so if a real sync comes back empty or with the wrong
fields, that's the next thing to check.
Verified with 23 backend checks against a fake phpIPAM server matching
that documented shape (the empty-subnet quirk, a subnet that fails
outright, malformed/missing fields, a non-JSON response) and the real
route (added/updated/skipped counts, a manually-entered IP never
overwritten, roles, no-enabled-integration, upstream failure surfaced
per-integration rather than as a 500, audit entries) plus a browser check
of the real IP Addresses page against the real routers: the sync button,
its result message, re-syncing (updates rather than duplicates), the
manual entry staying untouched, and the viewer view.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
bf7f73f6b6
commit
70ba60c7da
14 files changed
+281
-13
No files matched your search
@@ -51,10 +51,11 @@ All modules from the original plan are built:
|
||||
is picked up automatically and an unreachable host is flagged instead of
|
||||
silently going stale
|
||||
- **IP Addresses (IPAM)** — inventory of IPs across vendors/locations,
|
||||
with "Sync from Tailscale" and "Sync from Proxmox" actions to pull in
|
||||
tailnet device IPs and VM/LXC IPs (never overwrites a
|
||||
manually-entered IP), and each entry now shows its matching DNS
|
||||
record(s) from the DNS module's cache
|
||||
with "Sync from Tailscale", "Sync from Proxmox", and "Sync from phpIPAM"
|
||||
actions to pull in tailnet device IPs, VM/LXC IPs, and phpIPAM's own
|
||||
addresses (never overwrites a manually-entered IP, or one a different sync
|
||||
owns), and each entry now shows its matching DNS record(s) from the DNS
|
||||
module's cache
|
||||
- **DNS** — zone/record management across Cloudflare, Loopia, Pi-hole, Azure
|
||||
DNS, cPanel, and Technitium; providers are configured in-app (not via env
|
||||
vars) and their credentials are encrypted at rest
|
||||
|
||||
Reference in new issue
Block a user