Metadata-Version: 2.4
Name: netbox-tenant-switcher
Version: 1.0.0
Summary: Searchable tenant selector in the NetBox navbar that scopes list views to the selected tenant.
Author-email: Du10777 <du103682@gmail.com>
License-Expression: MIT
Project-URL: Homepage, https://github.com/Du10777/netbox-tenant-switcher
Project-URL: Repository, https://github.com/Du10777/netbox-tenant-switcher
Project-URL: Documentation, https://github.com/Du10777/netbox-tenant-switcher#readme
Project-URL: Issues, https://github.com/Du10777/netbox-tenant-switcher/issues
Project-URL: Changelog, https://github.com/Du10777/netbox-tenant-switcher/blob/main/CHANGELOG.md
Keywords: netbox,netbox-plugin,plugin,tenant,multitenancy,dcim,ipam
Classifier: Development Status :: 5 - Production/Stable
Classifier: Environment :: Web Environment
Classifier: Framework :: Django
Classifier: Intended Audience :: System Administrators
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: System :: Networking
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Dynamic: license-file

<p align="center">
  <img src="docs/img/icon.svg" width="120" alt="netbox-tenant-switcher icon">
</p>

# NetBox Tenant Switcher

**Pick a tenant once, and every list in NetBox shows only that tenant's objects.**

`netbox-tenant-switcher` adds a searchable tenant selector to the top navigation
bar — rendered inside the field, just like NetBox's global search box. Choose a
tenant and, as you move between sections (Devices, Prefixes, VLANs, Sites,
Racks, …), each list view is automatically scoped to that tenant. Choose
**"— All tenants —"** to clear the scope.

It's ideal for MSPs, multi-customer labs, and anyone who spends the day working
inside one tenant at a time and doesn't want to add a tenant filter on every page.

## Screenshots

![Tenant selector in the navbar](docs/img/1.navbar.png)
*The tenant selector sits in the top navigation bar, rendered inside the field like NetBox's global search.*

![Tenant dropdown with per-tenant checkboxes and instant search](docs/img/2.dropdown.png)
*Open the dropdown to multi-select tenants and type to filter instantly; selected tenants float to the top.*

![Selected tenants shown in the field](docs/img/3.selected.png)
*Chosen tenants are listed comma-separated in the field and persist across the session.*

![Device list scoped to the selected tenants](docs/img/4.filtered.png)
*Every list view (Devices, Prefixes, VLANs, …) is automatically scoped to the selected tenants.*

## Features

- **Multi-select** tenant switcher in the navbar with a checkbox per tenant and
  **instant** client-side search — no external JS dependencies.
- Selected tenants are shown comma-separated in the field, truncated with an
  ellipsis to fit the header; the field width adapts to the viewport and never
  overlaps the global search box.
- Selected tenants float to the top when the dropdown opens; the list is ordered
  by name.
- Selection persists in the session; no models, no migrations.
- Automatically scopes every object **list** view whose filterset supports a
  tenant filter, by appending `?tenant_id=<id>` (once per selected tenant, so
  multiple tenants are OR-combined).
- Non-tenancy models (Manufacturers, Device Types, …) and detail views are left
  untouched.
- Permission-aware: the dropdown only lists tenants the user may view, and a
  tenant can't be selected unless the user has view access to it.
- Only ever *narrows* results — NetBox object permissions still apply on top.

## Compatibility

| Plugin version | NetBox version | Python  |
| -------------- | -------------- | ------- |
| 1.0.x          | 4.6            | 3.10 – 3.12 |

Developed and verified against **NetBox 4.6**. It uses only stable plugin APIs
(`PluginTemplateExtension.navbar()` / `head()`, plugin middleware) and is
expected to work on nearby 4.x releases; the CI matrix in
`.github/workflows/ci.yml` is where additional versions should be validated.

## Dependencies

- **NetBox** ≥ 4.6 (provides Django, Tom Select, and the tenancy models).
- No additional Python packages, external services, or other plugins required.

## Installation

1. Install the package into NetBox's Python environment:

   ```bash
   source /opt/netbox/venv/bin/activate
   pip install netbox-tenant-switcher
   ```

2. Enable it in `configuration.py`:

   ```python
   PLUGINS = [
       "netbox_tenant_switcher",
   ]
   ```

3. Restart NetBox:

   ```bash
   sudo systemctl restart netbox netbox-rq
   ```

No database migrations are required.

### Docker (netbox-docker)

See [`deploy/`](deploy/) for a ready-to-use `Dockerfile-Plugins`,
`docker-compose.override.yml`, and `plugins.py`. In short: drop the project under
`plugins/plugin-src/`, add the plugin to `configuration/plugins.py`, then:

```bash
docker compose build netbox
docker compose up -d
```

## Configuration

None. The plugin works out of the box; there are no `PLUGINS_CONFIG` settings.

## How it works

- **Navbar widget** (`template_content.py`) — a `PluginTemplateExtension` renders
  a small, dependency-free multi-select (checkbox list + instant search) via the
  `navbar()` hook; styling is injected through `head()`. It stays in one line
  with the selected tenants comma-separated and ellipsis-truncated.
- **Set endpoint** (`views.py`) —
  `GET /plugins/tenant-switcher/set/?tenant=<id>&tenant=<id>&next=<path>` stores
  the chosen tenants in the session and redirects back. `next` is validated
  against the current host (no open redirects) and every tenant id is checked
  against the user's view permission.
- **Middleware** (`middleware.py`) — for `ObjectListView` pages whose filterset
  exposes a `tenant_id` filter, it appends one `?tenant_id=<id>` per selected
  tenant when no explicit tenant filter is already present.

  > Design note: scoping is done by URL rewriting rather than by patching every
  > queryset. This keeps the plugin decoupled from core views, applies uniformly
  > across DCIM/IPAM/etc., and leaves the applied filter visible and removable in
  > the UI.

## Support

- **Issues / bugs / features:** GitHub Issues —
  <https://github.com/Du10777/netbox-tenant-switcher/issues>
- **Questions:** GitHub Discussions, or the NetDev Community Slack (`#netbox`).

## Contributing

PRs welcome. Run the test suite the way NetBox does — see
`.github/workflows/ci.yml` (checkout NetBox, install the plugin, then
`python netbox/manage.py test netbox_tenant_switcher`).

## License

[MIT](LICENSE). The icon in `docs/img/` is released under
[CC BY 4.0](https://creativecommons.org/licenses/by/4.0/).
