Sven Luthi 4d18dfde33 new file: .gitea/workflows/publish.yml
new file:   .github/workflows/publish.yml
Add publishing pipelines
2026-10-27 11:16:39 +01:00
2026-08-16 13:10:26 +02:00
2026-08-16 13:10:26 +02:00
2026-08-16 13:10:26 +02:00
2026-08-16 13:10:26 +02:00
2026-08-16 13:10:26 +02:00
2026-08-16 13:10:26 +02:00
2026-08-16 13:10:26 +02:00
2026-10-27 11:15:57 +01:00

NetBox Services Plugin

A NetBox plugin for declarative service templates with requirement trees.

DISCLAIMER: THIS PROJECT IS VIBE CODED USING AN LLM.

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

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":

- 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

S
Description
No description provided
Readme MIT
136 KiB
0 Stars 1 Watchers 0 Forks
Languages
Python 92.4%
HTML 7.1%
Shell 0.5%