NetPalm Introduction - Part 3

Introduction

This post is a follow up on part 1 and part 2.

In part 1, we focused on retrieving information from our devices using NetPalm. In part 2, we focused on changing/setting information in our devices.

In this post, we will explore some more advanced features of NetPalm. We will be covering:

  • using Jinja2 templates to change configuration
  • using service templates

Using Jinja2 templates

NetPalm allows you to change configuration on devices using Jinja2 templates in combination with NAPALM and Netmiko. If you are a regular reader of my blog, we have been changing configurations already using NAPALM and Netmiko individually:

  • NAPALM: we added a loopback interface to our device using a Jinja2 template (check this post )

  • Netmiko: we added a loopback interface to our device using a Jinja2 template and we also changed the description of an interface (check this post)

In this post, we will add some loopback interfaces to our device but using NetPalm (which under the hood will use NAPALM or Netmiko).

Let’s first create the Jinja2 template. Create a file called loopback.j2 and place this in the netpalm/backend/plugins/jinja2_templates folder. We will be using the following template:

{% for interface in interfaces %}
   interface {{interface.name}}
   description {{interface.description}}
   ip address {{interface.ipv4_addr}} {{interface.ipv4_mask}}
{% endfor %}

NetPalm provides an API to change the configuration through a Jinja2 template (see here for Netmiko and here for NAPALM.

The example is the following:

netpalm

Essentially the template argument points to the template we have stored in the netpalm/backend/plugins/jinja2_templates folder, in our case this will be loopback (not loopback.j2). Next, in the args, we need to pass the variables for our Jinja2 template. In our case, we want to provide the following information.

{
  "interfaces": [
    {
      "name": "Loopback3001",
      "description": "Description for Loopback 3001",
      "ipv4_addr": "200.200.200.230",
      "ipv4_mask": "255.255.255.255"
    },
    {
      "name": "Loopback3002",
      "description": "Description for Loopback 3002",
      "ipv4_addr": "200.200.200.231",
      "ipv4_mask": "255.255.255.255"
    }
  ]
}

Below is an example of the complete REST API call:

netpalm

And a view on the task (pay attendtion to the changes attribute):

netpalm

Next, let’s check if it worked correctly. We will be using the Netmiko getconfig API for this (this one).

netpalm

In below screenshot, you can see these two loopback interfaces got added successfully.

netpalm

Or via SSH into our devices, we see them listed indeed:

csr1000v-1#show ip interface brief
Interface              IP-Address      OK? Method Status                Protocol
GigabitEthernet1       10.10.20.48     YES other  up                    up
GigabitEthernet2       unassigned      YES NVRAM  administratively down down
GigabitEthernet3       unassigned      YES NVRAM  administratively down down
Loopback76             unassigned      YES unset  up                    up
Loopback100            unassigned      YES unset  up                    up
Loopback1000           unassigned      YES unset  up                    up
Loopback2000           10.0.0.40       YES other  up                    up
Loopback3001           200.200.200.230 YES manual up                    up
Loopback3002           200.200.200.231 YES manual up                    up

Service templates

NetPalm supports a feature called Service Templates. The value from service templates comes from the fact they allow you to create things at a service level rather then the individual device level. Sounds pretty abstract right?

Imagine you have dozens of devices onto which you want to add additional interfaces (or add interfactes to certain VLANs, or create trunk ports or…). In the first and second post, we have seen how this could be achieved through calling NetPalm’s getconfig/setconfig API and pass the commands for each device. These could be daunting and error-prone tasks if you need to repeat this for multiple dozens of devices, possibly devices having different operating systems or coming from multiple vendors.

Service templates will allow you to define a single service template that can be used across multiple devices. The service template supports all of the Jinja logic. In other words, it allows you to run IF/ELSE statements inside an individual operation (retrieve, create, delete). The benefit here is that we only need to define such service template once and it will work against all the underlying devices. If we were to do the same withouth service templates, it would require us to call NetPalm’s getconfig/setconfig API but each time specifying different JSON payloads (per vendor, per device and per operation system).

Service templates: code overview

In order to work with service templates, we need to create a service template which needs to be stored in the netpalm > backend > plugins > service_templates folder. NetPalm ships out of the box with some boilerplate templates for you to get started. For this post, I’m using my own service template (we’ll call it loopback.j2), though very much inspired by the existing examples.

A service file defines several CRUD operations, hence you will find a section to get configuration from your device (RETRIEVE), to add some configuration (CREATE) and to delete some configuration from your device (DELETE).

A) Retrieve section

Let’s have a look first at the easiest one, which is the retrieve. As you can see, this is (part of) a Jinja template to which we need to pass some variables like the host, username and password. Also note that to retrieve the interfaces, we will be using netmiko under the hood.

      {
        "operation": "retrieve",
        "payload": {
          "library": "netmiko",
          "connection_args": {
            "device_type": "cisco_xe",
            "host": "{{host}}",
            "username": "{{username}}",
            "password": "{{password}}",
            "port": "8181"
          },
        "command": "show ip interface brief"
        }
      }

We will pass in these variables through the json body as part of the REST call. Below you see an example of such body.

