From 1849a38abafab8da1d6b3c0f05060aba3dd4aa64 Mon Sep 17 00:00:00 2001 From: jeremystretch Date: Mon, 14 Nov 2022 11:01:04 -0500 Subject: [PATCH] Add documentation for change staging --- docs/models/extras/branch.md | 13 +++++++ docs/models/extras/stagedchange.md | 26 ++++++++++++++ docs/plugins/development/staged-changes.md | 42 ++++++++++++++++++++++ mkdocs.yml | 3 ++ 4 files changed, 84 insertions(+) create mode 100644 docs/models/extras/branch.md create mode 100644 docs/models/extras/stagedchange.md create mode 100644 docs/plugins/development/staged-changes.md diff --git a/docs/models/extras/branch.md b/docs/models/extras/branch.md new file mode 100644 index 000000000..be124ebde --- /dev/null +++ b/docs/models/extras/branch.md @@ -0,0 +1,13 @@ +# Branches + +A branch is a collection of related [staged changes](./stagedchange.md) that have been prepared for merging into the active database. A branch can be mered by executing its `commit()` method. Deleting a branch will delete all its related changes. + +## Fields + +### Name + +The branch's name. + +### User + +The user to which the branch belongs (optional). diff --git a/docs/models/extras/stagedchange.md b/docs/models/extras/stagedchange.md new file mode 100644 index 000000000..feda2fee6 --- /dev/null +++ b/docs/models/extras/stagedchange.md @@ -0,0 +1,26 @@ +# Staged Changes + +A staged change represents the creation of a new object or the modification or deletion of an existing object to be performed at some future point. Each change must be assigned to a [branch](./branch.md). + +Changes can be applied individually via the `apply()` method, however it is recommended to apply changes in bulk using the parent branch's `commit()` method. + +## Fields + +!!! warning + Staged changes are not typically created or manipulated directly, but rather effected through the use of the [`checkout()`](../../plugins/development/staged-changes.md) context manager. + +### Branch + +The [branch](./branch.md) to which this change belongs. + +### Action + +The type of action this change represents: `create`, `update`, or `delete`. + +### Object + +A generic foreign key referencing the existing object to which this change applies. + +### Data + +JSON representation of the changes being made to the object (not applicable for deletions). diff --git a/docs/plugins/development/staged-changes.md b/docs/plugins/development/staged-changes.md new file mode 100644 index 000000000..7a4446eea --- /dev/null +++ b/docs/plugins/development/staged-changes.md @@ -0,0 +1,42 @@ +# Staged Changes + +!!! danger "Experimental Feature" + This feature is still under active development and considered experimental in nature. Its use in production is strongly discouraged at this time. + +!!! note + This feature was introduced in NetBox v3.4. + +NetBox provides a programmatic API to stage the creation, modification, and deletion of objects without actually committing those changes to the active database. This can be useful for performing a "dry run" of bulk operations, or preparing a set of changes for administrative approval, for example. + +To begin staging changes, first create a [branch](../../models/extras/branch.md): + +```python +from extras.models import Branch + +branch1 = Branch.objects.create(name='branch1') +``` + +Then, activate the branch using the `checkout()` context manager and begin making your changes. This initiates a new database transaction. + +```python +from extras.models import Branch +from netbox.staging import checkout + +branch1 = Branch.objects.get(name='branch1') +with checkout(branch1): + Site.objects.create(name='New Site', slug='new-site') + # ... +``` + +Upon exiting the context, the database transaction is automatically rolled back and your changes recorded as [staged changes](../../models/extras/stagedchange.md). Re-entering a branch will trigger a new database transaction and automatically apply any staged changes associated with the branch. + +To apply the changes within a branch, call the branch's `commit()` method: + +```python +from extras.models import Branch + +branch1 = Branch.objects.get(name='branch1') +branch1.commit() +``` + +Committing a branch is an all-or-none operation: Any exceptions will revert the entire set of changes. After successfully committing a branch, all its associated StagedChange objects are automatically deleted (however the branch itself will remain and can be reused). diff --git a/mkdocs.yml b/mkdocs.yml index 011d4414f..a147785d9 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -131,6 +131,7 @@ nav: - REST API: 'plugins/development/rest-api.md' - GraphQL API: 'plugins/development/graphql-api.md' - Background Tasks: 'plugins/development/background-tasks.md' + - Staged Changes: 'plugins/development/staged-changes.md' - Exceptions: 'plugins/development/exceptions.md' - Search: 'plugins/development/search.md' - Administration: @@ -191,12 +192,14 @@ nav: - SiteGroup: 'models/dcim/sitegroup.md' - VirtualChassis: 'models/dcim/virtualchassis.md' - Extras: + - Branch: 'models/extras/branch.md' - ConfigContext: 'models/extras/configcontext.md' - CustomField: 'models/extras/customfield.md' - CustomLink: 'models/extras/customlink.md' - ExportTemplate: 'models/extras/exporttemplate.md' - ImageAttachment: 'models/extras/imageattachment.md' - JournalEntry: 'models/extras/journalentry.md' + - StagedChange: 'models/extras/stagedchange.md' - Tag: 'models/extras/tag.md' - Webhook: 'models/extras/webhook.md' - IPAM: