Jason Edelman's Blog
  • Home
  • About
  • Contact

Automated Network Diagrams with Schprokits & AutoNetkit

11/10/2014

9 Comments

 
Over the past few months I’ve written about Ansible and the intersection of DevOps and Networking quite a few times.  As network vendors continue to develop better APIs on network devices (switches, routers, FWs, etc.) there is no doubt going to be an emergence of new tools for the network industry.  One of these emerging tools is Schprokits.  Schprokits (company name and product name), still in stealth, was founded by Jeremy Schulman, who previously worked at Juniper and did the initial work for integrating Junos with Puppet, Chef, and Ansible, and on top of that developed the Juniper PyEZ Python framework.  Schprokits seems to be the outcome of Schulman’s experiences working with existing DevOps automation platforms and building one now purpose built for networking.  Over the past few weeks, I've been fortunate to be able to be part of the first Schprokits user-test group.  

In this article, I’m going to explore not only working with Schprokits, but also working with AutoNetkit.  AutoNetkit, part of the PhD thesis work of Simon Knight, is an application and framework for modeling network devices, both from a configuration and visualization/diagramming standpoint.  Some of you may also realize AutoNetkit is used in the Cisco VIRL and Juniper Junosphere products too.
Note: this isn’t meant to be a deep dive on either Schprokits or AutoNetkit, but rather just one use case for automating the building of network diagrams based on real time state of the network.  The following is just one example of a diagram that can be created in seconds.  

Picture
We’ll step through how this is done in the sections that follow.

Background

I have a lab with two (2) Nexus 9000 switches, (1) Nexus 3000, and (1) Catalyst 3550 switch.  There are three (3) links inter-connecting the Nexus 9000 switches.  This is to simulate VPC peerlinks (2) and a peer keeaplive link (1) although the VPC configuration doesn’t actually exist yet on the switches.  The Nexus 3000 connects to each Nexus 9000.  The Catalyst 3550 connects to each of the three (3) Nexus switches as it’s being used as an out of band management switch and connects to each of the switches mgmt0 interface.

The Goal

Remember the goal is create diagram(s) based on real time state.  We’ll need to break this up logically.  First, it should be understood that Schprokits is being used as the core automation engine here.  Within Schprokits, we’ll be doing two major activities: Activity 1 will be to collect the data we need to create physical diagrams and Activity 2 will be to create the diagram(s).

Schprokits Tables/Views

Without programming, how do you extract the data needed from the Nexus switches?  Going on a small tangent that we’ll bring back home very soon, it’s important to know Schprokits supports a concept called Tables/Views.  Tables/Views makes it so ANYONE can get ANY data they wish out of the switch programmatically.  Rather than try and explain it, let’s just see an example.  This example will be using Tables/Views for NX-API devices via Schprokits.

Within the Schprokits workbook below (filename of this file is nxapi_table_view.yml), you will see two actions. The first is to load table definitions and the second is to actually get the data (and store it to a local file).

Schprokits Workbook
Picture
You will see that the all of tables are being loaded from nexus_tables.yml using the Schprokits core action called use_tables.  I know it’s still not clear what tables are, but we’ll get there taking a top down approach.

Let’s now take a look inside the nexus_tables.yml file.

Table/View Definition
Picture
The name of the table is totally arbitrary.  I used nxapi_neigh_table.  Next is the really cool part as you get to use the NX-API on the Nexus switches without needing to write any code.  You see the command, item, key, and view.  The command is self-explanatory, but since NX-API is just an API wrapping commands, this is the API/command being sent to the device.  For other device types, the command may be an RPC call or any other type of API.

For those new to NX-API, Nexus devices that support NX-API actually support a sandbox environment to test and see the output of an API call.  The picture below shows the sandbox output for executing the show cdp neighbor command via the API.  The sandbox is viewed by going to http://nexus_switch_ip.
Picture
Let’s take a deeper look at the response (in the bottom right).  In this next picture, all I did was copy and paste the response into my text editor to be able to capture more of it.  This output shows the response for three (3) neighboring connections.  The important part here is to see what sections comprise of a neighbor.  What we can determine from the picture below is that every section called ROW_cdp_neighbor_brief_info denotes a new neighbor.  
Picture
If you go back to the nexus_tables.yml file, this is exactly what item is!  Now we have the command and item, but what are key and view.  Since there can be any number of given neighbors, we need a way to reference each one.  Here, as the user, or network automator (is that even a word?), you can pick anything unique that you want to use as the neighbor ID, or KEY.  We are using the intf_id because we know that’s always unique and will be the interface name.  As you’ll see from the picture above, the intf_id’s are mgmt0, Ethernet1/1, Ethernet1/2, etc.

