Files
netbox-librenms-plugin/.github/instructions/sync.instructions.md
Vlastislav Svatek 673e67106e
Some checks failed
ci / deploy (push) Has been cancelled
CodeQL Advanced / Analyze (actions) (push) Has been cancelled
CodeQL Advanced / Analyze (javascript-typescript) (push) Has been cancelled
CodeQL Advanced / Analyze (python) (push) Has been cancelled
first commit
2026-06-05 10:39:05 +02:00

5.3 KiB

applyTo, description
applyTo description
**/views/base/**,**/views/object_sync/**,**/views/sync/**,**/tables/**,**/librenms_sync.js Sync page architecture, base views, and sync action patterns

Sync Pages

Three-Layer View Architecture

All four sync resources (interfaces, cables, IP addresses, VLANs) follow the same pattern:

  1. Base views (views/base/) — abstract classes that define the data pipeline:

    • BaseLibreNMSSyncView — tabbed sync page, orchestrates all tabs via abstract get_*_context() methods.
    • BaseInterfaceTableView — fetch ports → enrich with VLANs → cache → compare with NetBox interfaces → render table.
    • BaseCableTableView — fetch links → match remote devices → check cable status → render table.
    • BaseIPAddressTableView — fetch IPs → resolve interfaces → detect existing/update/new → render table.
    • BaseVLANTableView — fetch VLANs → compare with NetBox VLANs → auto-select groups → render table.
  2. Object sync views (views/object_sync/) — wire base views to NetBox models:

    • Use @register_model_view(Device, name="librenms_sync", path="librenms-sync") to inject as a tab on Device/VM detail pages.
    • Each get_*_context() method creates an instance of the concrete table view, copies request, and calls get_context_data().
    • VMs skip cables and VLANs (return None).
  3. Sync action views (views/sync/) — POST-only views that create/update/delete NetBox objects:

    • Follow a consistent pattern: check permissions → read selected rows from POST → load cached data → apply changes in transaction.atomic() → redirect to sync tab.

Data Pipeline (Base Views)

Every base table view follows: fetch → cache → compare → render.

  • Fetch: Call LibreNMS API (e.g., get_ports(), get_device_ips(), get_device_vlans()).
  • Cache: Store results via CacheMixin keys: librenms_{data_type}_{model_name}_{pk}. Also store fetch timestamp at librenms_{data_type}_last_fetched_{model_name}_{pk}.
  • Compare: Match LibreNMS data against NetBox objects. Each resource implements its own comparison (interface matching by name, IP matching by address/mask, VLAN matching by VID+group).
  • Render: Build a django-tables2 table, return a partial template (_*_sync_content.html).

Sync Action View Pattern

class SyncSomeResourceView(LibreNMSPermissionMixin, NetBoxObjectPermissionMixin, CacheMixin, View):
    required_object_permissions = {"POST": [("add", Model), ("change", Model)]}

    def post(self, request, object_type, object_id):
        if error := self.require_all_permissions("POST"):
            return error
        # 1. Resolve object (Device or VM)
        # 2. Read selected items from request.POST.getlist("select")
        # 3. Load cached data from cache.get(self.get_cache_key(obj, "..."))
        # 4. Apply changes inside transaction.atomic()
        # 5. Redirect to sync tab with ?tab=<resource>

Table Conventions (tables/*.py)

  • Tables define HTMX-enabled columns and checkboxes. Selection uses ToggleColumn(attrs={"input": {"name": "select"}}).
  • Constructor takes contextual params (e.g., device, interface_name_field, vlan_groups) to customize rendering.
  • Tables set self.tab and self.prefix for multi-table pagination via get_table_paginate_count().
  • Row attrs include data-* attributes for JavaScript filtering and identification.
  • VLAN columns use render_vlans() with hidden inputs for per-row group selection and JSON data for modals.

Key Mixins Used by Sync Views

  • LibreNMSAPIMixin — lazy-creates LibreNMSAPI instance via self.librenms_api property. Also provides get_server_info() for template context.
  • CacheMixin — generates consistent cache keys via get_cache_key(obj, data_type) and get_last_fetched_key(obj, data_type). Also provides get_vlan_overrides_key(obj) for VLAN group override persistence.
  • VlanAssignmentMixin — VLAN group scope resolution: Rack → Location → Site → SiteGroup → Region → Global. Used by interface and VLAN sync for auto-selecting the most-specific VLAN group and building lookup maps.

JavaScript (librenms_sync.js)

  • Not wrapped in an IIFE — functions are global. Master initializer initializeScripts() runs on DOMContentLoaded and htmx:afterSwap.
  • Key function groups:
    • Checkbox management: initializeTableCheckboxes(), updateBulkActionButton().
    • TomSelect dropdowns: initializeVCMemberSelect(), initializeVRFSelects(), initializeVlanGroupSelects(), initializeVlanSyncGroupSelects(). Uses TOMSELECT_INIT_DELAY_MS = 100 for delayed initialization after HTMX swaps.
    • Verification: handleInterfaceChange(), handleCableChange(), handleVRFChange() — POST to single-item verify endpoints.
    • VLAN modals: openVlanDetailModal(), verifyVlanInGroup(), verifyVlanSyncGroup() — per-interface VLAN detail editing.
    • Bulk operations: initializeBulkEditApply(), deleteSelectedInterfaces().
    • Table filtering: initializeTableFilters(), filterTable() — client-side row filtering.
    • URL/tab state: initializeTabs(), getDeviceIdFromUrl(), setInterfaceNameFieldFromURL().
    • Cache countdowns: initializeCountdown(), initializeCountdowns().
  • CSRF token extracted via document.querySelector('[name=csrfmiddlewaretoken]').value.