### Start NetBox Development Server Source: https://github.com/netboxlabs/netbox-branching/blob/main/AGENTS.md Starts the NetBox development server locally, with the NetBox Branching plugin loaded and active. ```bash python netbox/manage.py runserver ``` -------------------------------- ### Build and Start NetBox Docker Source: https://github.com/netboxlabs/netbox-branching/blob/main/docs/netbox-docker.md Build the NetBox Docker images using the custom configuration and then start the Docker containers in detached mode. ```bash docker compose build --no-cache ``` ```bash docker compose up -d ``` -------------------------------- ### Install NetBox Branching Plugin Source: https://github.com/netboxlabs/netbox-branching/blob/main/README.md Install the NetBox Branching plugin from PyPI using pip. Ensure your virtual environment is activated. ```bash $ pip install netboxlabs-netbox-branching ``` -------------------------------- ### Install Plugin with Dev and Test Extras Source: https://github.com/netboxlabs/netbox-branching/blob/main/AGENTS.md Installs the NetBox Branching plugin in editable mode, including development and testing dependencies. ```bash pip install -e '.[dev,test]' ``` -------------------------------- ### Install NetBox Requirements Source: https://github.com/netboxlabs/netbox-branching/blob/main/AGENTS.md Install the Python dependencies required by the NetBox project. ```bash pip install -r netbox/requirements.txt ``` -------------------------------- ### Install NetBox Branching Plugin via Pip Source: https://github.com/netboxlabs/netbox-branching/blob/main/docs/index.md Installs the netboxlabs-netbox-branching Python package using pip. ```bash pip install netboxlabs-netbox-branching ``` -------------------------------- ### Squash Merge Strategy Example Source: https://github.com/netboxlabs/netbox-branching/blob/main/docs/using-branches/syncing-merging.md Illustrates how the squash strategy collapses branch changes into a single operation before applying to main. It shows the branch changelog, the collapsed changes, and the final applied changes to main. ```text Branch changelog: [1] Create Site A (User: alice, 09:00) [2] Update Site A (User: bob, 09:45) [3] Update Site A (User: alice, 10:30) [4] Update Device B (User: bob, 10:15) Collapsed to: Create Site A (final attributes after all updates) Update Device B Applied to main: Create Site A → 1 ObjectChange in main (credited to the user who ran the merge) Update Device B → 1 ObjectChange in main (credited to the user who ran the merge) ``` -------------------------------- ### Plugin Installation Order for Branching Support Source: https://github.com/netboxlabs/netbox-branching/blob/main/docs/plugin-development.md Ensure `netbox_branching` is listed last in the `PLUGINS` configuration to enable branching support for models from plugins listed before it. Plugins listed after `netbox_branching` will not have their models enrolled. ```python PLUGINS = [ 'my_plugin', # branching support registered for my_plugin's models 'netbox_branching', # must be last ] ``` -------------------------------- ### Activate NetBox Virtual Environment Source: https://github.com/netboxlabs/netbox-branching/blob/main/README.md Activate the NetBox virtual environment before installing the plugin. The path to the virtual environment may vary. ```bash $ source /opt/netbox/venv/bin/activate ``` -------------------------------- ### Iterative Merge Strategy Example Source: https://github.com/netboxlabs/netbox-branching/blob/main/docs/using-branches/syncing-merging.md Illustrates how the iterative merge strategy replays individual ObjectChange log entries from a branch into main chronologically, preserving original attribution. ```text Branch changelog: [1] Create Site A (User: alice, 09:00) [2] Update Device B (User: bob, 10:15) [3] Delete Tenant C (User: alice, 11:30) Applied to main: Create Site A → 1 new ObjectChange in main (credited to alice, 09:00) Update Device B → 1 new ObjectChange in main (credited to bob, 10:15) Delete Tenant C → 1 new ObjectChange in main (credited to alice, 11:30) ``` -------------------------------- ### Connect to Post-Merge Signal Source: https://github.com/netboxlabs/netbox-branching/blob/main/docs/plugin-development.md React to branch lifecycle events by connecting to Django signals. This example shows how to hook into the post-merge signal. ```python from django.dispatch import receiver from netbox_branching.models import Branch from netbox_branching.signals import post_merge @receiver(post_merge, sender=Branch) def on_branch_merged(sender, branch, user, **kwargs): # Notify an external system, refresh a cache, etc. ... ``` -------------------------------- ### Configure NetBox Branching Plugin Source: https://github.com/netboxlabs/netbox-branching/blob/main/docs/configuration.md Set plugin-specific configuration options within NetBox's PLUGINS_CONFIG dictionary. This example shows how to set the maximum number of working branches and the stale warning threshold. ```python PLUGINS_CONFIG = { 'netbox_branching': { 'max_working_branches': 10, 'stale_warning_threshold': 14, }, } ``` -------------------------------- ### Registering a Branching Resolver Source: https://github.com/netboxlabs/netbox-branching/blob/main/docs/plugin-development.md Register a custom resolver from your plugin's `PluginConfig.ready()` method. Wrap the import in a try-except block to ensure compatibility when netbox-branching is not installed. ```python # my_plugin/__init__.py from netbox.plugins import PluginConfig class MyPluginConfig(PluginConfig): name = 'my_plugin' # ... def ready(self): super().ready() try: from netbox_branching.utilities import register_branching_resolver from .branching import my_resolver register_branching_resolver(my_resolver) except ImportError: pass # netbox-branching not installed; nothing to register ``` -------------------------------- ### Conflict Response Example (409 Conflict) Source: https://github.com/netboxlabs/netbox-branching/blob/main/docs/rest-api.md This JSON response is returned when conflicting changes exist on a branch. It details the nature of the conflicts, including the object type, ID, conflicting fields, and the differing data between the branch and main. ```json { "detail": "All conflicts must be acknowledged before this action can proceed.", "conflicts": [ { "id": 6, "object_type": "dcim.site", "object_id": 31, "object_repr": "s1", "action": { "value": "update", "label": "Updated" }, "conflicts": ["description", "tags"], "conflicting_data": { "original": { "description": "", "tags": [] }, "branch": { "description": "abc", "tags": ["Alpha", "Foxtrot"] }, "main": { "description": "def", "tags": ["Alpha", "Charlie", "Delta"] } }, "last_updated": "2024-08-12T17:07:10.442432Z" } ] } ``` -------------------------------- ### Configure Job Timeout for Branch Operations Source: https://github.com/netboxlabs/netbox-branching/blob/main/docs/configuration.md Adjust the maximum time in seconds that background jobs for branch operations (sync, merge, revert) are allowed to run. This example sets the timeout to 2 hours (7200 seconds). ```python PLUGINS_CONFIG = { 'netbox_branching': { 'job_timeout': 7200, # 2 hours } } ``` -------------------------------- ### Serve User Documentation Locally Source: https://github.com/netboxlabs/netbox-branching/blob/main/AGENTS.md Builds and serves the MkDocs-generated user documentation site locally for previewing. ```bash mkdocs serve ``` -------------------------------- ### Build Static Documentation Site Source: https://github.com/netboxlabs/netbox-branching/blob/main/AGENTS.md Builds the static HTML site for the user documentation using MkDocs. ```bash mkdocs build ``` -------------------------------- ### Symlink Configuration File Source: https://github.com/netboxlabs/netbox-branching/blob/main/AGENTS.md Create a symbolic link for the plugin's testing configuration file into the NetBox directory. ```bash ln -s "$PWD/nbl-netbox-branching/testing/configuration.py" netbox/netbox/netbox/configuration.py ``` -------------------------------- ### Configure Database and Router in configuration.py Source: https://github.com/netboxlabs/netbox-branching/blob/main/README.md Configure the database connection and the branch-aware router in `configuration.py`. Use `DynamicSchemaDict` for database configuration and specify the `BranchAwareRouter`. ```python from netbox_branching.utilities import DynamicSchemaDict DATABASES = DynamicSchemaDict({ 'default': { 'ENGINE': 'django.db.backends.postgresql', 'NAME': 'netbox', # Database name 'USER': 'netbox', # PostgreSQL username 'PASSWORD': 'password', # PostgreSQL password 'HOST': 'localhost', # Database server 'PORT': '', # Database port (leave blank for default) 'CONN_MAX_AGE': 300, # Max database connection age } }) DATABASE_ROUTERS = [ 'netbox_branching.database.BranchAwareRouter', ] ``` -------------------------------- ### Build Source Distribution and Wheel Source: https://github.com/netboxlabs/netbox-branching/blob/main/AGENTS.md Builds the source distribution (sdist) and wheel package for the plugin, matching the release workflow. ```bash python -m build ``` -------------------------------- ### Create Dockerfile for Plugins Source: https://github.com/netboxlabs/netbox-branching/blob/main/docs/netbox-docker.md Create a Dockerfile to build a NetBox image that includes the netbox-branching plugin. Ensure you substitute the correct NetBox and plugin versions. ```dockerfile FROM netboxcommunity/netbox:v4.6.0 RUN uv pip install netboxlabs-netbox-branching ``` -------------------------------- ### Configure NetBox Branching Plugin Source: https://github.com/netboxlabs/netbox-branching/blob/main/docs/netbox-docker.md Create a `plugins.py` file to configure the netbox-branching plugin. This includes specifying the plugin in the `PLUGINS` list and defining database connection settings, ensuring the `BranchAwareRouter` is used. ```python # If you have multiple plugins, netbox-branching _must_ come last PLUGINS = ["netbox_branching"] from netbox_branching.utilities import DynamicSchemaDict DATABASES = DynamicSchemaDict({ 'default': { 'ENGINE': 'django.db.backends.postgresql', 'NAME': 'netbox', # Database name 'USER': 'netbox', # PostgreSQL username 'PASSWORD': 'yourpassword', # PostgreSQL password 'HOST': 'postgres', # Database server 'PORT': '', # Database port (leave blank for default) 'CONN_MAX_AGE': 300, # Max database connection age } }) DATABASE_ROUTERS = [ 'netbox_branching.database.BranchAwareRouter', ] ``` -------------------------------- ### Run NetBox Database Migrations Source: https://github.com/netboxlabs/netbox-branching/blob/main/docs/index.md Applies the database migrations required by the NetBox branching plugin. ```bash cd /opt/netbox/netbox ./manage.py migrate ``` -------------------------------- ### Run NetBox Migrations Source: https://github.com/netboxlabs/netbox-branching/blob/main/README.md Run NetBox migrations after configuring the plugin and database settings. This command applies necessary database schema changes. ```bash $ ./manage.py migrate ``` -------------------------------- ### Clone NetBox Repository Source: https://github.com/netboxlabs/netbox-branching/blob/main/AGENTS.md Clone the NetBox repository alongside the plugin repository to set up a local development environment. ```bash git clone https://github.com/netbox-community/netbox.git ``` -------------------------------- ### Run Full Test Suite Source: https://github.com/netboxlabs/netbox-branching/blob/main/AGENTS.md Executes the complete test suite for the NetBox Branching plugin. The --keepdb flag preserves the database between test runs. ```bash python netbox/manage.py test netbox_branching.tests --keepdb ``` -------------------------------- ### Configure DynamicSchemaDict for Databases Source: https://github.com/netboxlabs/netbox-branching/blob/main/docs/index.md Wraps the DATABASES configuration with DynamicSchemaDict to support dynamic schema management for branches. ```python from netbox_branching.utilities import DynamicSchemaDict DATABASES = DynamicSchemaDict({ 'default': { 'ENGINE': 'django.db.backends.postgresql', 'NAME': 'netbox', 'USER': 'netbox', ... } }) ``` -------------------------------- ### Branching Workflow Sequence Diagram Source: https://github.com/netboxlabs/netbox-branching/blob/main/docs/index.md Illustrates the sequence of events in a typical branching workflow, from provisioning to merging. ```mermaid sequenceDiagram actor User B participant Main participant Branch actor User A Main->>Branch: Provision new branch User A->>Branch: Make changes User B->>Main: Make unrelated changes Main->>Branch: Synchronize changes User A->>Branch: Make more changes Branch->>Main: Merge branch ``` -------------------------------- ### Add NetBox Branching to PLUGINS Source: https://github.com/netboxlabs/netbox-branching/blob/main/README.md Add 'netbox_branching' to the PLUGINS list in your `configuration.py` file. It must be the last plugin listed. ```python PLUGINS = [ # ... 'netbox_branching', ] ``` -------------------------------- ### Configure Docker Compose Override Source: https://github.com/netboxlabs/netbox-branching/blob/main/docs/netbox-docker.md Create a `docker-compose.override.yml` file to specify the custom NetBox image with plugins and configure service settings. This ensures the custom image is used and sets up necessary environment variables and health checks. ```yaml services: netbox: image: netbox:v4.6.0-plugins pull_policy: never ports: - "8000:8080" build: context: . dockerfile: Dockerfile-Plugins environment: SKIP_SUPERUSER: "false" SUPERUSER_EMAIL: "" SUPERUSER_NAME: "admin" SUPERUSER_PASSWORD: "admin" healthcheck: test: curl -f http://127.0.0.1:8080/login/ || exit 1 start_period: 600s timeout: 3s interval: 15s postgres: ports: - "5432:5432" netbox-worker: image: netbox:v4.6.0-plugins pull_policy: never ``` -------------------------------- ### Branch Creation Response Source: https://github.com/netboxlabs/netbox-branching/blob/main/docs/rest-api.md The response to a successful branch creation request includes the branch's ID, URL, display name, status, owner details, and timestamps. The status will be 'new' initially and change to 'ready' upon completion of provisioning. ```json { "id": 2, "url": "http://netbox:8000/api/plugins/branching/branches/2/", "display": "Branch 1", "name": "Branch 1", "status": "new", "owner": { "id": 1, "url": "http://netbox:8000/api/users/users/1/", "display": "admin", "username": "admin" }, "description": "My new branch", "schema_id": "td5smq0f", "last_sync": null, "merged_time": null, "merged_by": null, "comments": "", "tags": [], "custom_fields": {}, "created": "2024-08-12T17:07:46.196956Z", "last_updated": "2024-08-12T17:07:46.196970Z" } ``` -------------------------------- ### Apply Django Migrations Source: https://github.com/netboxlabs/netbox-branching/blob/main/AGENTS.md Applies all pending database migrations for the NetBox application, including those for the netbox_branching plugin. ```bash python netbox/manage.py migrate ``` -------------------------------- ### Create a Branch Source: https://github.com/netboxlabs/netbox-branching/blob/main/docs/rest-api.md Branches can be created by sending a POST request to the /api/plugins/branching/branches/ endpoint with the desired attributes like name and description. A valid authentication token is required. ```APIDOC ## POST /api/plugins/branching/branches/ ### Description Creates a new branch with specified attributes. ### Method POST ### Endpoint /api/plugins/branching/branches/ ### Parameters #### Request Body - **name** (string) - Required - The name of the branch. - **description** (string) - Optional - A description for the branch. ### Request Example ```json { "name": "Branch 1", "description": "My new branch" } ``` ### Response #### Success Response (200) Returns the created branch object, including its ID, URL, status, and other attributes. #### Response Example ```json { "id": 2, "url": "http://netbox:8000/api/plugins/branching/branches/2/", "display": "Branch 1", "name": "Branch 1", "status": "new", "owner": { "id": 1, "url": "http://netbox:8000/api/users/users/1/", "display": "admin", "username": "admin" }, "description": "My new branch", "schema_id": "td5smq0f", "last_sync": null, "merged_time": null, "merged_by": null, "comments": "", "tags": [], "custom_fields": {}, "created": "2024-08-12T17:07:46.196956Z", "last_updated": "2024-08-12T17:07:46.196970Z" } ``` ``` -------------------------------- ### Lint Code with Ruff Source: https://github.com/netboxlabs/netbox-branching/blob/main/AGENTS.md Runs the Ruff linter to check for code style and potential errors. ```bash ruff check ``` -------------------------------- ### Clone NetBox Docker Repository Source: https://github.com/netboxlabs/netbox-branching/blob/main/docs/netbox-docker.md Clone the netbox-docker repository to your local machine and navigate into the directory. ```bash git clone https://github.com/netbox-community/netbox-docker.git pushd netbox-docker ``` -------------------------------- ### Branch Lifecycle States Source: https://github.com/netboxlabs/netbox-branching/blob/main/AGENTS.md Illustrates the possible states a branch can be in throughout its lifecycle, including transitional and terminal states. ```text NEW → PROVISIONING → READY → (SYNCING / MIGRATING / MERGING / REVERTING) → MERGED or ARCHIVED ``` -------------------------------- ### Generate Django Migrations Source: https://github.com/netboxlabs/netbox-branching/blob/main/AGENTS.md Creates new Django migration files for the netbox_branching app after making changes to its models. ```bash python netbox/manage.py makemigrations netbox_branching ``` -------------------------------- ### Configure Database Router for Branch Awareness Source: https://github.com/netboxlabs/netbox-branching/blob/main/docs/index.md Declares DATABASE_ROUTERS to use the plugin's custom router for branch-aware database operations. ```python DATABASE_ROUTERS = [ 'netbox_branching.database.BranchAwareRouter', ] ``` -------------------------------- ### Activate a Branch for API Requests Source: https://github.com/netboxlabs/netbox-branching/blob/main/docs/rest-api.md To make API requests within the context of a specific branch, include the `X-NetBox-Branch` HTTP header with the branch's schema ID. This header is required for operations that modify NetBox objects within a branch. ```APIDOC ## Using the X-NetBox-Branch Header ### Description Specifies the active branch for subsequent API requests. This is crucial for performing operations on objects within a particular branch. ### Method Any HTTP method (GET, POST, PUT, DELETE, etc.) ### Endpoint Any NetBox API endpoint (e.g., `/api/dcim/sites/`) ### Headers - **X-NetBox-Branch** (string) - Required - The schema ID of the branch to activate. Do not include the `branch_` prefix. - **Authorization** (string) - Required - Valid NetBox API token. - **Content-Type** (string) - Required for POST/PUT requests. - **Accept** (string) - Optional - Specifies desired response format. ### Request Example ```bash curl -X POST \ -H "Authorization: Token $TOKEN" \ -H "Content-Type: application/json" \ -H "Accept: application/json; indent=4" \ -H "X-NetBox-Branch: td5smq0f" \ http://netbox:8000/api/dcim/sites/ ``` ### Deactivation The branch is effectively deactivated for future API requests by simply omitting the `X-NetBox-Branch` header. ``` -------------------------------- ### Restart NetBox Services Source: https://github.com/netboxlabs/netbox-branching/blob/main/docs/index.md Restarts the NetBox and NetBox-RQ services to apply the plugin changes. ```bash sudo systemctl restart netbox netbox-rq ``` -------------------------------- ### Snapshotting Object Before Mutation in NetBox Branch Source: https://github.com/netboxlabs/netbox-branching/blob/main/docs/best-practices.md When programmatically modifying an object in a NetBox branch, call `obj.snapshot()` before mutation to capture the 'before' state. This ensures accurate changelog entries and enables proper conflict detection during merges. ```python interface = Interface.objects.get(pk=interface_id) interface.snapshot() # capture the "before" state interface.description = 'Updated by script' interface.save() ``` -------------------------------- ### Activate Branch for API Requests Source: https://github.com/netboxlabs/netbox-branching/blob/main/docs/rest-api.md To make API requests within a specific branch, include the 'X-NetBox-Branch' HTTP header with the branch's schema ID. This header is required for modifying objects within a branch context but not for managing branches themselves. ```no-highlight curl -X POST \ -H "Authorization: Token $TOKEN" \ -H "Content-Type: application/json" \ -H "Accept: application/json; indent=4" \ -H "X-NetBox-Branch: td5smq0f" \ http://netbox:8000/api/dcim/sites/ ``` -------------------------------- ### Run Single Test Module Source: https://github.com/netboxlabs/netbox-branching/blob/main/AGENTS.md Executes tests from a specific module within the NetBox Branching test suite. The --keepdb flag preserves the database between test runs. ```bash python netbox/manage.py test netbox_branching.tests.test_branches --keepdb ``` -------------------------------- ### Create a Branch via REST API Source: https://github.com/netboxlabs/netbox-branching/blob/main/docs/rest-api.md Use a POST request to the branches API endpoint to create a new branch with specified attributes. Ensure you include a valid authorization token and set the content type to JSON. ```no-highlight curl -X POST \ -H "Authorization: Token $TOKEN" \ -H "Content-Type: application/json" \ -H "Accept: application/json; indent=4" \ http://netbox:8000/api/plugins/branching/branches/ \ --data '{"name": "Branch 1", "description": "My new branch"}' ``` -------------------------------- ### Integrate Branch Context into Event Pipeline Source: https://github.com/netboxlabs/netbox-branching/blob/main/docs/configuration.md Add the plugin's context function to the NetBox EVENTS_PIPELINE to include branch information in event processing. This must be placed before 'extras.events.process_event_queue'. ```python EVENTS_PIPELINE = [ 'netbox_branching.events.add_branch_context', 'extras.events.process_event_queue', ] ``` -------------------------------- ### Synchronize Branch Changes Source: https://github.com/netboxlabs/netbox-branching/blob/main/docs/rest-api.md Send a POST request to the branch's sync endpoint to synchronize updates from main. The 'commit' argument can be set to 'false' for a dry run. ```no-highlight curl -X POST \ -H "Authorization: Token $TOKEN" \ -H "Content-Type: application/json" \ -H "Accept: application/json; indent=4" \ http://netbox:8000/api/plugins/branching/branches/2/sync/ \ --data '{"commit": true}' ``` -------------------------------- ### Exempt All Plugin Models from Branching Source: https://github.com/netboxlabs/netbox-branching/blob/main/docs/plugin-development.md Use a wildcard pattern to exempt all models within a specific plugin from NetBox branching support. This is useful for plugins where no models require isolated staging. ```python exempt_models = ['my_plugin.*'] ``` -------------------------------- ### Register Validators via Plugin Configuration Source: https://github.com/netboxlabs/netbox-branching/blob/main/docs/plugin-development.md Configure validator import paths in your NetBox plugin's settings. This is the simplest method for registering validators. ```python PLUGINS_CONFIG = { 'netbox_branching': { 'sync_validators': [ 'my_plugin.validators.require_sync_approval', ], 'merge_validators': [ 'my_plugin.validators.check_external_ticket', ], 'migrate_validators': [], 'revert_validators': [], 'archive_validators': [], } } ``` -------------------------------- ### Add REST API Endpoint Source: https://github.com/netboxlabs/netbox-branching/blob/main/AGENTS.md Steps to add a new REST API endpoint for a model in the NetBox Branching plugin, including serializer, viewset, URL registration, and integration tests. ```python from rest_framework.decorators import action ``` -------------------------------- ### Revert Branch Merge Sequence Diagram Source: https://github.com/netboxlabs/netbox-branching/blob/main/docs/index.md Shows the sequence for reverting a merged branch and re-applying corrected changes. ```mermaid sequenceDiagram participant Main participant Branch actor User A Main->>Branch: Provision new branch User A->>Branch: Make changes Branch->>Main: Merge branch Note left of Main: Error detected! Main->>Branch: Revert changes User A->>Branch: Correct error Branch->>Main: Merge branch ``` -------------------------------- ### Register Validators Programmatically Source: https://github.com/netboxlabs/netbox-branching/blob/main/docs/plugin-development.md Register validators from your plugin's AppConfig.ready() method using Branch.register_preaction_check(). This offers programmatic control over validator registration. ```python # my_plugin/__init__.py from netbox.plugins import PluginConfig class MyPluginConfig(PluginConfig): name = 'my_plugin' # ... def ready(self): super().ready() from netbox_branching.models import Branch from .validators import check_external_ticket Branch.register_preaction_check(check_external_ticket, 'merge') ``` -------------------------------- ### Configure Stale Branch Warning Threshold Source: https://github.com/netboxlabs/netbox-branching/blob/main/docs/configuration.md Set the number of days before a branch becomes stale to display a warning. Set to 0 to disable. ```python PLUGINS_CONFIG = { 'netbox_branching': { 'stale_warning_threshold': 14, } } ``` -------------------------------- ### Resolver for Dynamically-Generated Through Tables Source: https://github.com/netboxlabs/netbox-branching/blob/main/docs/plugin-development.md This resolver marks dynamically-generated M2M through tables within the 'my_plugin' app as branchable based on their model name pattern. This ensures relationship rows are stored in the correct branch schema. ```python # my_plugin/branching.py def supports_branching_resolver(model): """Mark dynamically-generated M2M through tables as branchable.""" meta = getattr(model, '_meta', None) if meta is None or meta.app_label != 'my_plugin': return None if (meta.model_name or '').startswith('through_my_plugin_'): return True return None ``` -------------------------------- ### Resolver Function Signature Source: https://github.com/netboxlabs/netbox-branching/blob/main/docs/plugin-development.md A resolver function takes a model class and returns a boolean or None to determine branchability. True means branchable, False means always route to main, and None defers to the next resolver or default heuristic. ```python def my_resolver(model) -> bool | None: ... ``` -------------------------------- ### Retrieve Change Diff Details via API Source: https://github.com/netboxlabs/netbox-branching/blob/main/docs/rest-api.md Use this cURL command to fetch full details for a specific change diff record, identified by its ID. This is useful for investigating individual conflicts. ```bash curl -X GET \ -H "Authorization: Token $TOKEN" \ -H "Accept: application/json; indent=4" \ http://netbox:8000/api/plugins/branching/changes/6/ ``` -------------------------------- ### Acknowledge Conflicts During Sync Source: https://github.com/netboxlabs/netbox-branching/blob/main/docs/rest-api.md This cURL command demonstrates how to acknowledge and resolve conflicts during a sync operation by including `"acknowledge_conflicts": true` in the request body. This action will overwrite main with the branch's version of conflicting fields. ```bash curl -X POST \ -H "Authorization: Token $TOKEN" \ -H "Content-Type: application/json" \ -H "Accept: application/json; indent=4" \ http://netbox:8000/api/plugins/branching/branches/2/sync/ \ --data '{"commit": true, "acknowledge_conflicts": true}' ``` -------------------------------- ### Grant PostgreSQL Schema Creation Permission Source: https://github.com/netboxlabs/netbox-branching/blob/main/README.md Grant the NetBox database user permission to create schemas in the PostgreSQL database. Replace `$database` and `$user` with your actual database name and user. ```postgresql GRANT CREATE ON DATABASE $database TO $user; ``` -------------------------------- ### Sync Branch with Conflicts Source: https://github.com/netboxlabs/netbox-branching/blob/main/docs/rest-api.md When syncing a branch, if conflicts exist, the API will return a 409 Conflict status. The response includes details about the conflicts, such as the object type, ID, and the specific fields that have diverged. To proceed, conflicts must be acknowledged. ```APIDOC ## POST /api/plugins/branching/branches/{branch_id}/sync/ ### Description Synchronizes a branch with its parent, potentially merging changes. If conflicts are detected, a 409 response is returned. Conflicts can be acknowledged by including `"acknowledge_conflicts": true` in the request body. ### Method POST ### Endpoint `/api/plugins/branching/branches/{branch_id}/sync/` ### Parameters #### Path Parameters - **branch_id** (integer) - Required - The ID of the branch to sync. #### Request Body - **commit** (boolean) - Optional - Whether to commit the sync operation. - **acknowledge_conflicts** (boolean) - Optional - If true, acknowledges all detected conflicts, allowing the sync to proceed by overwriting conflicting fields in the main branch with the branch's version. ### Request Example ```json { "commit": true, "acknowledge_conflicts": true } ``` ### Response #### Success Response (200 OK) - **detail** (string) - A message indicating the sync was successful. #### Error Response (409 Conflict) - **detail** (string) - A message indicating that conflicts must be acknowledged. - **conflicts** (array) - A list of objects detailing each conflict. - **id** (integer) - The PK of the `ChangeDiff` record. - **object_type** (string) - The type of the affected object (e.g., `dcim.site`). - **object_id** (integer) - The PK of the affected object. - **object_repr** (string) - Human-readable name of the affected object. - **action** (object) - The change action on the branch (`create`, `update`, or `delete`). - **value** (string) - The action value (e.g., "update"). - **label** (string) - The action label (e.g., "Updated"). - **conflicts** (array of strings) - List of field names where the branch and main have diverged. - **conflicting_data** (object) - Three-way view of the conflicting fields. - **original** (object) - The state of the fields at branch creation. - **branch** (object) - The current value of the fields in the branch. - **main** (object) - The current value of the fields in the main branch. - **last_updated** (string) - The timestamp of the last update for the conflict. ### Response Example (409 Conflict) ```json { "detail": "All conflicts must be acknowledged before this action can proceed.", "conflicts": [ { "id": 6, "object_type": "dcim.site", "object_id": 31, "object_repr": "s1", "action": { "value": "update", "label": "Updated" }, "conflicts": ["description", "tags"], "conflicting_data": { "original": { "description": "", "tags": [] }, "branch": { "description": "abc", "tags": ["Alpha", "Foxtrot"] }, "main": { "description": "def", "tags": ["Alpha", "Charlie", "Delta"] } }, "last_updated": "2024-08-12T17:07:10.442432Z" } ] } ``` ``` -------------------------------- ### Exempt Plugin Models from Branching Source: https://github.com/netboxlabs/netbox-branching/blob/main/docs/plugin-development.md Configure NetBox to exclude specific plugin models from branching support by listing them in the `exempt_models` setting. This ensures changes to these models affect the main schema immediately. ```python PLUGINS_CONFIG = { 'netbox_branching': { 'exempt_models': [ 'my_plugin.mymodel', ], } } ``` -------------------------------- ### Branch Synchronization Response Source: https://github.com/netboxlabs/netbox-branching/blob/main/docs/rest-api.md A successful synchronization request returns data about the background job enqueued to handle the synchronization. This response includes job details and status. ```json { "id": 4, "url": "http://netbox:8000/api/core/jobs/4/", "display_url": "http://netbox:8000/core/jobs/4/", "display": "f0c6dea2-d5bb-4683-851e-2ac705510af4", "object_type": "netbox_branching.branch", "object_id": 2, "name": "Sync branch", "status": { "value": "pending", "label": "Pending" }, "created": "2024-08-12T17:27:57.448405Z", "scheduled": null, "interval": null, "started": null, "completed": null, "user": { "id": 1, "url": "http://netbox:8000/api/users/users/1/", "display": "admin", "username": "admin" }, "data": null, "error": "", "job_id": "f0c6dea2-d5bb-4683-851e-2ac705510af4" } ``` -------------------------------- ### Branch Job Operations Source: https://github.com/netboxlabs/netbox-branching/blob/main/AGENTS.md Details the types of background jobs used for managing branch operations, such as provisioning, syncing, merging, and reverting. ```text ProvisionBranchJob | Create the schema and copy the database SyncBranchJob | Pull changes from main into the branch MergeBranchJob | Apply branch changes to main RevertBranchJob | Undo a merged branch's changes MigrateBranchJob | Apply outstanding Django migrations to the branch schema ```