[ ~/netbox-proxbox/developer ]tty0

   ___              _
  | _ \_ _ _____ __| |__  _____ __
  |  _/ '_/ _ \ \ / '_ \/ _ \ \ /
  |_| |_| \___/_\_\_.__/\___/_\_\
   n e t b o x  ⇄  p r o x m o x

emerson@netdevops:~/netbox-proxbox$ ./describe.sh netbox-proxbox

Developer guide — architecture, integrations, contribution workflow and end-to-end testing.

netbox-proxbox is a Django plugin shipped on top of NetBox 4.5.x / 4.6.x. It runs inside the NetBox process and orchestrates all real Proxmox traffic through a sibling FastAPI service called proxbox-api.

This page documents the moving parts a contributor has to understand: how a Full Update click in the NetBox UI ends up streaming clusters, nodes, VMs, snapshots and backups into the source-of-truth, where the code that does it lives, and how the test suite proves the wiring works.

intro

emerson@netdevops:~/netbox-proxbox/developer$ cat README.md | head

netbox-proxbox is a Django plugin shipped on top of NetBox 4.5.x / 4.6.x. It runs inside the NetBox process and orchestrates all real Proxmox traffic through a sibling FastAPI service called proxbox-api.

This page documents the moving parts a contributor has to understand: how a Full Update click in the NetBox UI ends up streaming clusters, nodes, VMs, snapshots and backups into the source-of-truth, where the code that does it lives, and how the test suite proves the wiring works.

architecture

