Table of Contents
Today I was working to demonstrate how to get started with Nautobot Jobs within the Jobs root of Nautobot. This is not a pattern that I develop often, as I am typically developing Jobs within a plugin as my development standard. More to come on that later. During this case, the ask was to build a Job that would connect to a network device. I had a few troubles that I didn’t want to have to work through on a call that had limited time and that was a screen share. So I am taking to working on this via a blog post to share, and hopefully will be helpful for others as well.
Nautobot Documentation #
The Nautobot documentation is pretty straight on. But it has grown organically over time. As such, this is going to be a small walkthrough in an opinionated way. This post will dive into:
- Providing a Job form that will allow you to select a Device
- Connect to the device
- Execute a
show versionon the device as a method of connecting to the device
In this case I will be connecting to a Cisco device over SSH with Netmiko.
Creating the Job #
The default Jobs root path is
$NAUTOBOT_ROOT/jobs/, which following the default install instructions for Nautobot is then
/opt/nautobot/jobs/ on a virtual machine install. With the default install the jobs directory comes with an
nautobot@nautobot-host:~/jobs$ tree . └── __init__.py
Let’s build out the structure. The Nautobot repository has an Example file (or use this as a starting point) to get started. In the repository there is an example plugin that has jobs in it as a reference. You can find the jobs information then here https://github.com/nautobot/nautobot/blob/develop/examples/example_plugin/example_plugin/jobs.py.
Here I’m executing
vim demo_jobs.py from the
/opt/nautobot/jobs/ directory. In the end, the file just needs to be in the directory.
This will be a multiple step process. I like to debug the job along the way in order to know what I am working with. So the first iteration I include the following code to verify what is being sent in from the device form. Here is what the code looks like.
At this point, you can exit out and then execute
nautobot-server post_upgrade and restart the services
sudo systemctl restart nautobot nautobot-worker nautobot-scheduler from the server CLI (usually not the Nautobot user). During this process you should see the message:
01:49:20.083 INFO nautobot.extras.utils : Created Job "josh-v.com Demo jobs: Get show version" from <local: GetShowVersion> 01:49:20.089 INFO nautobot.extras.utils : Refreshed Job "josh-v.com Demo jobs: Get show version" from <local: GetShowVersion>
Then going into the UI menu of Jobs »> Jobs you get the following result with the Job Enabled column having a red X on it.
To enable the Job for execution, take a look at the docs here on the Nautobot Docs page for enabling a Job.
When you execute the Job for a device, you now get a basic “Hello World” execution. You can see the result with the device name displayed.
Get the Device Information From Nautobot #
The best way to get the information available within a Nautobot object is to work within the shell_plus environment. On your Nautobot server as the Nautobot user, enter the command
nautobot-server shell_plus. This will bring you into an interactive shell, hopefully an iPython like environment. If you do not get an iPython shell and you are on a development host (not production), then you can do a pip install to get iPython installed (
pip install ipython).
In the exploration with the shell, on lines 3 and 4 you see the verification that I’m working with the particular device that I wanted to work with. Lines 6 and 7 show that the platform name will come out as
Cisco IOS. This will not work for using Netmiko connection to the device, so I then went exploring further of the data. I then saw on lines 15 and 16 something that I can work with for Netmiko. So I am going to use the NAPALM driver. If you need to do some conversions of NAPALM drivers over to Netmiko, there are some mapping utilities in the NetUtils library that can help. Lastly I explored how to get the IP address that I wanted to connect to.
mydevice.primary_ip is a Nautobot object. That cannot be used in its own to connect to the host. I checked the string representation of the object, but that doesn’t just get us the IP address. But I do know that the object has a separate
mask_length objects. So I grabbed just the host for the Job.
The run method now looks like this:
On line 1 of the above example, the
import os was added to get the environment variables to get the credential to connect to the device. This could be set, or you may want to use another method.
The import on line 4 is used for converting the NAPALM platform into a usable Netmiko platform.
When connecting to a network device in a multi-vendor environment there are a few considerations that need to be made. You need to know what the commands are needed to do various things. This is where the possibility of using NAPALM as a method to connect to devices and their use of “getters” would come in handy. This may be an idea for a future blog post. You can see the example on line 14 of the run method above the use of converting “ios” to “cisco_ios”.
Executing the Job #
Now when you go to execute the job, you are able to get the
show version output from the device to the screen. Take a look at the example:
With Nautobot, there are many ways that you can get started with executing your own custom Jobs. By using Nautobot Jobs you can centralize your power scripts into one place, allowing for those power scripts to be put to use and then some by the entire organization, not just a select few. Take some design caution in what you do make available though. Nautobot centralizes, but also provides for authentication, user logging, and creates an API that is available for use to others. Looking for more on how the Jobs are an API endpoint, take a look at my previous post on creating that API endpoint.
Thanks for the read and Happy Automating!
Appendix - Full Code #
Here is the full code block: