Skip to main content

Branch Review for NetBox

Project description

Netbox-Branch-Review

Branch-aware change request & approval workflow for NetBox that can gate branch merges until a Change Request (CR) is approved.

Features

  • Create and track Change Requests linked to branches
  • One- or two-level approvals (configurable)
  • Merge gate: blocks merges until CR is approved or scheduled
  • Simple UI actions: Approve and Merge from the CR detail page
  • API serializers/viewset for integration
  • Optional peer review action & audit log of approvals / merge events
  • Revoke (undo) approvals before implementation, resetting status to Pending

Requirements

  • NetBox 4.x
  • Netbox-Branching plugin for branch operations (the merge gate integrates with it)
  • Python 3.10+

Installation

  1. Install the plugin:
pip install netbox-branch-review 
  1. Enable in NetBox configuration.py:
PLUGINS = [
    "netbox_branch_review",
    "netbox_branching",
]

PLUGINS_CONFIG = {
    "netbox_branch_review": {
        # Require two approvals before merge (default: True)
        "require_two_approvals": True,
        # Enforce branching integration (default: True)
        "enforce_branching": True,
    # Approval implies branch changes are acceptable; merge button appears once approved.
    }
}
  1. Migrate:
python manage.py migrate
  1. Restart NetBox.

Quick Start (Groups & Permissions)

Run the management command to create/sync default groups and permissions:

python manage.py sync_change_review

This will ensure:

  • Group "Change Managers" gets approve / merge / peer review permissions.
  • Group "Change Reviewers" gets only the peer review permission.

Customize names:

python manage.py sync_change_review --managers "My Managers" --reviewers "My Reviewers"

Skip peer group creation:

python manage.py sync_change_review --no-peer-group

Usage

Approval & Peer Review Flow

Config key: require_two_approvals (default True) Self full approval: allow_self_full_approval (default True) lets the CR creator (who has approval permission) fully approve in one action even when two approvals are normally required (records both levels in audit with an implicit second approval entry).

Scenario Action 1 Action 2 Status progression
Two approvals required First approval (different user recorded, or creator self-approval if allowed) Second approval (must be different user unless self full approval triggered) Pending → In review → Approved (or direct to Approved if self full)
Single approval mode First approval (Further approvals blocked for same user) Pending → Approved

Peer Review (optional): A user with only peer_review_changerequest can record a peer review before approval. Peer reviews do NOT change status; they are logged for audit & visibility.

Merge sets status to “Implemented”. Duplicate approvals or attempts after final approval are logged and safely ignored.

The merge gate validator require_cr_approved_before_merge enforces:

  • Two approvals when configured
  • Status must be Approved or Scheduled

Permissions & Suggested Groups

Custom permissions defined on the model: ChangeRequest.Meta.permissions

Codename Purpose
approve_changerequest Perform L1/L2 approvals (depending on config)
merge_changerequest Execute merge / implement action
peer_review_changerequest Record a peer review (no status change)
revoke_changerequest Revoke existing approvals (pre-implementation)

Because NetBox’s Group UI currently only lists standard model permissions in the multiselect, custom codenames may not appear for manual selection. The plugin’s post_migrate signal ensures they are created; you can assign them via shell if needed.

Suggested groups:

  • Change Managers: approve_changerequest, merge_changerequest (optionally also peer_review_changerequest).
  • Change Reviewers: peer_review_changerequest (and view_changerequest if not already provided globally).

Example shell assignment:

python manage.py shell -c "from django.contrib.auth.models import Group,Permission; mgr,_=Group.objects.get_or_create(name='Change Managers'); rev,_=Group.objects.get_or_create(name='Change Reviewers'); mgr.permissions.add(*Permission.objects.filter(codename__in=['approve_changerequest','merge_changerequest','peer_review_changerequest'])); rev.permissions.add(Permission.objects.get(codename='peer_review_changerequest'))"

Check a user’s effective perms:

python manage.py shell -c "from django.contrib.auth import get_user_model; u=get_user_model().objects.get(username='alice'); print([p for p in sorted(u.get_all_permissions()) if p.startswith('netbox_branch_review.')])"

Audit Log

Each approval, peer review, merge, revoke, or blocked duplicate attempt writes an entry to ChangeRequestAudit (displayed on the CR detail page). The last 10 entries render as badges; extend as needed.

Revoking Approvals (Undo)

Users with revoke_changerequest can revert a Change Request back to Pending (prior to implementation). This:

  1. Creates audit entries for each revoked level (L2 then L1) plus a summary revoke_full entry.
  2. Clears approver_1, approver_2 and their timestamps.
  3. Sets status to pending.

Limitations:

  • Can't revoke after status reaches Implemented.
  • Self full approvals (implicit level 2) will be fully cleared in one revoke action.

UI: A Revoke Approvals button appears when (a) the user has the permission, (b) the CR isn't implemented, and (c) at least one approval exists.

API

Note: Expose routes via the NetBox plugin API router as needed. The serializer exposes all CR fields, including ticket.

Project layout

netbox-branch-review/
├── pyproject.toml
├── README.md
└── netbox_branch_review/
    ├── __init__.py
    # (plugin.py not used; configuration lives in __init__.py)
    ├── models.py
    ├── choices.py
    ├── forms.py
    ├── filtersets.py
    ├── tables.py
    ├── navigation.py
    ├── menu.py
    ├── urls.py
    ├── views.py
    ├── signals.py
    ├── validators.py
    ├── api/
    │   ├── __init__.py
    │   ├── serializers.py
    │   └── views.py
    ├── templates/
    │   └── netbox_branch_review/
    │       ├── changerequest_list.html
    │       ├── changerequest.html
    │       └── includes/
    │           └── changerequest_header.html
    └── migrations/
    ├── 0001_initial.py
    ├── 0002_add_description.py
    ├── 0003_merge.py
    └── 0004_add_comments.py

Notes

  • The plugin registers the merge gate during ready() by calling register_pre_merge_validator() if available (see __init__.py). If the branching plugin is not present, merge enforcement gracefully no-ops, and UI will warn when branch data
  • Default groups may also be auto-created during post_migrate based on plugin settings (see __init__.py and signals.py), but the management command provides a clear, repeatable onboarding step.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

netbox_branch_review-0.1.8.tar.gz (20.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

netbox_branch_review-0.1.8-py3-none-any.whl (24.7 kB view details)

Uploaded Python 3

File details

Details for the file netbox_branch_review-0.1.8.tar.gz.

File metadata

  • Download URL: netbox_branch_review-0.1.8.tar.gz
  • Upload date:
  • Size: 20.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.10.12

File hashes

Hashes for netbox_branch_review-0.1.8.tar.gz
Algorithm Hash digest
SHA256 fde3ffe27d79b7d443e936be652593c9e67819c5cc39e96049084826ac5c7c4a
MD5 4e0a40773960df24d39a6c2f0c99680e
BLAKE2b-256 a9ab050128e98d09aabb8fffbb1a8de31b6a98de1c209cbac383bd9e22b6914e

See more details on using hashes here.

File details

Details for the file netbox_branch_review-0.1.8-py3-none-any.whl.

File metadata

File hashes

Hashes for netbox_branch_review-0.1.8-py3-none-any.whl
Algorithm Hash digest
SHA256 63a4984c40a0d6b0f9267aa63a0ee050882e089ff20b1e42f3014da1a8e12efb
MD5 9bf066f1816b47be6ab5d237d086debc
BLAKE2b-256 ec85cf8f8803eeaba5e47358b2ed6156e91d17dd8c2f72add901d99dbe5ba4b3

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page