Skip to content

How it works

The plugin is presentational: no model, no migration, no background job. Every page and fragment is built on request from ipam.Prefix, ipam.Aggregate and ipam.VRF.

Lazy loading

The tree page renders the top levels only. Opening a row fetches its children as an HTML fragment and inserts it below the row, so the cost of a page is the cost of what is open, not of the whole IPAM. Expand all, subtree expansion, filtered trees and restoring a previous state each fetch their rows in one request, capped by expand_all_limit.

Endpoint Returns
children/?key=... The direct children of one node.
subtree/?key=... A node's whole subtree (Alt+click, *, Expand all).
expand/?keys=... The rows needed to reopen a set of nodes.

Node keys are vrf:<id> (with vrf:0 for Global), agg:<id>@<vrf> for an aggregate under a VRF group, and pfx:<id>.

Nesting

For unconstrained users, children come from NetBox's cached prefix hierarchy (_depth and _children), maintained by NetBox itself on every prefix change. With constrained permissions, the tree is recomputed from the visible prefixes only (see Permissions).

Aggregates have no VRF in NetBox, so under each VRF group the plugin shows the aggregates covering that VRF's top-level prefixes. An aggregate that falls inside an open prefix (for example under 0.0.0.0/0) is not shown as a level.

Utilization

Utilization is computed in bulk, with a constant number of queries per VRF, instead of one call to Prefix.get_utilization() per row. The integration tests check that the bulk numbers equal NetBox's own for every prefix of the test data.

Performance

  • Query counts stay constant regardless of the number of rows; the integration tests guard this.
  • Row rendering avoids per-row queries and per-row URL resolution.
  • On the development dataset, Expand all of 5000 rows takes about 2 seconds on the server, plus browser layout.

Browser side

tree.js is plain JavaScript with no build step: it uses fetch() for fragments and the browser's local storage for the open nodes (at most 200 keys, or a single flag after Expand all). If a fragment request is redirected to the login page because the session expired, the page reloads to the login form.