Files
netbox-plugin-services/README.md
T
2026-08-16 13:10:26 +02:00

115 lines
3.6 KiB
Markdown

# NetBox Services Plugin
A NetBox plugin for declarative service templates with requirement trees.
## Overview
This plugin lets you define **service templates** that specify what NetBox
resources a service requires, without attaching any resources to the template
itself. Templates contain a **requirement tree** — a stacked, declarative
description of what objects are needed (devices, interfaces, IP addresses, etc.)
and how to select or allocate them.
One or more **services** are then spawned from these templates. When a service is
**resolved**, the resolver engine walks the requirement tree, evaluates selectors
and allocators against live NetBox data, and creates **resource bindings** that
link the service to real NetBox objects.
## Key Concepts
- **ServiceTemplate** — Reusable template with a declarative requirement tree
stored as JSON (editable as YAML or JSON in the UI). Locked once any service
instances are spawned from it.
- **Service** — A concrete instance spawned from a ServiceTemplate. Requires a
tenant.
- **ServiceResourceBinding** — Internal model (hidden from UI) that links a
service to a real NetBox object via a generic foreign key.
## Tree Structure
The requirement tree is a list of nodes. Each node specifies:
| Field | Description |
|-------|-------------|
| `name` | Unique name for the node |
| `object_type` | NetBox model as `app_label.model_name` (e.g. `dcim.device`) |
| `quantity` | How many objects to select/allocate (default: 1) |
| `selector` | How to find existing objects (see Selector Types) |
| `allocation` | How to create new objects (see Allocation Strategies) |
| `scope` | `service` (resolve once) or `parent` (resolve per selected parent) |
| `children` | List of child nodes (recursive) |
A node must have either a `selector` or an `allocation` (not both).
## Selector Types
| Type | Description |
|------|-------------|
| `netbox_filter` | Apply NetBox filter parameters to find existing objects |
| `reference` | Resolve a dotted context path (e.g. `parent.site`) |
| `prefix` | Find ipam.Prefix objects by filter or reference |
## Allocation Strategies
| Strategy | Description |
|----------|-------------|
| `first_free` | Allocate the first available IP from a resolved prefix |
| `specific` | Use a specific object by address or context path |
## Reconciliation
When a service is re-resolved, the resolver performs **set reconciliation**:
- Objects in the new plan but not currently bound → **added**
- Objects currently bound but not in the new plan → **removed** (binding only; the underlying NetBox object is not deleted)
- Objects in both → **kept** unchanged
For allocation nodes, existing bound objects of the same type are reused before
allocating new ones (avoids duplicate IPs on re-resolve).
## Quick Start
```bash
cd dev/
podman-compose up -d
```
Access at `http://localhost:8001` (admin/admin).
## Example
A service template for "2 routers, each with a management IP from a prefix pool":
```yaml
- name: routers
object_type: dcim.device
quantity: 2
selector:
type: netbox_filter
filters:
role: router
scope: service
children:
- name: mgmt-ip
object_type: ipam.ipaddress
quantity: 1
allocation:
strategy: first_free
prefix:
type: prefix
filters:
site: hq
tag: mgmt
scope: parent
```
## REST API
- `GET/POST /api/plugins/services/service-templates/` — CRUD for templates
- `GET/POST /api/plugins/services/services/` — CRUD for services
- `POST /api/plugins/services/services/<id>/resolve/` — Resolve a service
- Body: `{"mode": "dry_run"}` or `{"mode": "commit"}`
## License
MIT