
Netbox is the best open source DCIM/IPAM available. It is clear when you start playing with it that it is written by the people that use it, rather than people that want to sell it.
This post is about a feature of Netbox that allows you run python scripts from within the UI. It allows the user to extend the functionality of Netbox in a direction that matches the needs to the particular installation. If you can code in Python you make Netbox do exactly what you want to do, rather than wait for the process of working with the community on github to create a feature request or even add the functionality as a contribution.
Perhaps you can use this as a test bed for a feature that you might later want to contribute to the main code.
The Netbox script feature allows you to run any Python script. That isn’t a unique thing since you can run python scripts from the command line. It can also access Netbox data as variables and even make changes to the Netbox database. Though this isn’t unique. There is even a python library for Netbox to do all of this without bringing up a web browser. So the unique point of the feature is to run Python scripts within the Netbox UI.
This might seem a small point for the confident coder but consider that for every technically astute engineer who has installed netbox and can programme a bit, there are a bunch of regular network engineers who just want to use the tool to perform their job function. I’d guess the majority of pure network engineers can’t code at all and so even the act of running a python script might seem a challenge. By allowing organisation specific scripts to run in the same GUI as the place engineers go to perform basic job functions allows the scripts to reach a wider audience.
Example Script
The Netbox documentation does a good job of describing how to create custom scripts so I’m not going to provide a tutorial. You need to be able to code python and save a text file in the right directory (normally /opt/netbox/netbox/scripts). Thats it. There are some specific code structures you’ll need to learn so that Netbox can interact with the script. Mainly to place the code you want Netbox to take note of within a class that inherits from the extras.scripts.Script code base. You define a run() method which is where the magic happens. Everything else is optional
Options include adding a ‘return’ line so that text appears in the output tab in the GUI after the script completes. You can also provide input into the script in a range of GUI based methods such as a validated text box. In the example below a single string is requested (a MAC address) and you can specify things like max length or a regex which the string must match against.
So putting this together the feature could be used to create a custom form for the input of data into netbox, which validates what the person is typing and maybe also goes to an external source to get some data. Maybe you could type a hostname of something you want to add to netbox and the script finds the switch this is attached to and creates the connections for you on top of adding the IP address to the IPAM database.
My sample below is the complete file needed. It isn’t much more than Hello World and simply provides all the other formats you might need for a MAC address you enter into the text box. It allows you to see how the class is structured, input is gained from the GUI and text is put to the output tab after runtime.
Note that in the source tab you only see the class definition and not the complete file. Other classes and import statements aren’t shown. If you have more than one class definition you will see multiple items in the list of scripts to run in the GUI (each under the heading of the filename).
from extras.scripts import *
from netaddr import *
class MacFind(Script):
class Meta:
name = "Show MAC address formats"
description = "provides all the different formats for a given MAC address"
mac1 = StringVar(max_length=20, label="Mac Address?", required=True)
def run(self, data, commit):
class mac_comware(mac_cisco): pass
mac_comware.word_sep = '-'
mac_comware.word_size = 16
class mac_procurve(mac_pgsql): pass
mac_procurve.word_sep = '-'
mac_procurve.word_size = 24
mac1 = data['mac1']
badMac=False #start with assuming MAC is valid
hexChars = ["0","1","2","3","4","5","6","7","8","9","a","b","c","d","e","f"]
mac2=mac1.translate(str.maketrans('', '', '-:_'))
if len(mac2) != 12: #if MAC address isn't 12 chars then it is invalid
badMac=True
for i in mac2.lower(): #if MAC address contains non HEX chars then mark invalid
if i not in hexChars :
badMac=True
if badMac==True: #if MAC is invalid..
output = 'MAC Address is invalid'
else:
output = ("original: " + str(mac1))
output = output + '\n' + ("mac_cisco: " + str(EUI(mac1, dialect = mac_cisco)))
output = output + '\n' + ("mac_unix_expanded: " + str(EUI(mac1, dialect = mac_unix_expanded)))
output = output + '\n' + ("mac_bare: " + str(EUI(mac1, dialect = mac_bare)))
output = output + '\n' + ("mac_pgsql: " + str(EUI(mac1, dialect = mac_pgsql)))
output = output + '\n' + ("mac_unix: " + str(EUI(mac1, dialect = mac_unix)))
output = output + '\n' + ("mac_eui: " + str(EUI(mac1)))
output = output + '\n' + ("mac_comware: " + str(EUI(mac1, dialect = mac_comware)))
output = output + '\n' + ("mac_procurve: " + str(EUI(mac1, dialect = mac_procurve)))
try: #needed because easy to get an exception when a MAC isn't registered in OUI db
output = output + '\n' + "vendor= " + (EUI(mac1).oui.registration().org)
except Exception:
pass
output = output + '\n' + ("can't find MAC in database")
return(output)
There is nothing to do except to create the python file in the right directory. It is instantly available to use in the GUI. Below is what you get from the above script. Pasting in a MAC address and running the script gives the output log (which can be enhanced in your script) together with the output tab.


The script pasted here is not complente. Function printMacs is not defined and this provides error when executing.
LikeLike
Hi, thank you for posting and apologies that I haven’t visited the site since June.
I’ve updated the article with the actual file I have on a running Netbox. Please give it a go and see if it works.
LikeLike