{
	"operation": "retrieve",
	"args":{
		"hosts":["ios-xe-mgmt-latest.cisco.com"],
		"username":"developer",
		"password":"C1sco12345"
		
	}
}

With this piece of information, NetPalm knows you want to use the retrieve part of the service template and will execute the command you specified in that section of the service template.

Let’s try things out now. Go to POSTMAN and issue a GET request to the address http://localhost:9000/service/loopback. The word loopback here refers to the name of the service template (but without the j2 extension)

netpalm

You will get back a task ID which we can then use to query the http://localhost:9000/task API. Doing so, will show you the list of interfaces on our device.

netpalm

B) Create section

If you understood the above, it will be quite easy to understand also the create and delete sections of the service template. Let’s quickly walk over things here.

Below is the create part of the service template.

      {
        "operation": "create",
        "payload": {
          "library": "napalm",
          "connection_args": {
            "device_type": "cisco_ios",
            "host": "{{host}}",
            "username": "{{username}}",
            "password": "{{password}}",
            "optional_args": {"port": 8181}
        },
        "j2config": {
    	    "template":"loopback_create",
    	    "args":{
              "interfaces": [
                {
                  "name": "Loopback250",
                  "description": "Description for Loopback 250",
                  "ipv4_addr": "200.200.200.20",
                  "ipv4_mask": "255.255.255.255"
                },
                {
                  "name": "Loopback251",
                  "description": "Description for Loopback 251",
                  "ipv4_addr": "200.200.200.21",
                  "ipv4_mask": "255.255.255.255"
                }
              ]
          }
    	  }

It looks pretty similar to the retrieve example from above. Yet, here we are passing a Jinja template as well. How does this work? Well, NetPalm needs to know what you want to create on your device. In our little example, we will be adding two loopback interfaces. While in the retrieve section we wanted to use netmiko, here I deciced to use napalm.

Next, you’ll need to create file in the netpalm > backend > plugins > jinja2_templates folder. We’ll call this file loopback_create.j2 and it looks as follows:

{% for interface in interfaces %}
   interface {{interface.name}}
   description {{interface.description}}
   ip address {{interface.ipv4_addr}} {{interface.ipv4_mask}}
{% endfor %}

This is a simple Jinja2 template, in fact the same one as we used in the first section of this blog post. We’ll need to pass in the data to the template of course and this is exactly what the j2config portion of the create section does for us. As you can see from the service template snippet above, we are providing a list of two interfaces.

Let’s try things out again. The POSTMAN REST call does not change apart from the fact that we specify the create operation for obvious reasons.

netpalm

Below you will see that we added the loopback interfaces.

netpalm

Let’s verify by logging into the device through SSH and you indeed see the loopback interfaces were added successfully.

csr1000v-1#show ip interface brief
Interface              IP-Address      OK? Method Status                Protocol
GigabitEthernet1       10.10.20.48     YES other  up                    up
GigabitEthernet2       10.255.255.2    YES other  administratively down down
GigabitEthernet3       10.255.255.2    YES other  up                    up
Loopback250            200.200.200.20  YES TFTP   up                    up
Loopback251            200.200.200.21  YES TFTP   up                    up
C) Delete section

The delete section is very similar to the create section in terms of the logic. Also here we need to create a Jinja2 template for deleting the loopback interfaces and then refer to this template in the delete section of the service template. So let’s do this:

First, create a file called loopback_remove.j2 in the netpalm > backend > plugins > jinja2_templates folder which contains the following content.

{% for interface in interfaces %}
   no interface {{interface.name}}
{% endfor %}

In the snippet above, pay attention to the word ‘no’ which indicates we want to remove the interface from our device. Also note we only need to know the name of the interface (the description and IP configuration will obviously automatically be deleted by the device).

Next, let’s have a look at the delete operation in the service template.

     "operation": "delete",
        "payload": {
          "library": "napalm",
          "connection_args": {
            "device_type": "cisco_ios",
            "host": "{{host}}",
            "username": "{{username}}",
            "password": "{{password}}",
            "optional_args": {"port": 8181}
          },
        "j2config": {
    	    "template":"loopback_remove",
    	    "args":{
    		    "interfaces": [
                {
                  "name": "Loopback250"
                },
                {
                  "name": "Loopback251"
                }
              ]
    	    }
        }
      }

Very similar to the create section, but here we are referring to the loopback_remove template and we provide just the name of the interface we want to remove.

Let’s once again try things out. As we’re dealing with the delete function, we need to specify the delete operation in the JSON body.

netpalm

You’ll see we get back an indication that the interfaces were deleted. See below screenshot.

netpalm

And as usual, let’s verify things again through SSH and you’ll see the loopback interfaces were removed properly.

csr1000v-1#show ip interface brief
Interface              IP-Address      OK? Method Status                Protocol
GigabitEthernet1       10.10.20.48     YES other  up                    up
GigabitEthernet2       10.255.255.2    YES other  administratively down down
GigabitEthernet3       10.255.255.2    YES other  up                    up

The entire service template can be found here.

That’it for now folks. Hope you started to see the benefits of NetPalm Service Templates.