Metadata-Version: 2.4
Name: netbox-site-context
Version: 0.1.1
Summary: Add context to your NetBox sites for automation and scripting
Author-email: Wouter de Bruijn <wouter@hedium.nl>
Project-URL: Documentation, https://github.com/wouterdebruijn/netbox-site-context/blob/main/README.md
Project-URL: Source, https://github.com/wouterdebruijn/netbox-site-context
Project-URL: Tracker, https://github.com/wouterdebruijn/netbox-site-context/issues
Keywords: netbox,netbox-plugin
Classifier: Development Status :: 3 - Alpha
Classifier: Framework :: Django
Classifier: Framework :: Django :: 5.1
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: System Administrators
Classifier: Intended Audience :: Telecommunications Industry
Classifier: Natural Language :: English
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Topic :: System :: Networking
Requires-Python: >=3.12.0
Description-Content-Type: text/markdown
License-File: LICENSE
Provides-Extra: test
Requires-Dist: check-manifest==0.51; extra == "test"
Requires-Dist: ruff==0.14.14; extra == "test"
Requires-Dist: pytest==9.0.2; extra == "test"
Dynamic: license-file

# netbox-site-context

Add context to your NetBox sites for automation and scripting.

- Free software: MIT
- Documentation: https://wouterdebruijn.github.io/netbox-site-context/

## Overview

This plugin brings NetBox's config-context concept to **sites**. You define
**Site Context** objects, each holding an arbitrary JSON dict, and scope them to
one or more site identifiers. For any given site, every context that applies is
**deep-merged by weight** into a single rendered dict — the same way config
contexts are resolved for devices.

## Features

- **Site Context objects** with a JSON `data` payload, a `weight`, an
  `is_active` flag, and a description.
- **Flexible scoping** — assign a context to any combination of regions, site
  groups, sites, tenant groups, and tenants. An empty assignment for a dimension
  matches every site. Region, site-group, and tenant-group assignments also
  match their descendants, so a context assigned to a parent region applies to
  sites in its child regions.
- **Weighted deep merge** — when several contexts apply to a site, their `data`
  is merged in ascending weight order, so a higher weight wins on conflicting
  keys. Nested dicts are merged recursively; lists and scalars are replaced.
- **Site detail tab** — a _Context_ tab is added to every site, showing the
  rendered (merged) context and the individual contexts that contributed to it.
- **REST API** for managing contexts, plus a dedicated endpoint that returns the
  rendered context for a given site.
- **GraphQL** queries for Site Context objects.
- Standard NetBox integration: change logging, journaling, tags, custom fields,
  global search, filtering, and the object-based permission system.

## Compatibility

This plugin requires **NetBox 4.6**.

| NetBox Version | Plugin Version |
| -------------- | -------------- |
| 4.6            | 0.1.1          |

For more detailed compatibility information, see
[COMPATIBILITY.md](COMPATIBILITY.md).

## Dependencies

This plugin requires:

- NetBox 4.6.x
- Python 3.12 or later

No additional Python packages are required beyond NetBox's core dependencies.

## Installing

