6.4 KiB
Custom Scripts
Custom scripting was introduced in NetBox v2.7 to provide a way for users to execute custom logic from within the NetBox UI. Custom scripts enable the user to directly and conveniently manipulate NetBox data in a prescribed fashion. They can be used to accomplish myriad tasks, such as:
- Automatically populate new devices and cables in preparation for a new site deployment
- Create a range of new reserved prefixes or IP addresses
- Fetch data from an external source and import it to NetBox
Custom scripts are Python code and exist outside of the official NetBox code base, so they can be updated and changed without interfering with the core NetBox installation. And because they're written from scratch, a custom script can be used to accomplish just about anything.
Writing Custom Scripts
All custom scripts must inherit from the extras.scripts.Script
base class. This class provides the functionality necessary to generate forms and log activity.
from extras.scripts import Script
class MyScript(Script):
..
Scripts comprise two core components: variables and a run()
method. Variables allow your script to accept user input via the NetBox UI. The run()
method is where your script's execution logic lives. (Note that your script can have as many methods as needed: this is merely the point of invocation for NetBox.)
class MyScript(Script):
var1 = StringVar(...)
var2 = IntegerVar(...)
var3 = ObjectVar(...)
def run(self, data):
...
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.
Defining variables is optional: You may create a script with only a run()
method if no user input is needed.
Returning output from your script is optional. Any raw output generated by the script will be displayed under the "output" tab in the UI.
Module Attributes
name
You can define name
within a script module (the Python file which contains one or more scripts) to set the module name. If name
is not defined, the filename will be used.
Script Attributes
Script attributes are defined under a class named Meta
within the script. These are optional, but encouraged.
name
This is the human-friendly names of your script. If omitted, the class name will be used.
description
A human-friendly description of what your script does.
fields
The order in which the variable fields should appear. This is optional, however on Python 3.5 and earlier the fields will appear in random order. (Declarative ordering is preserved on Python 3.6 and above.) For example:
fields = ['var1', 'var2', 'var3']
Logging
The Script object provides a set of convenient functions for recording messages at different severity levels:
log_debug
log_success
log_info
log_warning
log_failure
Log messages are returned to the user upon execution of the script.
Variable Reference
StringVar
Stores a string of characters (i.e. a line of text). Options include:
min_length
- Minimum number of charactersmax_length
- Maximum number of charactersregex
- A regular expression against which the provided value must match
Note: min_length
and max_length
can be set to the same number to effect a fixed-length field.
IntegerVar
Stored a numeric integer. Options include:
min_value:
- Minimum valuemax_value
- Maximum value
BooleanVar
A true/false flag. This field has no options beyond the defaults.
ObjectVar
A NetBox object. The list of available objects is defined by the queryset parameter. Each instance of this variable is limited to a single object type.
queryset
- A Django queryset
Default Options
All variables support the following default options:
label
- The name of the form fielddescription
- A brief description of the fielddefault
- The field's default valuerequired
- Indicates whether the field is mandatory (default: true)
Example
Below is an example script that creates new objects for a planned site. The user is prompted for three variables:
- The name of the new site
- The device model (a filtered list of defined device types)
- The number of access switches to create
These variables are presented as a web form to be completed by the user. Once submitted, the script's run()
method is called to create the appropriate objects.
from django.utils.text import slugify
from dcim.constants import *
from dcim.models import Device, DeviceRole, DeviceType, Site
from extras.scripts import *
class NewBranchScript(Script):
class Meta:
name = "New Branch"
description = "Provision a new branch site"
fields = ['site_name', 'switch_count', 'switch_model']
site_name = StringVar(
description="Name of the new site"
)
switch_count = IntegerVar(
description="Number of access switches to create"
)
switch_model = ObjectVar(
description="Access switch model",
queryset = DeviceType.objects.filter(
manufacturer__name='Cisco',
model__in=['Catalyst 3560X-48T', 'Catalyst 3750X-48T']
)
)
def run(self, data):
# Create the new site
site = Site(
name=data['site_name'],
slug=slugify(data['site_name']),
status=SITE_STATUS_PLANNED
)
site.save()
self.log_success("Created new site: {}".format(site))
# Create access switches
switch_role = DeviceRole.objects.get(name='Access Switch')
for i in range(1, data['switch_count'] + 1):
switch = Device(
device_type=data['switch_model'],
name='{}-switch{}'.format(site.slug, i),
site=site,
status=DEVICE_STATUS_PLANNED,
device_role=switch_role
)
switch.save()
self.log_success("Created new switch: {}".format(switch))
# Generate a CSV table of new devices
output = [
'name,make,model'
]
for switch in Device.objects.filter(site=site):
attrs = [
switch.name,
switch.device_type.manufacturer.name,
switch.device_type.model
]
output.append(','.join(attrs))
return '\n'.join(output)