{"id":45803450,"url":"https://github.com/unifi2netbox/netbox-unifi-sync","last_synced_at":"2026-04-06T09:01:27.027Z","repository":{"id":340446929,"uuid":"1165687933","full_name":"unifi2netbox/netbox-unifi-sync","owner":"unifi2netbox","description":"Scrape Unifi for devices and adds them to Netbox.","archived":false,"fork":false,"pushed_at":"2026-04-06T08:06:27.000Z","size":1303,"stargazers_count":5,"open_issues_count":0,"forks_count":1,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-04-06T08:48:27.434Z","etag":null,"topics":["netbox","netbox-plugin","unifi","unifi2netbox","unifisync"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/unifi2netbox.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-02-24T12:43:05.000Z","updated_at":"2026-04-06T08:06:29.000Z","dependencies_parsed_at":"2026-04-06T09:00:54.780Z","dependency_job_id":null,"html_url":"https://github.com/unifi2netbox/netbox-unifi-sync","commit_stats":null,"previous_names":["unifi2netbox/unifi2netbox-plugins","unifi2netbox/netbox-unifi-sync"],"tags_count":41,"template":false,"template_full_name":null,"purl":"pkg:github/unifi2netbox/netbox-unifi-sync","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/unifi2netbox%2Fnetbox-unifi-sync","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/unifi2netbox%2Fnetbox-unifi-sync/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/unifi2netbox%2Fnetbox-unifi-sync/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/unifi2netbox%2Fnetbox-unifi-sync/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/unifi2netbox","download_url":"https://codeload.github.com/unifi2netbox/netbox-unifi-sync/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/unifi2netbox%2Fnetbox-unifi-sync/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31466228,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-06T08:36:52.050Z","status":"ssl_error","status_checked_at":"2026-04-06T08:36:51.267Z","response_time":112,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["netbox","netbox-plugin","unifi","unifi2netbox","unifisync"],"created_at":"2026-02-26T13:01:24.917Z","updated_at":"2026-04-06T09:01:27.021Z","avatar_url":"https://github.com/unifi2netbox.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# netbox-unifi-sync\n\n\u003e [!WARNING]\n\u003e We are aware that there are issues in the codebase.\n\u003e This is a hobby project maintained in spare time.\n\u003e Fixes and improvements are implemented when time allows.\n\u003e Do not deploy in production without proper validation.\n\n`netbox_unifi_sync` is a NetBox 4.2+ plugin that runs UniFi -\u003e NetBox sync jobs inside NetBox workers.\n\n---\n\n\u003e [!IMPORTANT]\n\u003e NetBox should be treated as the Source of Truth.\n\u003e Objects created or managed by this plugin should not be manually modified unless you understand how future sync runs will affect them.\n\n---\n\n## Visual Overview\n\n![netbox-unifi-sync overview](docs/assets/netbox-unifi-sync-overview.svg)\n\n```mermaid\nflowchart LR\n    U[\"UniFi Controller(s)\"] --\u003e P[\"netbox_unifi_sync plugin\u003cbr/\u003eNetBox Jobs (RQ)\"]\n    P --\u003e N[\"NetBox DCIM/IPAM/Wireless\"]\n    A[\"Plugin UI\u003cbr/\u003eSettings/Controllers/Mappings\"] --\u003e P\n```\n\n---\n\n## Architecture \u0026 Internal Flow\n\n### Runtime Execution Flow\n\n```mermaid\nflowchart TD\n    A[Scheduled Job / Manual Trigger] --\u003e B[NetBox RQ Worker]\n    B --\u003e C[Load Plugin Settings]\n    C --\u003e D[Authenticate to UniFi]\n    D --\u003e E[Fetch Data from UniFi API]\n    E --\u003e F[Normalize / Map Data]\n    F --\u003e G[Create / Update NetBox Objects]\n    G --\u003e H[Write Audit Log]\n```\n\n---\n\n### Detailed Sync Pipeline\n\n```mermaid\nflowchart LR\n    U[UniFi API] --\u003e V[Devices]\n    U --\u003e W[VLANs]\n    U --\u003e X[WLANs]\n    U --\u003e Y[DHCP Scopes]\n\n    V --\u003e M1[Device Mapping]\n    W --\u003e M2[VLAN Mapping]\n    X --\u003e M3[Wireless Mapping]\n    Y --\u003e M4[IP Range Mapping]\n\n    M1 --\u003e NB[NetBox ORM]\n    M2 --\u003e NB\n    M3 --\u003e NB\n    M4 --\u003e NB\n\n    NB --\u003e DB[(NetBox Database)]\n```\n\n---\n\n### Object Lifecycle Logic\n\n```mermaid\nflowchart TD\n    A[UniFi Object] --\u003e B{Exists in NetBox?}\n    B -- Yes --\u003e C[Update Object]\n    B -- No --\u003e D[Create Object]\n    C --\u003e E[Mark as Synced]\n    D --\u003e E\n    E --\u003e F{Cleanup Enabled?}\n    F -- Yes --\u003e G[Remove Stale Objects]\n    F -- No --\u003e H[Keep Orphaned Objects]\n```\n\n---\n\n### Authentication Flow\n\n```mermaid\nflowchart LR\n    A[Plugin Settings] --\u003e B{Auth Mode}\n    B -- API Key --\u003e C[Attach Authorization Header]\n    B -- Username/Password --\u003e D[Session Login]\n    D --\u003e E[Optional MFA]\n    C --\u003e F[Authenticated API Session]\n    E --\u003e F\n    F --\u003e G[Execute Requests]\n```\n\n---\n\n### Error Handling \u0026 Retry Logic\n\n```mermaid\nflowchart TD\n    A[API Request] --\u003e B{Success?}\n    B -- Yes --\u003e C[Process Response]\n    B -- No --\u003e D{Retry \u003c Max Attempts?}\n    D -- Yes --\u003e E[Backoff + Retry]\n    D -- No --\u003e F[Log Error]\n    F --\u003e G[Mark Job Failed]\n```\n\n---\n\n## Features\n\n- Device sync (devices, interfaces, VLANs, prefixes, WLANs, uplink relations, IP assignments)\n- **Security Appliance sync** — VLAN subinterfaces and gateway IPs created correctly, including Integration API controllers\n- **MAC address sync** — per-port MACs (Legacy API) or device base MAC on Port 1 (Integration API); NetBox 4.5 `MACAddress` model compatible\n- DHCP scope sync to NetBox IP Ranges\n- UniFi auth via API key or legacy login (username/password + optional MFA)\n- Manual and scheduled sync jobs\n- Runtime settings stored in plugin models (`Settings`, `Controllers`, `Site mappings`)\n\n\u003e [!NOTE]\n\u003e Sync is strictly one-way: UniFi -\u003e NetBox.\n\u003e No configuration is ever pushed back to UniFi.\n\n---\n\n## Quick Start\n\n### 1. Install\n\n```bash\npip install netbox-unifi-sync\n```\n\nPyPI project page:\nhttps://pypi.org/project/netbox-unifi-sync/\n\nFor `netbox-docker`, add the package to `local_requirements.txt` before build:\n\n```bash\necho \"netbox-unifi-sync\" \u003e\u003e local_requirements.txt\n```\n\n\u003e [!IMPORTANT]\n\u003e The plugin must be installed in the same environment as both NetBox and the worker container.\n\u003e Otherwise scheduled jobs will fail.\n\n---\n\n### 2. Enable plugin in NetBox\n\n```python\nPLUGINS = [\"netbox_unifi_sync\"]\n\nPLUGINS_CONFIG = {\n    \"netbox_unifi_sync\": {}\n}\n```\n\n---\n\n### 3. Apply migrations\n\n```bash\npython manage.py migrate\n```\n\n\u003e [!CAUTION]\n\u003e Skipping migrations will result in database errors and plugin initialization failure.\n\n---\n\n### 4. Configure in UI\n\nGo to:\n\nPlugins -\u003e UniFi Sync\n\nConfigure:\n\n1. Settings (`tenant_name`, `netbox_roles`, defaults)\n2. Controllers (URL, auth mode, credentials)\n3. Site mappings (if UniFi/NetBox site names differ)\n\n\u003e [!TIP]\n\u003e Use a dedicated read-only API account in UniFi for synchronization.\n\u003e This limits impact if credentials are exposed.\n\n---\n\n### 5. Run first sync\n\nUI:\nPlugins -\u003e UniFi Sync -\u003e Sync Dashboard -\u003e Run now\n\nCLI:\n\n```bash\npython manage.py netbox_unifi_sync_run --dry-run --json\npython manage.py netbox_unifi_sync_run\npython manage.py netbox_unifi_sync_run --cleanup\n```\n\n\u003e [!IMPORTANT]\n\u003e Always run the first execution with --dry-run to verify intended changes before writing to NetBox.\n\n\u003e [!CAUTION]\n\u003e The --cleanup flag removes objects in NetBox that no longer exist in UniFi.\n\u003e Review carefully before using in production.\n\n---\n\n## Credentials\n\nSet credentials only in:\n\nPlugins -\u003e UniFi Sync -\u003e Controllers\n\n\u003e [!WARNING]\n\u003e Never store UniFi credentials in PLUGINS_CONFIG.\n\u003e Configuration files may end up in version control or logs.\n\n---\n\n## Scheduled Jobs\n\nThe plugin supports NetBox Scheduled Jobs.\n\nRecommended intervals:\n\n- Small environments: every 30–60 minutes\n- Larger environments: every 2–4 hours\n\n\u003e [!NOTE]\n\u003e High sync frequency increases load on both the UniFi controller and NetBox worker processes.\n\n---\n\n## Security Notes\n\n- SSL verification defaults to true\n- Secrets are redacted in run history and audit logs\n- Timeouts, retries, and backoff are configurable\n\n\u003e [!IMPORTANT]\n\u003e If disabling SSL verification for testing, restrict access to the controller network.\n\u003e Never disable SSL verification in production environments.\n\n---\n\n## Documentation\n\n- [Server install guide](docs/server-install.md)\n- [NetBox plugin mode](docs/netbox-plugin.md)\n- [Configuration reference](docs/configuration.md)\n- [Troubleshooting](docs/troubleshooting.md)\n- [Release and PyPI publish](docs/release.md)\n- [netbox-docker setup](deploy/netbox-docker/README.md)\n- [Wiki source pages](wiki/Home.md)\n- [GitHub Wiki](https://github.com/unifi2netbox/netbox-unifi-sync/wiki)\n\n---\n\n## Maintainer: Release to PyPI\n\n1. Bump version in:\n   - pyproject.toml (`[project].version`)\n   - netbox_unifi_sync/version.py (`__version__`)\n   - netbox-plugin.yaml (`compatibility[].release`)\n2. Configure PyPI Trusted Publisher (OIDC) for this repository/workflow.\n3. Create tag `vX.Y.Z` either:\n   - via GitHub Actions `Create Release Tag (manual)` (recommended), or\n   - manually with git:\n   - `git tag -a vX.Y.Z -m \"Release vX.Y.Z\"`\n   - `git push origin vX.Y.Z`\n4. `release.yml` runs on the tag push, gates on lint/tests, and creates the GitHub Release.\n5. `publish-python-package.yml` runs on `release: published` and publishes to PyPI (can also be run manually for retry).\n\n\u003e [!CAUTION]\n\u003e Version mismatch between pyproject.toml, version.py, and netbox-plugin.yaml will break the release pipeline.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Funifi2netbox%2Fnetbox-unifi-sync","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Funifi2netbox%2Fnetbox-unifi-sync","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Funifi2netbox%2Fnetbox-unifi-sync/lists"}