For adding to a NetBox Docker setup see
[the general instructions for using netbox-docker with plugins](https://github.com/netbox-community/netbox-docker/wiki/Using-Netbox-Plugins).

You can install with pip:

```bash
pip install git+https://github.com/wouterdebruijn/netbox-site-context
```

or by adding to your `local_requirements.txt` or `plugin_requirements.txt`
(netbox-docker):

```bash
git+https://github.com/wouterdebruijn/netbox-site-context
```

Enable the plugin in `/opt/netbox/netbox/netbox/configuration.py`, or if you use
netbox-docker, your `/configuration/plugins.py` file:

```python
PLUGINS = [
    'netbox_site_context'
]

PLUGINS_CONFIG = {
    "netbox_site_context": {},
}
```

Run the migrations to create the plugin's database tables:

```bash
python manage.py migrate netbox_site_context
```

## Configuration

This plugin does not require any additional configuration. It has no
`PLUGINS_CONFIG` settings of its own.

## Usage

1. Create Site Contexts under **Plugins → Site Contexts**. For each context, set
   a `weight`, an optional scope (regions / site groups / sites / tenant groups
   / tenants), and the JSON `data`.
2. Open any site and select the **Context** tab to see the rendered context and
   the contexts that contributed to it.

### Example

Given two contexts:

| Name        | Weight | Scope           | Data                                                    |
| ----------- | ------ | --------------- | ------------------------------------------------------- |
| `global`    | 1000   | _(none)_        | `{"dns": {"servers": ["8.8.8.8"]}, "snmp": "public"}`   |
| `eu-region` | 2000   | Region = Europe | `{"dns": {"servers": ["1.1.1.1"]}, "ntp": ["eu.pool"]}` |

A site located in (or under) the Europe region renders:

```json
{
  "dns": { "servers": ["1.1.1.1"] },
  "snmp": "public",
  "ntp": ["eu.pool"]
}
```

The higher-weighted `eu-region` context wins on `dns.servers` (a list, so it is
replaced), while `snmp` is inherited from `global` and `ntp` is added.

## REST API

Standard CRUD for Site Context objects:

- `/api/plugins/netbox_site_context/site-contexts/` — list and create contexts
- `/api/plugins/netbox_site_context/site-contexts/<id>/` — retrieve, update,
  delete

Rendered context for a site (the deep-merged result of all applicable contexts):

- `/api/plugins/netbox_site_context/sites/<site_id>/rendered-context/`

```json
{
  "site_id": 1,
  "site": "AMS1",
  "context": { "dns": { "servers": ["1.1.1.1"] }, "snmp": "public" }
}
```

## GraphQL

The plugin exposes Site Contexts through NetBox's GraphQL API via the
`site_context` and `site_context_list` queries:

```graphql
query {
  site_context_list {
    id
    name
    weight
    is_active
    data
  }
}
```

## pynetbox client extension

For scripting and automation against the REST API, a companion
[pynetbox](https://github.com/netbox-community/pynetbox) extension is published
as a **separate, lightweight package**:
[`site-context-extension`](https://pypi.org/project/site-context-extension/). It
teaches pynetbox about this plugin's objects and adds a helper for fetching a
site's rendered context. Installing it pulls in only `pynetbox` — none of the
NetBox plugin source or its server-side dependencies.

```bash
pip install site-context-extension
```

```python
import pynetbox

from site_context_extension import SiteContextExtension, rendered_site_context

nb = pynetbox.api(
    "https://netbox.example.com",
    token="<your-api-token>",
    extensions=[SiteContextExtension],
)

# CRUD over Site Context objects
for ctx in nb.plugins.netbox_site_context.site_contexts.all():
    print(ctx.name, ctx.weight, ctx.data)

# The rendered (deep-merged) context for a site
rendered = rendered_site_context(nb, site_id=2)
if rendered is not None:
    print(rendered.context)
```

The extension's source lives in [extension/](extension/); see
[extension/README.md](extension/README.md) for details.

## Contributing

Contributions are welcome! Please see [CONTRIBUTING.md](CONTRIBUTING.md) for
guidelines.

### Reporting Bugs

Please report bugs by opening an issue on our
[GitHub Issues](https://github.com/wouterdebruijn/netbox-site-context/issues)
page. When reporting bugs, please include:

- NetBox version
- Plugin version
- Python version
- Steps to reproduce
- Expected behavior
- Actual behavior

### Feature Requests

Feature requests can be submitted as
[GitHub Issues](https://github.com/wouterdebruijn/netbox-site-context/issues)
with the "enhancement" label.

## Support

- **Documentation**: https://wouterdebruijn.github.io/netbox-site-context/
- **Issues**: https://github.com/wouterdebruijn/netbox-site-context/issues
- **Discussions**:
  https://github.com/wouterdebruijn/netbox-site-context/discussions
- **NetBox Community Slack**: [netdev-community.slack.com](https://netdev.chat/)

## Credits

Based on the NetBox plugin tutorial:

- [demo repository](https://github.com/netbox-community/netbox-plugin-demo)
- [tutorial](https://github.com/netbox-community/netbox-plugin-tutorial)

This package was created with
[Cookiecutter](https://github.com/audreyr/cookiecutter) and the
[`netbox-community/cookiecutter-netbox-plugin`](https://github.com/netbox-community/cookiecutter-netbox-plugin)
project template.
