Nautobot Apps - Lab 02: Creating a New Plugin¶
- Nautobot Apps - Lab 02: Creating a New Plugin
- Task 1 - Create an Empty App
- Task 2 - Begin the App Configuration
- Task 3 - Work with the App
- Task 4 - Save Your Work with Git
In this lab, we'll set up and install the skeleton of a new Nautobot plugin for development. These steps can be performed from a shell or using VSCode Remote Development.
Task 1 - Create an Empty App¶
To establish a foundation on which we can construct our own Nautobot plugin, we'll initialize a git repository for revision tracking, create a plugin configuration class, and create a setup.py file.
Step 1-0 - Prepare for the Lab¶
For this and all remaining labs, it is advisable to open two terminal windows, one for running the Nautobot development server, and another for executing various commands.
The steps in this lab require that you have a terminal open and have switched to the nautobot user. Verify your username with the whoami command and switch user to nautobot if needed.
ntc@nautobot:~$ whoami
ntc
ntc@nautobot:~$ sudo -iu nautobot
nautobot@nautobot:~$ whoami
nautobot
nautobot@nautobot:~$
Step 1-1 - Create the Project Directory¶
Now create your project directory and change into it:
nautobot@nautobot:~$ mkdir -p /opt/nautobot/plugin
nautobot@nautobot:~$ cd /opt/nautobot/plugin
nautobot@nautobot:~/plugin$
Step 1-2 - Initialize the Git Repo¶
Initialize a new git repository. This will allow us to track our changes as we proceed through the upcoming labs.
nautobot@nautobot:~/plugin$ git init .
Initialized empty Git repository in /opt/nautobot/plugin/.git/
nautobot@nautobot:~/plugin$
The above command creates a hidden .git folder in the current directory. You can view the files:
nautobot@nautobot:~/plugin$ ls -la .git/
total 40
drwxrwxr-x 7 nautobot nautobot 4096 Apr 24 04:31 .
drwxrwxr-x 3 nautobot nautobot 4096 Apr 24 04:31 ..
-rw-rw-r-- 1 nautobot nautobot 23 Apr 24 04:31 HEAD
drwxrwxr-x 2 nautobot nautobot 4096 Apr 24 04:31 branches
-rw-rw-r-- 1 nautobot nautobot 92 Apr 24 04:31 config
-rw-rw-r-- 1 nautobot nautobot 73 Apr 24 04:31 description
drwxrwxr-x 2 nautobot nautobot 4096 Apr 24 04:31 hooks
drwxrwxr-x 2 nautobot nautobot 4096 Apr 24 04:31 info
drwxrwxr-x 4 nautobot nautobot 4096 Apr 24 04:31 objects
drwxrwxr-x 4 nautobot nautobot 4096 Apr 24 04:31 refs
Task 2 - Begin the App Configuration¶
Step 2-1 - Create the App's Setup File¶
In your project root (~/plugin/), create a file named setup.py. This will be used to install the plugin within the Python environment. Open this newly created file in VSCode and update accordingly.
Within setup.py, import find_packages and setup from the setuptools module, and write a call to setup() with parameters appropriate for your plugin. Be sure to set the packages keyword argument to find_packages() to ensure proper installation. A reference is provided below.
from setuptools import find_packages, setup
setup(
name='maintenance-notices',
version='0.1',
description='A Nautobot plugin for tracking maintenance notices',
author='Student Name',
packages=find_packages(),
include_package_data=True,
)
Save the file.
Note: We are defining our plugin version within the setup.py file, which is used for Python packaging. Shortly we will add some code that exposes this version within the plugin.
Step 2-2 - Create the App's Directory Structure¶
Nautobot contains a helper command that builds out a template of files you will need to build a plugin. The command format is nautobot-server startplugin <NEW_PLUGIN_NAME>. Our new plugin name will be maintenance_notices. Start a new plugin by executing the nautobot-server startplugin maintenance_notices command.
nautobot@nautobot:~/plugin$ nautobot-server startplugin maintenance_notices
nautobot@nautobot:~/plugin$ ls -l maintenance_notices/
total 28
-rw-rw-r-- 1 nautobot nautobot 981 Feb 15 00:05 __init__.py
drwxrwxr-x 2 nautobot nautobot 4096 Feb 15 00:05 migrations
-rw-rw-r-- 1 nautobot nautobot 188 Feb 15 00:05 models.py
-rw-rw-r-- 1 nautobot nautobot 1065 Feb 15 00:05 navigation.py
drwxrwxr-x 2 nautobot nautobot 4096 Feb 15 00:05 tests
-rw-rw-r-- 1 nautobot nautobot 202 Feb 15 00:05 urls.py
-rw-rw-r-- 1 nautobot nautobot 152 Feb 15 00:05 views.py
nautobot@nautobot:~/plugin$
Step 2-3 - Create the App Configuration Class¶
The app configuration class for our plugin is defined in __init__.py. Open this file in VSCode.
The unmodified file should look like this:
"""maintenance_notices Plugin Initialization."""
from nautobot.extras.plugins import PluginConfig
class MaintenanceNoticesConfig(PluginConfig):
"""Plugin configuration for the maintenance_notices plugin."""
name = "maintenance_notices" # Raw plugin name; same as the plugin's source directory.
verbose_name = "maintenance_notices" # Human-friendly name for the plugin.
base_url = "maintenance_notices" # (Optional) Base path to use for plugin URLs. Defaulting to app_name.
required_settings = [] # A list of any configuration parameters that must be defined by the user.
min_version = "1.0.0" # Minimum version of Nautobot with which the plugin is compatible.
max_version = "1.999" # Maximum version of Nautobot with which the plugin is compatible.
default_settings = {} # A dictionary of configuration parameters and their default values.
caching_config = {} # Plugin-specific cache configuration.
config = MaintenanceNoticesConfig
Step 2-4 - Prepare to Version the App¶
First we want to access and expose the plugin version number that is defined in the setup.py file. We will use the importlib.metadata helper function to do that. Add the following line to the file below the from nautobot.extras.plugins import PluginConfig statement and above the class MaintenanceNoticesConfig line. There should be a empty line above and below it.
try:
from importlib import metadata
except ImportError:
# Python version < 3.8
import importlib_metadata as metadata
__version__ = metadata.version(__name__)
Note: In Python version 3.8 this helper was simplified to be
from importlib import metadata. We use the try/except block here to determine if we are executing code on an earlier Python version.
Notice that the template code imports Nautobot's PluginConfig class from nautobot.extras.plugins and has a subclass named MaintenanceNoticesConfig. The PluginConfig class is a Nautobot-specific wrapper around Django's built-in AppConfig class. Each plugin should provide its own subclass, defining its name, and metadata, as well as any default and/or required configuration parameters. While the file is usable as is, we will make a few adjustments to this class.
Step 2-5 - Update the App's verbose_name¶
Take note that the name and verbose_name are the same. We want to fix the verbose_name so that it appears in title case, where the first letter of each word is capitalized. Go ahead and change that line to read as follows:
Step 2-6 - Add Additional App Metadata¶
Let's provide some additional metadata to the configuration. Specifically, we will add these attributes between verbose_name and base_url:
version: Add this to the file. Set this to the previously defined variable__version__author: Add your name as the plugin author.description: A brief description of the plugin
This is how they should look:
version = __version__
author = "Student Name"
description = "Nautobot plugin to manage maintenance notices"
The last line in the file, config = MaintenanceNoticesConfig, exposes your new class to Nautobot by assigning it to the name config.
Note: To learn more about required and optional attributes, reference the PluginConfig Documentation
Step 2-7 - Review the App's __init__.py (so far)¶
Your completed __init__.py module should look like this:
"""Plugin declaration for MaintenanceNoticesConfig."""
from nautobot.extras.plugins import PluginConfig
try:
from importlib import metadata
except ImportError:
# Python version < 3.8
import importlib_metadata as metadata
__version__ = metadata.version(__name__)
class MaintenanceNoticesConfig(PluginConfig):
"""Plugin configuration for the maintenance_notices plugin."""
name = "maintenance_notices"
verbose_name = "Maintenance Notices"
version = __version__
author = "Student Name"
description = "Nautobot plugin to manage maintenance notices"
base_url = "maintenance_notices"
required_settings = []
min_version = "1.1.0"
max_version = "1.9999"
default_settings = {}
caching_config = {}
config = MaintenanceNoticesConfig
Save the file.
Task 3 - Work with the App¶
Step 3-1 - Verify the Virtual Environment¶
Verify that the Nautobot virtual environment is activated by checking the location of the python executable file. It should be located in the /opt/nautobot/bin/python directory.
Step 3-2 - Install the App¶
Finally, we'll install our plugin as a Python package within the virtual environment. When running setup.py, we'll append the develop command line argument: This installs a link to our local development directory rather than copying everything. Installing the package in this manner ensures that Nautobot is always run with the most recent changes to our plugin's code, and avoids the need to reinstall the plugin every time a change is made.
nautobot@nautobot:~/plugin$ python setup.py develop
running develop
running egg_info
creating nautobot_maintenance_notices.egg-info
writing nautobot_maintenance_notices.egg-info/PKG-INFO
writing dependency_links to nautobot_maintenance_notices.egg-info/dependency_links.txt
writing top-level names to nautobot_maintenance_notices.egg-info/top_level.txt
writing manifest file 'nautobot_maintenance_notices.egg-info/SOURCES.txt'
reading manifest file 'nautobot_maintenance_notices.egg-info/SOURCES.txt'
writing manifest file 'nautobot_maintenance_notices.egg-info/SOURCES.txt'
running build_ext
Creating /opt/nautobot/lib/python3.8/site-packages/nautobot-maintenance-notices.egg-link (link to .)
Adding nautobot-maintenance-notices 0.1 to easy-install.pth file
Installed /opt/nautobot/plugin
Processing dependencies for nautobot-maintenance-notices==0.1
Finished processing dependencies for nautobot-maintenance-notices==0.1
Step 3-3 - Activate the App¶
To activate our new plugin in Nautobot, open the Nautobot configuration file /opt/nautobot/nautobot_config.py in VSCode and add it to the PLUGINS list:
PLUGINS = [
"nautobot_data_validation_engine",
"nautobot_device_lifecycle_mgmt",
"nautobot_plugin_nornir",
"nautobot_golden_config",
"maintenance_notices",
]
Note: If you have the Nautobot development server running in one of your terminals, you will need to stop it by hitting
<CTRL> C. This is because thenautobot_config.pyfile is not monitored for changes byStatReloader.
Start the Nautobot development server with the command nautobot-server runserver 0.0.0.0:8080 --insecure.
nautobot@ntc-nautobot-apps:~$ nautobot-server runserver 0.0.0.0:8080 --insecure
Watching for file changes with StatReloader
Performing system checks...
System check identified no issues (0 silenced).
April 24, 2022 - 05:19:10
Django version 3.1.14, using settings 'nautobot_config'
Starting development server at http://0.0.0.0:8080/
Quit the server with CONTROL-C.
Step 3-4 - Validate the App Installation in the Django Toolbar¶
Validate the Plugin has been registered from the UI
Within the Django Debug toolbar, open the "Settings" section and inspect the value of INSTALLED_APPS. You should see 'maintenance_notices.MaintenanceConfig' at the bottom of the list. This indicates that the plugin has been loaded.