The last part in the table definition is the view that should be used.  You may already be able to decipher what the view is doing, but it is basically slicing and dicing what should be included “under the key” for each neighbor.  You can see 9 things that define each neighbor that include: device_id, intf_id, ttl, capabilities, platform_id, etc.  The view allows you to select exactly what data you want because you may not need everything.
Picture
You can see that lines 9-13 are the view and line 7 calls the view.  If we combine the table and view, we now can see that we’ll have collected neighbor data from the switch that stores it based on the interface name (intf_id) and within each interface name, we’ll be able to access three details about the neighbor from the view, namely, the device_id, port_id, and platform_id.  And by the way, you can call these things whatever you want.  If you wanted to call the port_id, “interface,” you could just by typing “interface: port_id” in line 12.  

If you go back to the first picture, you will see that the second action in the workbook was to specify the exact table you want to get data from.  You need to do this because you can have more than 1 table being used.  We’ll see this shortly.  So, you see the action called “get_tables” retrieves the data using the table/view specified, but also then calls the “opipe” action, that then just stores the data into a local file that is called neighbors.json.

Let’s get back to Schprokits and see this in action, so it makes more sense.  If we execute the workbook, we see the following.  Remember, I’m executing this on three (3) Nexus devices that have NX-API enabled.  The cat3550 is not being access programmatically.
Picture
Everything looks okay.  This means, we should have three new files call neighbors.json.  Each device has their own directory.  Let’s take a look at one of them to see what the data looks like.

Picture
Can you see how the table/view for neighbors matches up to this?

Adding more Tables/Views

I’m going to now add two more tables that will help gather more relevant data for creating the diagram that I so desire :).

With these changes, the updated tables file looks like this:
Picture
And the workbook looks like this:

Picture
At this point, we have three (3) files per device.  This is the data required to create the diagram. 

Note: based on the complexity of the diagram, you can retrieve a lot more data such as IP addressing, L3 information, etc. to make different types and more detailed diagrams.

Extending Schprokits – creating an action that uses AutoNetkit

Due to the extensibility and openness of Schprokits and AutoNetkit, I was able to create a custom action in Schprokits that creates a diagram.  To create a diagram, we need to send the three (3) files per device to the diagram action along with the path where to find the files.  I’ve now created a second activity in the Schprokits workbook that will create the diagram.  The activity is pretty straightforward and looks like this:
Picture
The new complete workbook is now comprised of two (2) activities.  In the first activity, there are four actions, one to pull in table definitions, and then three to extract the required data from the devices.  In the second activity, there is just one action, called diagram, that sends the data files that were created from the first activity, to the diagram action. 

The output is a sleek looking diagram that is using AutoNetkit on the back end.

Here is the diagram that is created after running the updated workbook.

Picture
Also notice that if you hover over the interface, link, or device, you get more contextual data about each.

Picture
Picture
You may also realize that Schprokits did NOT connect to the 3550, but still displayed it on the diagram.  Based on the neighbor data received from other devices, the diagram action was smart enough to realize there was another device on the network to include in the diagram.  This can come in handy for phones, access points, virtual switches running CDP/LLDP, or peering points, etc.

One more thing that the diagram action can do based on this is let the user select how they want to treat “unknown” devices like the 3550.  In the diagram above, it was treated as “unknown” and placed in the bottom right of the diagram.

Let’s change this to treat unknowns as leafs, just for the heck of it, to see how it works.

This requires a small change to workbook. Notice the last parameter in the following picture:  unknown=leaf
Picture
After re-running the workbook, the new diagram will treat the 3550 as a leaf in terms of placement on the diagram.  The result looks like this (there is also a checkbox to remove the interface descriptions which I selected here as well):

Picture
I need to recognize Simon Knight, creator of AutoNetkit.  I ran into a few snags and bugs along the way and he was gracious enough to spend some time make sure I got the diagrams working!  Thanks again Simon.

This is just one small use case for network automation with Schprokits, but as an early user of the platform, it could have the potential to revolutionize the way networks are managed and operated.

Would love to hear your thoughts below.  If you have any specific product questions, you should reach out to them directly, of course.  Here are their contact pages:  Schprokits and AutoNetkit.

Thanks,
Jason

Twitter: @jedelman8

9 Comments
David Gethings
11/10/2014 02:08:29 pm

This is very cool!

This is great example of what well produced tools can do - providing a reusable framework to present data that is easy for humans to understand.

Not all tools have to produce pretty pics - but they should express data that is easy to understand and provide meaning.

Reply
Jason Edelman link
11/11/2014 10:47:08 pm

