Extend custom scripts to pass the 'commit' value via run()

This commit is contained in:
Jeremy Stretch 2020-02-25 14:49:41 -05:00
parent f643af13d7
commit 5000f7f8d7
3 changed files with 22 additions and 8 deletions

View File

@ -27,11 +27,17 @@ class MyScript(Script):
var2 = IntegerVar(...) var2 = IntegerVar(...)
var3 = ObjectVar(...) var3 = ObjectVar(...)
def run(self, data): def run(self, data, commit):
... ...
``` ```
The `run()` method is passed a single argument: a dictionary containing all of the variable data passed via the web form. Your script can reference this data during execution. The `run()` method should accept two arguments:
* `data` - A dictionary containing all of the variable data passed via the web form.
* `commit` - A boolean indicating whether database changes will be committed.
!!! note
The `commit` argument was introduced in NetBox v2.7.8. Backward compatibility is maintained for scripts which accept only the `data` argument, however moving forward scripts should accept both arguments.
Defining variables is optional: You may create a script with only a `run()` method if no user input is needed. Defining variables is optional: You may create a script with only a `run()` method if no user input is needed.
@ -196,7 +202,7 @@ These variables are presented as a web form to be completed by the user. Once su
``` ```
from django.utils.text import slugify from django.utils.text import slugify
from dcim.constants import * from dcim.choices import DeviceStatusChoices, SiteStatusChoices
from dcim.models import Device, DeviceRole, DeviceType, Site from dcim.models import Device, DeviceRole, DeviceType, Site
from extras.scripts import * from extras.scripts import *
@ -222,13 +228,13 @@ class NewBranchScript(Script):
) )
) )
def run(self, data): def run(self, data, commit):
# Create the new site # Create the new site
site = Site( site = Site(
name=data['site_name'], name=data['site_name'],
slug=slugify(data['site_name']), slug=slugify(data['site_name']),
status=SITE_STATUS_PLANNED status=SiteStatusChoices.STATUS_PLANNED
) )
site.save() site.save()
self.log_success("Created new site: {}".format(site)) self.log_success("Created new site: {}".format(site))
@ -240,7 +246,7 @@ class NewBranchScript(Script):
device_type=data['switch_model'], device_type=data['switch_model'],
name='{}-switch{}'.format(site.slug, i), name='{}-switch{}'.format(site.slug, i),
site=site, site=site,
status=DEVICE_STATUS_PLANNED, status=DeviceStatusChoices.STATUS_PLANNED,
device_role=switch_role device_role=switch_role
) )
switch.save() switch.save()

View File

@ -6,6 +6,7 @@
* [#4173](https://github.com/netbox-community/netbox/issues/4173) - Return graceful error message when webhook queuing fails * [#4173](https://github.com/netbox-community/netbox/issues/4173) - Return graceful error message when webhook queuing fails
* [#4227](https://github.com/netbox-community/netbox/issues/4227) - Omit internal fields from the change log data * [#4227](https://github.com/netbox-community/netbox/issues/4227) - Omit internal fields from the change log data
* [#4237](https://github.com/netbox-community/netbox/issues/4237) - Support Jinja2 templating for webhook payload and headers * [#4237](https://github.com/netbox-community/netbox/issues/4237) - Support Jinja2 templating for webhook payload and headers
* [#4262](https://github.com/netbox-community/netbox/issues/4262) - Extend custom scripts to pass the `commit` value via `run()`
* [#4267](https://github.com/netbox-community/netbox/issues/4267) - Denote rack role on rack elevations list * [#4267](https://github.com/netbox-community/netbox/issues/4267) - Denote rack role on rack elevations list
## Bug Fixes ## Bug Fixes

View File

@ -286,7 +286,7 @@ class BaseScript:
return vars return vars
def run(self, data): def run(self, data, commit):
raise NotImplementedError("The script must define a run() method.") raise NotImplementedError("The script must define a run() method.")
def as_form(self, data=None, files=None, initial=None): def as_form(self, data=None, files=None, initial=None):
@ -383,10 +383,17 @@ def run_script(script, data, request, commit=True):
# Add the current request as a property of the script # Add the current request as a property of the script
script.request = request script.request = request
# Determine whether the script accepts a 'commit' argument (this was introduced in v2.7.8)
kwargs = {
'data': data
}
if 'commit' in inspect.signature(script.run).parameters:
kwargs['commit'] = commit
try: try:
with transaction.atomic(): with transaction.atomic():
start_time = time.time() start_time = time.time()
output = script.run(data) output = script.run(**kwargs)
end_time = time.time() end_time = time.time()
if not commit: if not commit:
raise AbortTransaction() raise AbortTransaction()