emerson@netdevops:~/netbox-proxbox/developer$ tree -L 2 src/

  • ├─Plugin entry: netbox_proxbox/__init__.py registers the NetBoxPluginConfig (currently certified against NetBox v4.5.8 → v4.6.x).
  • ├─Persisted models: ProxmoxEndpoint, NetBoxEndpoint (singleton), FastAPIEndpoint (singleton), ProxmoxCluster, ProxmoxNode, ProxmoxStorage, BackupRoutine, Replication, VMBackup, VMSnapshot, VMTaskHistory, ProxboxPluginSettings.
  • ├─URL routing: netbox_proxbox/urls.py wires every CRUD and operational view; views in netbox_proxbox/views/ extend NetBoxModelViewSet and use register_model_view for related-object panels.
  • ├─REST API: netbox_proxbox/api/ exposes DRF NetBoxModelViewSet routes for every persisted model.
  • ├─Sync workflow: a Full Update enqueues ProxboxSyncJob on NetBox's RQ default queue (7200s job timeout, 3600s HTTP read timeout). The job calls proxbox-api's full-update/stream endpoint and replays each SSE event back to the browser via netbox_proxbox/services/backend_proxy.py.
  • ├─Live log viewer: a separate WebSocket bridge keeps proxbox-api's log buffer streaming inside the plugin UI. Browser-side parsing lives in netbox_proxbox/static/netbox_proxbox/js/.
  • ├─Security model: CRUD views use ObjectPermissionRequiredMixin; custom views use ConditionalLoginRequiredMixin (respects NetBox's LOGIN_REQUIRED); operational endpoints use ContentTypePermissionRequiredMixin.
  • ├─Companion CLI: proxbox_cli/ ships the pxb command (declared in pyproject.toml [project.scripts]) for headless sync triggers.

integrations

emerson@netdevops:~/netbox-proxbox/developer$ ./describe-integrations

target protocol library
proxbox-apiHTTP REST + Server-Sent Events + WebSocketrequests + websockets + a small SSE reader in services/backend_proxy.py
NetBox core (Django ORM + DRF)in-processNetBox plugin framework
Proxmox VEindirect
  • proxbox-api: Resolved at runtime via FastAPIEndpoint.objects.first() — never imported as a Python dependency.
  • NetBox core (Django ORM + DRF): Plugin lives inside NetBox; persists its own models in NetBox's database and renders inside NetBox's templates.
  • Proxmox VE: The plugin never talks to Proxmox directly; everything goes through proxbox-api.

contributing

emerson@netdevops:~/netbox-proxbox/developer$ ./contributing --help

# dev install

install
emerson@netdevops:~$ pip install -e '.[dev,test,cli]'

# pre-PR checks

  • syntax compile

    shell
    python -m compileall netbox_proxbox tests
  • lint

    shell
    rtk ruff check .
  • type check (cli)

    shell
    rtk ty check proxbox_cli
  • unit + integration

    shell
    rtk pytest tests/

# code style

  • ├─Linter: ruff (line length 88, select E/F/W).
  • ├─Formatter: black.
  • ├─Type checker: ty (>=0.0.1a19).
  • ├─Pre-commit hooks: .pre-commit-config.yaml (run before opening a PR).
  • ├─PRs reference the closing issue with `Closes #<id>`. Contribution guide: CONTRIBUTING.md.

# issue tracker https://github.com/N-Multifibra/netbox-proxbox/issues

ci

emerson@netdevops:~/netbox-proxbox/developer$ gh workflow list

The CI surface is split between fast package checks, a reusable Docker E2E stack, documentation automation, nightly contract checks, and staged package publishing.

Release validation keeps the plugin and backend on matching package indexes: TestPyPI plugin validation uses TestPyPI proxbox-api, while PyPI candidate and final validation use PyPI proxbox-api.

# workflows

workflow trigger purpose
ci.ymlpush + pull_requestRuns lint, ty, compile checks, pytest coverage, and package metadata contract tests.
e2e-docker.ymlworkflow_call + manual + nightlyRuns NetBox, rqworker, proxbox-api, PostgreSQL, Redis, and a Proxmox mock in Docker.
publish-testpypi.ymlversion tags + GitHub releases + manualPublishes immutable TestPyPI/PyPI package versions and gates them with exact install and E2E validation.
docs.ymldocs changesBuilds and publishes the MkDocs site.
nightly-contracts.ymlschedule + manualChecks cross-repo contracts that must stay aligned with proxbox-api.

# notes

  • ├─Never retry a consumed package version with --skip-existing; publish the next .postN or rcN instead.
  • ├─The E2E workflow accepts install_source, dependency_mode, proxbox_api_version, and netbox_image for focused validation.
  • ├─The public MkDocs source of truth is docs/developer/ci-e2e-workflows.md.

e2e

emerson@netdevops:~/netbox-proxbox/developer$ ./run-e2e --report

framework

Plain Python requests + Docker Compose stack (NetBox + PostgreSQL + Redis + proxbox-api + a proxmox-sdk:dev-nginx mock).

There is no pytest E2E target — the suite is a runnable Python script that brings the whole stack up, drives a Full Update, and asserts the resulting NetBox state.

The same suite is wired into GitHub Actions for nightly coverage and for staged package releases: TestPyPI runs install the plugin and proxbox-api from TestPyPI, while PyPI candidate and final runs install both from PyPI.

# commands

  • run E2E locally

    shell
    python tests/e2e/e2e_stack_check.py

# coverage

  • ├─Spec files: tests/e2e/e2e_stack_check.py, stack_setup.py, stack_sync.py, stack_common.py, mock_proxmox_api.py.
  • ├─Stack: NetBox image netboxcommunity/netbox:v4.5.8 / v4.5.9 / v4.6.0 + Postgres + Redis + proxbox-api + proxmox-sdk:dev-nginx.
  • ├─Mock data: tests/e2e/proxmox_openapi_mock_data.json mounted into the proxmox-sdk mock container.
  • ├─Matrix axes include install_source ∈ {local, pypi, container, testpypi} and dependency_mode ∈ {dev, published, testpypi-package, pypi-package}.
  • ├─Release gate: publish-testpypi.yml publishes to TestPyPI first, validates exact package installs, then promotes PyPI rc/final versions only after E2E passes with the matching proxbox-api package index.
  • ├─Schedule: nightly cron 31 2 * * * exercises the full matrix unattended.

ci workflow: .github/workflows/e2e-docker.yml

emerson@netdevops:~/netbox-proxbox/developer$ links