Couldn't agree more. That is the key- to see something like Schprokits as a framework and leverage its extensibility. As for the diagrams, agree as well. Not needed, but many folks like them :)

Reply
Mirza Waqas Ahmed
11/11/2014 01:45:54 am

It is amazing how networks can become simple by changing the way we think of operating networks. Great works by Simon and would love to see more of that from you Jason.

One idea though if we can adapt the nx-api, why cant we have snmp as the underlying protocol to communicate with C3550 :)

Reply
Jason Edelman link
11/11/2014 10:48:25 pm

Thank you! Of course SNMP...or SSH can be used. Want to give it a try and let me know what you come with? :)

Time permitting, I'm planning this, but not sure when that may be.

Reply
Val
11/12/2014 01:11:42 pm

I might be missing something obvious here, but when you execute the workbook, how does Schprokits know which switches to connect to?

Reply
Jason Edelman link
11/12/2014 11:19:07 pm

You aren't missing something. I didn't document that! Upcoming posts will.

But take a look here: https://www.youtube.com/watch?v=ytv1F39fT7I
Start at the 3:25 minute mark. You'll see the hosts or inventory file and group called Cisco that has three devices in it. Watch for a minute and it should make sense.

Reply
Mark Tees
1/2/2015 03:02:27 pm

Hi there,

Love the post!

I want do something similar to what you have done to automate networking diagrams. One thing I am stumbling on at present is how I am going to automate the positioning of things for Autonetkit.

Any chance you could give me a hint as to how you positioned things in the diagram in the post?

Thanks!

Mark

Reply
Mark Tees
1/2/2015 06:59:20 pm

Just an update to the above in case anyone else wanted to do the same. My aim is being able to walk into a network, map everything easily and snapshot it.

I used the Python networkx library's node positioning algorithms to get the effect that I needed to get started.

http://networkx.github.io/documentation/latest/reference/drawing.html

Parsing a copy of the house.json file in the examples directory:

```
import json
from pprint import pprint
from subprocess import call
import networkx as nx

with open('position_test.json', 'r+') as f:
data = json.load(f)

# Create nx graph
G = nx.MultiGraph()
for link in data['links']:
G.add_edge(link['src'], link['dst'])

pos = nx.spring_layout(G, iterations=200, scale=400)

for node in data['nodes']:
node_id = node['id']
print "Old data...."
print "Node: %s, x: %d, y: %d" % (node['id'], node['x'], node['y'])

# Update position values
node['x'] = pos[node_id][0]
node['y'] = pos[node_id][1]

print "New data...."
print "Node: %s, x: %d, y: %d" % (node['id'], node['x'], node['y'])


# Write json file
f.seek(0)
json.dump(data, f, indent=4)


# Update Autonetkit
call(["autonetkit", "-f", "position_test.json"])
```

Reply
Jason Edelman link
1/3/2015 01:45:15 am

Cool. Thanks for posting. I'm hoping to do more with this soon, but I created a template to use for leaf/spine diagrams. In my example, a WAN, etc. wouldn't look proper, but ank does have default positioning algorithms.

You can have different types of templates and an unknown category and then manually fix as an option too.

Thanks again for sharing!




Leave a Reply.

    Author

    Jason Edelman, Founder & CTO of Network to Code. 


    Enter your email address:

    Delivered by FeedBurner


    RSS Feed


    Categories

    All
    1cloudroad
    2011
    2960
    40gbe
    7000
    Arista
    Aruba
    Big Switch
    Brocade
    Capwap
    Christmas
    Cisco
    Controller
    Data Center
    Dell Force10
    Embrane
    Extreme
    Fex
    Hadoop
    Hp
    Ibm
    Isr G2
    Juniper
    Limited Lifetime Warranty
    Meraki
    Multicast
    N7k
    Nexus
    Nicira
    Ons
    Opendaylight
    Openflow
    Openstack
    Presidio
    Qsfp
    Quick Facts
    Routeflow
    Sdn
    Sdn Ecosystem
    Security
    Ucs


    Archives

    May 2015
    April 2015
    February 2015
    January 2015
    December 2014
    November 2014
    October 2014
    September 2014
    August 2014
    June 2014
    May 2014
    March 2014
    February 2014
    January 2014
    December 2013
    November 2013
    October 2013
    September 2013
    August 2013
    July 2013
    June 2013
    May 2013
    April 2013
    March 2013
    February 2013
    January 2013
    December 2012
    November 2012
    October 2012
    June 2012
    May 2012
    April 2012
    March 2012
    February 2012
    January 2012
    December 2011
    November 2011


    View my profile on LinkedIn
Photo used under Creative Commons from NASA Goddard Photo and Video