Earlier|blog|posts in this Cisco DNA Center series gave an overview of PnP, how to use the API and an introduction to the configuration template editor. This blog post explores creating templates in velocity. Velocity is a template programming language, used in Cisco Prime Infrastructure and APIC-EM.
The template engine can be used for either Day-0 (PnP) or Day-N (provisioning) changes. There are a couple of subtle implications of this.
At the heart of any template is the concept of a "variable". Variables allow parts of a configuration to be customized for a specific device, while ensuring other parts are standardized across all devices. A single configuration template is required, but it can be applied to many devices. In velocity, variables begin with "$". A trivial example follows.
hostname $hname
To configure a hostnamefor a network device, the cli command "hostname adam-router" is used. "adam-router" is the name of the device. When applying this template to a set of devices, the only thing that changes is the variable ( $hname).
In the example above, there may be a requirement to always end the hostname with "-router". The "{}" can be used to specify which part of a string is a variable and which is a string. In the example below, the suffix will always be "-router" and$hname would be set to "adam" to achieve a similar result to the first example.
hostname ${hname}-router
When the variable$hname is set to "adam" the template renders as
hostname adam-router
Occasionally "$" is required to be used in the configuration for something other than a variable. This is often seen in encrypted passwords for example. It is possible to mark these as "not a variable" in the UI.
It is also possible to create a dummy variable for "$" and use that instead.
#set ($d = "$")enable secret 5 werw${d}2dsf3423${d}dd${d}
In the example above, a variable "d" is defined as "$". The "${d}" syntax is used where ever a "$" is required. The template above renders as
enable secret 5 werw$2dsf3423$dd$
Macros are a great way of encapsulating a block of CLI. For example, define a configuration block for an uplink. For example, define a configuration block for an uplink. Once the macro"uplink_interface"has been defined, it can be referenced as#uplink_interface
#macro(uplink_interface)switchport trunk native vlan 999switchport mode trunkchannel-group 1 mode active#endinterface Ten1/0/1#uplink_interface
This will render as:
interface Ten1/0/1switchport trunk native vlan 999switchport mode trunkchannel-group 1 mode active
Loops are a powerful control construct that can be used in templates. One common application is when combined with macros. The macro"uplink_interface"was defined above, and it needs to be applied to every uplink in a switch stack. A variable called stack_count is provided to the template which contains the number of switches in the stack.
#set ($stack_member_count =$stack_count)#foreach($switch in [1..${stack_member_count}])interface Ten${switch}/0/1#uplink_interface#end
When the variable "stack_count" is set to "2", the template renders as shown:
interface Ten1/0/1switchport trunk native vlan 999switchport mode trunkchannel-group 1 mode activeinterface Ten2/0/1switchport trunk native vlan 999switchport mode trunkchannel-group 1 mode active
It is important to define the data type of$stack_count as an integer. An integer will be treated as a number so the range [1..4] is shorthand for [1,2,3,4] for example. The earlier blog showed how to change the type of a variable. Here is a reminder
The final example shows how to manipulate IP addresses. A common example is supplying an IP address and needing to create the default gateway in a configuration file. The variable$iphas been defined as a string with IP address syntax. The split command breaks the string up on octet boundaries and returns an array. This is assigned to the variable$octets.
#set ($octets =$ip.split('\.'))gateway$octets[0].$octets[1].$octets[2].1
If$ipis set to "10.11.12.240", the template will render as
gateway 10.11.12.1
Optionally the data type of"$ip" can be set to ipAddress. This will do input validation in the UI of the template. If left as Data Type string, then any text could be entered.
This blog shows more detail on the template language -velocity. The next blog in the series will cover some advanced use cases
In the meantime, if you would like to learn more about this, you could visit Cisco DevNet. DevNet has further explanations about this. In addition, we have a Github repository where you can get examples related to PnP.
Thanks for reading!
@adamradford123
We'd love to hear what you think. Ask a question or leave a comment below.
And stay connected with Cisco DevNet on social!
Twitter @CiscoDevNet | Facebook | LinkedIn
Visit the new Developer Video Channel