TAGS: |

Triggering Network Automation From The Web

John Capobianco

How best to return from a cliffhanger ending – in a previous post we used Django’s Model class .save() to write network state—that is CLI standard output transformed to JSON using pyATS—into a PostgreSQL database table. Django also helped us convert, or migrate, a Pythonic class-based model into this SQL table in the first place.

Now that we have populated the database, we can shift our focus from the back-end (the modelling) to the front-end (presenting the data to our stakeholders with web-development tools). But before we start making HTML templates we must confirm that our modelled data and controller function actually populated the database. We also will want to provide the user various ways inside of Views to trigger the automation (controller Python pyATS jobs) from the application’s web interface.

Login as admin/admin on http://localhost:8000/admin

Registered table – so far so good

The populated PostgreSQL table

An individual interface, against which we can perform CRUD activities

Giving The User Control Over The Network Automation

The first set view and capability I write is a page, the On-Demand Centre, that provides users the ability to either:

  • Click a button to trigger the pyATS show ip interface brief job against all devices in the Devices table
  • Provide an input box the user can keyword-filter using the keys from the Devices model to reduce the number of devices from which we parse show ip interface brief

Recall the trinity between URLs, Views, and Templates from the first article. We first need to define the URL the user will visit in their browser to reach the On-Demand Centre. Django also allows us to include other folders so we can actually make a sub-program to Merlin called OnDemand. This also helps keep the application modular and we can store all URLs and Views inside a dedicated subfolder called OnDemand.

merlin/urls.py

ondemand/urls.py

We have configured http://localhost:8000/OnDemand as a URL that calls the View “button” (views.button) as well as a placeholder page for the View to call when the specific button is pressed. Let’s take a look at these two Views.

ondemand/views.py

Button is simply the landing page that presents the user with all of the available buttons. The show_ip_int_brief_all_ondemand view triggers the pyATS job (os.system command), which in turn populates the database with fresh network state.

Moving into the HTML templates, first let’s create base.html. This is a  base layer of HTML, Cascading Style Sheets (CSS), JavaScripts (JS), and any other content we want to be inherited by every downstream HTML template (for example the Merlin logo).

base.html – the foundation for all other HTML Django templates

Brief interlude – all of those scripts and stylesheets you see included in the headers of all HTML pages in this project are from either datatables.net or getbootstrap.com – which in my case specifically enhance the HTML tables I use to present network state to the users. Datatables allows me to make a commercial-grade UI for free and with very little work. Bootstrap provides enterprise-grade visualizations such as process spinners.

datatables.net

getbootstrap.com Spinner example

Back to our templates – now that we have a base.html we can build our On-Demand Centre sub-page. You will notice this template extends base.html thus inheriting all of the scripts and static files. You will also notice the table has an ID and class we will reference later.

ondemand.html table header

 

HTML Button

Spinner HTML code

At the end of the ondemand.html template we will add the datatable JavaScript that will transform the plain-old-HTML-table into an interactive datatable.

datatable JavaScript at bottom of html template

We want this button click to trigger the pyATS automation. It will take several seconds to complete, so we can display a bootstrap spinner while the user waits. Using our own main.js file we can add this script.

main.js

Rendered HTML view on localhost:8000/OnDemand !

The spinner spins while the pyATS job runs in the background on the server.

The triggered pyATS job

The button (URL – View – Template) is effectively a bulk operation against all devices in the Devices table. But what if we want to update the network only for a single device or group of devices? Using an input box in the HTML template instead of a button we can provide the user this capability as well. We will need a new URL and View and will enhance the existing template.

Add another url for the input filter as_view()

This view will be a little more complex and we will make a new Class from the ListView. We must reference the template where the input will be coming from (template_name) and then define, specifically, a get_queryset(self) function.

The query will come from the template when the HTTP GET is triggered

You will see a reference to a new model, DynamicJobInput, which I decided to set up (and migrate) into the database to store the users’ input (input_field). You will notice a different pyATS job – filter_job.py – is then executed. The only difference between the pyATS job that the button click runs and the job that the input text job runs is that we filter, using the Q package (think of this as a powerful OR operator), the devices against the input.

Filtered job using the user’s input to select the devices for the dynamic testbed

Our last step is to add the Input text box into the template and optionally the list of available keywords to help guide the user.

Input text box HTML template

The final On-Demand Centre looks great, is easy to use, and provides users the ability to either click a button or keyword-limit the show ip interface brief command and refresh the PostgreSQL database with real-time network state.

The final On-Demand Centre

We are just getting started with Views! I thought it important to make the connection between the View and Controller in the Model View Controller approach. Next time we will focus strictly on presentation options. Until then, stay safe and start writing some Python!

About John Capobianco: My name is John Capobianco, a 20-year IT professional who has fallen in love with automation, including network automation. I like to help other IT professionals learn how to modernize their approach to problem-solving with an automated DevOps infrastructure as code approach.