Using DCNM to Automate Cisco FabricPath Operations

In my final post on Cisco’s Data Center Network Manager (DCNM), I’m taking a look at the deployment capabilities and templating features which allow configuration to be deployed automatically to multiple devices. In its simplest case, this might be used to set a new local username / password on all devices in the fabric, but in theory it can be used for much more.

DCNM

DCNM Scripting

Let’s get one thing straight right out of the gate: this ain’t no Jinja2 templating system. While DCNM’s templates support the use of variables and some basic loop and conditional structures, the syntax is fairly limited and the only real-time interaction with the device during the execution of the template amounts to a variable containing the output of the last command issued. There are also very few system variables provided to tell you what’s going on. For example I couldn’t find a variable containing the name of the current device; I had to issue a hostname command and evaluate the response in order to confirm which device I was connecting to. That said, with a little creativity and a lot of patience, it’s possible to develop scripts which do useful things to the fabric.

Adding VLANS

One minor irritation I have with Fabricpath is that while it’s easy to build a large layer 2 Ethernet switching fabric, it’s not configured centrally like many of the newer SDN or large virtual-chassis technologies. As a result, performing what should be a simple task – adding a VLAN – turns into a tedious process of adding the same configuration to every single switch in the fabric. My test fabric has just 18 switches in it, but that’s quite enough repetition to be dangerous, and it’s easy to miss a device when configuring manually. Consequently, I’ll use the Add VLAN task as an example, and look at ways to use DCNM to automate the task to the point where the user simply has to enter a VLAN number and a description, and DCNM will do the rest automatically.

Inputs

The basic process to run a template is:

  1. Choose the template you want to run
  2. Choose which devices you want to run the template on
  3. Enter values for any variables which have to be provided to the template
  4. Select execution options (parallel or sequential, etc)
  5. Success

Sounds simple, so let’s look at the structure of a template in DCNM land.

Template Structure

DCNM configuration deployment templates follow a simple format:

##template properties 
name =[name of template];
userDefined= true;
supportedPlatforms = [list of platforms this can run on];
templateType = CLI;
published = [true|false];
##

##template variables
[this is where variables are defined]
## 

##template content 
[the configuration]
##

The header information is created automatically by filling in text boxes and checkboxes within the web interface, so it requires minimal effort. For the rest of the template, the framework is provided, but beyond that the content is entered manually.

Variables

A variable is something which may change each time the script is run, so it is requested from the user when the script is chosen to run. An example of a variable would be a VLAN id for a script which creates a new VLAN in the fabric; the user enters the VLAN id, and the script goes off and creates it.

At its simplest, variable definition is a type and a variable name. For example, the following code will prompt the user for VLAN_ID_RANGE:

##template variables
integerRange VLAN_ID_RANGE;
##

DCNM Variables

integerRange is a built-in data type which allows for, well, a range of integers to be entered, e.g. 5-10,15,17. Other variable types include integer, boolean, string, ipV4Address and more. On its own, this variable definition doesn’t provide much guidance to the user as to what they should enter, so it’s possible to add a Description as well:

##template variables
@(Description="New VLAN(s) to be created.")
integerRange VLAN_ID_RANGE;
##

DCNM Variable with Description

That’s an improvement over just the variable name, but the VLAN_ID_RANGE looks a bit ugly, so a display name can be defined as well:

##template variables
@(DisplayName="List of VLAN IDs (100-4096)", Description="New VLAN(s) to be created.")
integerRange VLAN_ID_RANGE;
##

DCNM Variable with Display Name

Other basic validation can be added to the input fields too, so for an integer field it would be possible to define a valid range of values thus:

integer VLAN_ID { min =100; max =4096; };

More complex validation may have to be performed manually however. For example, when requesting a VLAN name, not only is the length important, but the name also cannot contain spaces. This can be accomplished using something like this, which leverages the conditionals in the templating language:

##template variables 
@(DisplayName="VLAN Name (max 128 char)", Description = "No spaces allowed!")
string VLAN_NAME{ minLength =1; maxLength =128; };
##
##template content
if ($$VLAN_NAME$$ contains " ") {
! **** ERROR ****
! VLAN name contains 1 or more spaces.
! VLAN name will not be added.
!
}
##

The templates work similarly to a server-side include for HTML; any output to the page is considered to be a command to be issued to the switches. In this case, the output all begins with ! which is considered to be a comment by Cisco devices, so even if the user ignores the warning being shown on screen as part of the configuration, it won’t cause any harm if deployed. Helpfully, DCNM shows a preview of the calculated configuration (plus a rather confusing representation of any configuration that must resolve at run-time) before choosing to start deployment, so a warning like this will be obvious on the preview page. Here is an example where I enter 50 for the VLAN ID (which is outside the valid range) and specify a VLAN name containing one or more spaces:

DCNM Variable Input

