First things first: Review the code:
Code: https://github.com/h4ndzdatm0ld/nornir3-netconf-backup
The goal of this walkthrough is to backup configuration files from NETCONF enabled devices. Thanks to the flexibility of python, we have the choice to either back up the files as JSON or XML.. We will use the nornir_utils, ‘write_file’ plugin which is now decoupled from Nornir (for those of you used to Nornir 2.x).
Ensure you have this plugin available, by installing it via pip:
Lets inspect our host file and rely on a custom data k, v: ‘operation: netconf-enabled’ to use as our Filter.
Lets begin our Nornir 3.0 runbook: Pay close attention to our filter, as we pass in (operation=”netconf-enabled”) from above.
Also ensure the additional libraries being imported, such as xmltodict and json, etc.. are present and installed.
A couple custom functions that we will take advantage of to assist us in creating directories and converting XML to JSON.
The create_folder function is a simple way to pass in a directory name and use the os library to create a new directory, if it’s not present. This is helpful as we will use this function to generate the ‘backup’ folder in our code to store our configuration files.
xml2json function is exactly that. We take in a XML string and return it in JSON.
The Bulk of the code:
Lets review. The get_config will take in the nornir task and have two boolean parameters which default to False, which are: XML backup and JSON backup. This allows us to specify if we want to backup the config in simple XML format, JSON format.. or both if you desire.
We start by extracting the config, using the nornir_netconf: netconf_get_config task. This retrieves the configuration and we extract the .result attribute and wrap it into a variable.
Now, we create a path as to where the files will be backed-up. We use f strings to format the directory structure: We specify a folder ‘Backups” followed by the platform of the device in which the current task is being executed against.
We take this custom generated path and pass it in to our create_folder function and allow python to help us set up the directories.
One other thing to prepare for our file naming convention is a date to append at the end of the filename. Lets create a variable out of the datetime library and pass it in later on as we name our files.
Finally, lets handle the boolean values and allow our program to make a decision on how to save the configuration (XML, JSON or both).
One thing to note, earlier in the code I added a system exception to exit the program if neither json_backup or xml_backup are set to True. There is no reason to execute and generate folders without a backup file to create and to place in the directories.
In the above code we take advantage of our xml2json custom function if we want to convert the retrieved XML config from our device and use our write_file Nornir Plugin to create and write the file. Something that’s also utilized from Nornir, is the task.host.name. If we are strategic enough we can even use our task.name of the current task and use it to our advantage. You can see we create the filename using f-strings and pass in the task.host.name alongside the today variable which was constructed earlier from the datetime library.
Execution:
The final result, depending on which format you chose to backup the configs will vary. In this demonstration, i’ve enabled both choices. See the tree directory below that was auto created for me and the write_file plugin from Nornir was helpful enough to save the configuration files. The Backups directory was generated, followed by the platform (task.host.platform) and finally the name of the file
filename = {task.host.name}_{date}_{XML_OR_JSON}
There you have it! A simple way to take advantage of the Nornir 3.0 framework and create backups of all your NETCONF enabled devices in either XML or JSON format.