# netbox-proxbox developer guide

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

| Field |Value |
| --- | --- |
| Canonical URL | https://emersonfelipesp.com/netbox-proxbox/developer |
| Showcase | https://emersonfelipesp.com/netbox-proxbox |
| GitHub | https://github.com/emersonfelipesp/netbox-proxbox |
| Releases | https://emersonfelipesp.com/netbox-proxbox/releases |
| Release snapshot synced | 2026-11-04T13:46:14.558Z |

## Intro

netbox-proxbox is a Django plugin for NetBox 4.5.8 through 4.7.x, with GA verification through 4.7.0. It runs inside the NetBox process and orchestrates 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

- Plugin entry: netbox_proxbox/__init__.py registers the NetBoxPluginConfig (declared range 4.5.8–4.7.99; GA CI through 4.7.0).
- 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: operational actions use run_proxmox_action on the exact owning ProxmoxEndpoint; constrained NetBox ObjectPermissions let non-superusers operate only approved endpoints.
- HA reads and operational dispatch fail before backend I/O when endpoint identity is missing, conflicting, disabled, or hidden.
- Migration 0106_device_sync_scope_and_netbox_token_approval adds endpoint ownership claims and token-bound approval for remote NetBox connections.
- automatic_background_tasks=False enables capture-only operation, while ws_run_id capability correlates WebSocket completion to the initiating backend run.
- OpenBao storage selection, endpoint overrides, owner deletion, bulk updates, and conflict upserts are validated under transaction locks.
- Companion CLI: proxbox_cli/ ships the pxb command (declared in pyproject.toml [project.scripts]) for headless sync triggers.

## Integrations

| Target |Protocol |Library |Notes |
| --- | --- | --- | --- |
| proxbox-api | HTTP REST + Server-Sent Events + WebSocket | requests + websockets + a small SSE reader in services/backend_proxy.py | Resolved at runtime via FastAPIEndpoint.objects.first() — never imported as a Python dependency. |
| NetBox core (Django ORM + DRF) | in-process | NetBox plugin framework | Plugin lives inside NetBox; persists its own models in NetBox's database and renders inside NetBox's templates. |
| Proxmox VE | indirect | — | The plugin never talks to Proxmox directly; everything goes through proxbox-api. |

## Contributing

Development install:

```shell
pip install -e '.[dev,test,cli]'
```

Pre-PR checks:

- syntax compile: `python -m compileall netbox_proxbox tests`
- lint: `rtk ruff check .`
- type check (cli): `rtk ty check proxbox_cli`
- unit + integration: `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.

Issues: https://github.com/emersonfelipesp/netbox-proxbox/issues

## CI

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.

| Workflow |Trigger |Purpose |
| --- | --- | --- |
| ci.yml | push + pull_request | Runs lint, ty, compile checks, pytest coverage, and package metadata contract tests. |
| e2e-docker.yml | workflow_call + manual + nightly | Runs NetBox, rqworker, proxbox-api, PostgreSQL, Redis, and a Proxmox mock in Docker. |
| publish-testpypi.yml | version tags + GitHub releases + manual | Publishes immutable TestPyPI/PyPI package versions and gates them with exact install and E2E validation. |
| docs.yml | docs changes | Builds and publishes the MkDocs site. |
| nightly-contracts.yml | schedule + manual | Checks cross-repo contracts that must stay aligned with proxbox-api. |

- 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, netbox_image, and proxmox_service for focused validation.
- Each matrix cell pulls a dedicated proxmox-sdk image tag — emersonfelipesp/proxmox-sdk:latest-pve, :latest-pbs, :latest-pdm — so the three Proxmox surfaces run in parallel with fail-fast disabled.
- The public MkDocs source of truth is docs/developer/ci-e2e-workflows.md (parallel mock matrix detailed in docs/features/e2e-docker-testing.md).

## End-to-end tests

Framework: Plain Python requests + Docker Compose stack (NetBox + PostgreSQL + Redis + proxbox-api + a per-cell proxmox-sdk mock chosen from latest-pve / latest-pbs / latest-pdm).

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 Docker matrix fans out across NetBox versions × proxmox_service so PVE, Proxmox Backup Server, and Proxmox Datacenter Manager surfaces are exercised in parallel. PVE-only assertions are gated by a stack helper and auto-skip on pbs/pdm cells; the proxbox-api /health smoke runs on every cell.

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 (default pve): `python tests/e2e/e2e_stack_check.py`
- run E2E against PBS mock: `PROXMOX_SERVICE=pbs python tests/e2e/e2e_stack_check.py`
- run E2E against PDM mock: `PROXMOX_SERVICE=pdm 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: every NetBox release from 4.5.8 through 4.5.10, every 4.6 release through 4.6.6, and 4.7.0 + Postgres + Redis + proxbox-api + the selected proxmox-sdk service image.
- Mock data: tests/e2e/proxmox_openapi_mock_data.json mounted into the proxmox-sdk mock container; the requested service tag drives which OpenAPI surface (PVE / PBS / PDM) is served.
- Matrix axes: 11 NetBox images × install_source ∈ {local, pypi, container} × proxbox_api_runtime ∈ {python, pyo3-rust} × proxmox_service ∈ {pve, pbs, pdm}, with fail-fast disabled; pull requests narrow runtime/service coverage to python + pve.
- 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 (https://github.com/emersonfelipesp/netbox-proxbox/blob/main/.github/workflows/e2e-docker.yml)

## Links

| Label |URL |
| --- | --- |
| repo | https://github.com/emersonfelipesp/netbox-proxbox |
| docs | https://emersonfelipesp.com/netbox-proxbox/docs/ |
| backendRepo | https://github.com/emersonfelipesp/proxbox-api |
| issues | https://github.com/emersonfelipesp/netbox-proxbox/issues |
| contributing | https://github.com/emersonfelipesp/netbox-proxbox/blob/main/CONTRIBUTING.md |