The resulting preview is like this:

Error Message - Bad Range

Going back a page and changing the VLAN to a valid integer (500 in this case) shows this for the preview:
Error Message

Note from the configuration that if the user continues with the deployment, VLAN 500 will be created as requested but it will not be given a name.

Getting More Complex

In my example fabric, I also know that when creating a new VLAN I will need to add it automatically to the port-channel uplinks on my edge switches which connect to the routers. I want to be able to select the entire fabric when creating the new VLAN, but I also need special configuration for those two devices. My solution was to use the device names. The edge switch hostnames contain the text fabricedge, so I can use that to identify which switches need the additional configuration. As noted earlier, however, I will have to obtain the hostname for myself because it’s not passed to the script as a system variable. The built-in variable $$LAST_CMD_RESPONSE$$ contains, unsurprisingly, the last response received from the switch:

show hostname
if ($$LAST_CMD_RESPONSE$$ contains "fabricedge") {
interface port-channel 1
 switchport trunk allowed vlan add $$VLAN_ID$$
exit
interface port-channel 2
 switchport trunk allowed vlan add $$VLAN_ID$$
exit
}

Thus the configuration to add the new vlan to the trunks on the fabric edge switches will only show up if, at runtime, the response to show hostname includes the text fabricedge.

With a little input validation and some basic logic, I now have a template which I can use to create a new VLAN across the entire fabric, and trunk it to the routers connected to the fabric edge, all with a few clicks.

Oddities

Mandatory Variables

It’s not possible to create template without a populated variables section. My solution to that is fairly simple:

##template variables 
boolean POINTLESS_CHECKBOX;
##

This satisfies the parser sufficiently to allow the script to run without further interference.

System (Implicit) Variables

DCNM provides only two system variables at run-time: DEVICE_TYPE and DEVICE_IMG_VERSION.

DCNM Implicit Variables

At the very least it might be nice to have HOSTNAME as a built-in variable.

Documentation Fun

Finding V10 Syntax Documentation

Don’t bother, there isn’t any. At least, not based on this page:

DCNM Documentation Versions

Evidently the v7 release was a beast. The document required to learn about the template syntax, by the way, is System Management Configuration Guide, Cisco DCNM for LAN, Release 7.x. Although there does not appear to be a DCNM v8 or v9, and that document has not been updated for v10, it seems to cover the basics successfully.

Cut and Paste Gotchas

Once discovered, I found the documentation for the configuration template syntax a little weak, focusing more on examples than in a proper definition of the syntax. This might not be quite such a problem except that I found the parser to be quite picky at times, and the error messages are not entirely helpful in directing attention to problems in the script, so as a user it’s easy to be left staring and wondering where the error could possibly be. This is compounded by at least one use of smart quotes instead of straight quotes within the sample configuration in the documentation which means a cut and paste from the documentation to DCNM will fail.

For example, here’s a screenshot from the DCNM v7 documentation:

DCNM Sample Code

Cutting and pasting that code to DCNM and validating the syntax produces the following error:

DCNM Syntax Validation Error

Line 12? Let’s check:

DCNM Code Editor

Line 12 is the ## marker indicating the end of the variables section. According to that error, DCNM expected to see the end of file (EOF) before the template content section? That makes no sense. The cause of the error is simple as it turns out; compare the quote characters:

DCNM Code Zoomed In

I’m not sure why that confuses the parser, but it clearly does. For the most part the error messages are a bit hit and miss both in content and reported position of the error.

Putting It All Together

Despite having some minor issues getting straight with the syntax, I have battled on and come up with some scripts which I can use in production.

As a sample, I’ve shared a DCNM script on github called ADD_A_NEW_VLAN, which aims to add a fabricpath VLAN, set the description and configure uplinks for an edge router. It’s intended to be pointed at an entire fabric (both leaf and spine) so that the new VLAN is present everywhere and the only task remaining would be to configure an access port. The script performs some of the error checking described above, and a bit more in addition. Feel free to comment, clone or submit pull requests if you’re so inclined!

If DCNM is feeling a bit unloved in your organization, it might be worth paying it a visit to see if there’s something it can do for you.

5 Comments on Using DCNM to Automate Cisco FabricPath Operations

      • Well Michael, I promised I would let you know, and the answer is ….. YES.

        It’s totally undocumented, but with a modicum of cunning it was possible to do so, and incredibly, it’s quite fast too. I will post shortly (within the next month I hope!) with details of how it can be done.

  1. Outstanding nugget of knowledge, thanks for sharing. I’m doing first Nexus deployment and I’d like to tweak this script for multiple VLANs if possible. Also looking for a way to have configurations ready for when FEX’ come online; I connect a pair, power them up and the leaf pushes down port groupings by type.

Leave a Reply

Your email address will not be published.


*


This site uses Akismet to reduce spam. Learn how your comment data is processed.