Task 4 - Save Your Work with Git¶
Step 4-1 - Use .gitignore¶
To save our work thus far, we'll commit the current directory to git. The .gitignore file specifies files that we don't want to track, so as the name suggests, we use this file to tell git to ignore these. While we could create a simple .gitignore file by hand, instead we will download one provided by the folks at GitHub.
Note: Use the
pwdcommand to make sure you are in the root folder of your plugin project. In this case we should be in/opt/nautobot/plugin.
The wget command will download the file and save if to the filename we provide wit the -O argument.
nautobot@nautobot:~/plugin$ wget -O .gitignore https://github.com/github/gitignore/raw/main/Python.gitignore
--2022-04-18 19:32:04-- https://github.com/github/gitignore/raw/main/Python.gitignore
Resolving github.com (github.com)...
...
Saving to: ‘.gitignore’
.gitignore 100%[=================================================================================================================>] 3.01K --.-KB/s in 0s
2022-04-18 19:32:04 (13.3 MB/s) - ‘.gitignore’ saved [3078/3078]
It is good practice to check that we downloaded the file and it has the name we expect. Feel free to open the file and inspect the contents.
nautobot@nautobot:~/plugin$ ls -la .gitignore
-rw-rw-r-- 1 nautobot nautobot 3078 Apr 18 19:32 .gitignore
nautobot@nautobot:~/plugin$
Step 4-2 - Configure the Global Git Settings¶
Configure the global Git settings
nautobot@nautobot:~/plugin$ git config --global user.email "you@example.com"
nautobot@nautobot:~/plugin$ git config --global user.name "Your Name"
Step 4-3 - Stage Changes and Commit with Git¶
Then, stage your changes and commit:
nautobot@nautobot:~/plugin$ git add -A
nautobot@nautobot:~/plugin$ git status
On branch master
No commits yet
Changes to be committed:
(use "git rm --cached <file>..." to unstage)
new file: .gitignore
new file: maintenance_notices/__init__.py
new file: maintenance_notices/migrations/__init__.py
new file: maintenance_notices/models.py
new file: maintenance_notices/navigation.py
new file: maintenance_notices/tests/__init__.py
new file: maintenance_notices/tests/test_models.py
new file: maintenance_notices/tests/test_views.py
new file: maintenance_notices/urls.py
new file: maintenance_notices/views.py
new file: setup.py
nautobot@nautobot:~/plugin$ git commit -m "Completed Lab 2."
This completes the first lab. Check your work against the solution guide before proceeding with the next lab.