Skip to content

Adapter Overview

Adapters are FreeSDN’s typed, auditable drivers that translate platform operations into vendor-specific API calls. All 12 adapters auto-register at startup. Every adapter follows the same safety contract so you interact with switches, firewalls, cameras, and hypervisors in a consistent way regardless of vendor.

All 12 adapters are registered at startup by adapter_registry.discover_adapters(), which explicitly imports each adapter by name. No configuration flag is needed - adapters are registered when the registry module is imported. Adding a new adapter package requires a corresponding entry in discover_adapters(); the function does not scan the filesystem. Each adapter declares its capabilities in an AdapterManifest registered in the adapter registry. The registry looks up the manifest at request time using the controller’s vendor type - nothing extra is stored in the Controller record.

The frontend reads capabilities via GET /api/v1/controllers/{id}/capabilities. Tabs, buttons, and dialogs are hidden when the adapter has not declared the matching Capability constant. You will never see a “Firmware Upgrade” button on a Controller whose adapter does not support firmware management.

The most important property of any FreeSDN adapter: a live device is never written to by accident. Every mutation travels through a two-stage pipeline:

  1. Stage - the change is recorded as a pending_changes row in the database. No packet is sent to the device. The staging endpoint validates input, checks tenant scope, and verifies the caller’s permission against the exact feature domain.

  2. Apply - the operator reviews the pending row in the Pending Changes page and confirms. Apply only succeeds when both conditions are true:

    • The environment variable ADAPTER_READ_ONLY is false.
    • The apply request body carries force: true.

Either gate alone refuses the apply. A stray API call cannot accidentally push a change if the environment is still set to read-only.

Apply is atomic: the pending row is claimed with SELECT ... FOR UPDATE inside the same database transaction that flips it to "applying", so two concurrent workers can never double-apply the same change. If a worker crashes mid-apply, a Celery beat janitor reverts rows stuck in "applying" for more than five minutes back to "failed", keeping the queue drainable.

The full honest matrix lives in the table below and in docs/SUPPORTED_VENDORS.md in the repository.

Tier What it means
Production Gold-standard contract enforced and verified. Suitable for evaluated production use after your own testing. File bugs as severity-1.
Beta Functional and covered by the automated test suite, but lacks field miles or one contract item. Use it; do not put it on the critical path of a paying customer without testing first.
Preview / Foundation Partial or unaudited implementation. Treat as a developer preview; expect gaps.

The gold-standard contract requires all six checks to pass: dual-gate writes (DG), tagged circuit breaker (CB), read-path secret redaction (RR), tenant scoping on reads (TS), SSRF guard on outbound URLs (SSRF), and role gates on destructive operations (RG).

Adapter Category Maturity DG CB RR TS SSRF RG
Omada (TP-Link) Network Production 12,807
OPNsense Firewall Production 7,761
pfSense Firewall Preview 2,176
MikroTik / RouterOS Firewall / Router Production 4,653
Proxmox VE Hypervisor Production 4,591
Hikvision Cameras / NVR Production 4,640
FreePBX / Asterisk VoIP Beta 5,268
Grandstream VoIP phones Beta 2,855
UniFi (Ubiquiti) Network Production 2,230
OpenWrt Router / AP Preview 3,666 - - - - - -
ONVIF (generic shim) Cameras - 2,558 - - - - - -
TrueNAS Storage Preview 1,722 - - - - - -

Every adapter must satisfy the FreeSDN adapter contract rubric before it ships. The checklist covers 14 sections: production safety, tenant isolation, permission boundaries, input validation, resilience (rate limiter + retry + circuit breaker), observability (Prometheus metrics + structured logging + health endpoint), audit trail, sensitive-data redaction, DoS hardening, capability advertisement, frontend contract, and test coverage. Each “MUST” item is a release-block.

The Omada adapter is the reference implementation every new adapter is graded against.

All adapters are accessed through a Controller record. Add one via the Setup wizard in the UI, or via the API:

Terminal window
# 1. Create the Controller (credentials are supplied inline)
curl -X POST https://<host>/api/v1/controllers \
-H "Cookie: freesdn_access=<token>" \
-H "X-CSRF-Token: <csrf>" \
-H "Content-Type: application/json" \
-d '{
"name": "my-controller",
"controller_type": "<vendor>",
"host": "https://controller.lan",
"port": 443,
"site_id": "<site_id>",
"username": "admin",
"password": "<password>"
}'
# 2. Trigger device discovery
curl -X POST https://<host>/api/v1/discovery/controllers/<controller_id> \
-H "Cookie: freesdn_access=<token>" \
-H "X-CSRF-Token: <csrf>"

Replace <vendor> with the lowercase adapter name: omada, opnsense, pfsense, mikrotik, unifi, openwrt, hikvision, freepbx, grandstream, proxmox, truenas.

  • Omada (TP-Link) - gold-standard reference, switches + APs
  • UniFi (Ubiquiti) - Production; 19 read methods + 9 dual-gated writes, live-validated on real Ubiquiti hardware
  • OPNsense - production firewall brain, 13 domains
  • pfSense - preview firewall, shares OPNsense client plumbing (not yet hardware-verified)
  • MikroTik RouterOS - production router/switch/VPN, 13 domains
  • OpenWrt - preview; ubus/UCI client, unaudited

All product names, logos, and brands are property of their respective owners. FreeSDN is an independent project and is not affiliated with or endorsed by the vendors it integrates with. See Trademarks.