Templates

When creating a template, it is possible to specify variables that will be contextually substituted. Many of these variables are available in the drop-down menu in the Template Editor (see Figure 12-4). It is also possible to create these files offline without the Template Editor and still use these variables.

The basic format of a template file is simply the text of the configuration to be downloaded to your device (see "Sample Template" section). However, you can put variable substitutions of the following form (for example, the variable name could be iosipaddress):

It is possible to create segments of templates that can be included in other templates. For example, you might have an Ethernet configuration that would be used by multiple devices. In each device template, you could have:

#include /opt/CSCOcnsie/Templates/ethernet_setup.cfgtpl

Now, you could centralize all the administration for Ethernet configuration in one file.

Caution Circular includes of template files are not allowed.

Sample Template

The following sample is the configuration template for the DemoRouter (DemoRouter.cfgtpl), which is pre-loaded on your system:

!

version 12.0

service timestamps debug uptime

service timestamps log uptime

no service password-encryption

service udp-small-servers

service tcp-small-servers

!

hostname DemoRouter

!

boot system flash c7200-is-mz

enable secret 5 $1$cMdI$.e37TH540MWB2GW5gMOn3/

enable password cisco

!

ip subnet-zero

!

interface FastEthernet0/0

no ip address

no ip directed-broadcast

no ip route-cache

no ip mroute-cache

shutdown

half-duplex

!

interface Ethernet1/0

ip address 10.10.1.1 255.255.255.240

no ip directed-broadcast

no ip route-cache

no ip mroute-cache

!

interface Ethernet1/1

no ip address

no ip directed-broadcast

no ip route-cache

no ip mroute-cache

shutdown

!

interface Ethernet1/2

no ip address

no ip directed-broadcast

no ip route-cache

no ip mroute-cache

shutdown

!

interface Ethernet1/3

no ip address

no ip directed-broadcast

no ip route-cache

no ip mroute-cache

shutdown

!

ip classless

ip route 0.0.0.0 0.0.0.0 10.10.1.1

ip http server

!

dialer-list 1 protocol ip permit

dialer-list 1 protocol ipx permit

!

line con 0

transport input none

line aux 0

line vty 0 4

password cisco

login

!

end

Configuration Control Templates

To restart a device with a new image, you need Configuration Control templates that contain the required CLI commands for image activation on particular devices.

For example, if you want to restart a Cisco 3600 Series router with an image named 3600.image, from the device console, you would issue the following CLI commands:

no boot systemboot system flash:3600.image

The content of the Configuration Control template for image activation should contain the CLI commands that you would normally enter from the device console to activate a new image on the device.

Dynamic Flow Control Template

The inventory information collected from image agents is made available for external users by means of the Dynamic Flow Control Template. This enables you to write templates that can control the flow of configuration and image distribution jobs, based on the inventory information.

Inventory Operations

These are the operations that are exposed to you to access the inventory of the device from the Dynamic Flow Control Templates:

Function

$!{invObj.getDram()}

Return Type

int (bytes).

Description

Dram = Main Mem Size + IO Mem Size.

Returns the size of the DRAM.

Function

$!{invObj.getVersionString()}

Return Type

String.

Description

Returns the version string of the current running image from the device inventory.

Function

$!{invObj.getImageFile()}

Return Type

String.

Description

Returns the current running image file name.

Function

$!{invObj.getImageMD5()}

Return Type

String.

Description

Returns the MD5 as provided in the device inventory.

Function

$!{invObj.getStartedAt()}

Return Type

String.

Description

Returns the time string of when the device started.

Function

$!{invObj.getPlatformName()}

Return Type

String.

Description

Returns the platform name.

Function

$!{invObj.getFlash()}

Return Type

int (bytes).

Description

Returns the size of the flash.

Function

$!{invObj.getFileSysSize("bootflash")}

Return Type

int (bytes).

Description

Returns the size of the bootflash.

Function

$!{invObj.getFileSysFreespace("bootflash")}

Return Type

int (bytes).

Description

Returns the amount of free space in the bootflash.

Function

$!{invObj.getFileSysSize("nvram")}

Return Type

int (bytes).

Description

Returns the size of the NVRAM.

Function

$!{invObj.getFileSysFreespace("nvram")}

Return Type

int (bytes).

Description

Returns the amount of free space in the NVRAM.

Function

$!{invObj.getFileSysSize("disk0")}

Return Type

int (bytes).

Description

Returns the size of disk0.

Function

$!{invObj.getFileSysFreespace("disk0")}

Return Type

int (bytes).

Description

Returns the amount of free space in disk0.

Function

$!{invObj.getFileSysSize("slot0")}

Return Type

int (bytes).

Description

Returns the size of slot0.

Function

$!{invObj.getFileSysFreespace("slot0")}

Return Type

int (bytes).

Description

Returns the amount of free space in slot0.

Function

$!{invObj.getFileSysSize("slot1")}

Return Type

int (bytes).

Description

Returns the size of slot1.

Function

$!{invObj.getFileSysFreespace("slot1")}

Return Type

int (bytes).

Description

Returns the amount of free space in slot1.

Other Operations

These are the operations that are exposed to you to perform an action based on the above criterion from the Dynamic Flow Control Template:

As seen in the example above, you can customize the flow of the job depending on the DRAM size.

When a custom job with the above inventory template is submitted, the device is queried for its inventory, and depending on the DRAM size, the decision is made if the image upgrade is to be performed or not. Hence when the above example inventory template is evaluated, if the DRAM size of the device is greater than 6100 bytes the image distribution and image activation will be performed.

Sample1

#set( $dram = $!{invObj.getDram()} )

#set( $flash = $!{invObj.getFlash()} )

##

#if ($dram > 64000000)

$!{cnsceObj.distribute()}

#if ( $flash > 48000000 )

$!{cnsceObj.activate("persist")}

#end

#end

Sample 2

#set( $disk0free = $!{invObj.getFileSysFreespace("disk0")} )

##

#if $disk0free > 3500000)

$!{cnsceObj.distribute()}

$!{cnsceObj.activate("persist")}

#end

Sample 3

#set( $flash = $!{invObj.getFlash()} )

##

#if ($flash > 65000000)

$!{cnsceObj.updateConfig(true, "persist")}

#end

Templates for Modular Routers

The template mechanism for the devices has been enhanced to support modular routers. A modular router chassis includes slots in which you can install modules. You can install any module into any available slot in the chassis. Some modules like 2 Ethernet 2 WAN card slot module can in turn have sub slots to install interface cards or line cards. Device management has been extended to support subdevices representing line cards.

Additional attributes representing line card number, line card type, and subdevices have been added to the existing device object structure in the directory server in order to have the same structure to represent the main device or the subdevice.

Currently, card type is a string that maps to the product code of the network module. Since the EPROM data in the card stores part numbers only, not product codes, the part numbers are mapped to product codes. The user uses part numbers and the configuration server maps part numbers to product codes.

In the context of main device, the line card number and line card type fields make no sense and hence are set to NULL value. The subdevices field in the sub device (representing the line card) is set to NULL value.

New interface variable support has been added. These variables are included in the templates, which are parameterize with the interface numbers in the template. These are not attributes. They are special format variables that are replaced by the configuration server based on the interface information, which comes from the device. These variables only specify the relative position of the interface on the module and are replaced by the actual slot number, shelf-ID or port number. The interface variables are wrapped in percent sign (%) characters and specify the type, if any, and the relative position. The configuration server replaces these variables with the interface numbers. The interface type still has to be specified in the CLI using the following syntax:

Interface Variable = %[InterfaceType] RelativePosition%

For example:

%FastEthernet 0% for interface FastEthernet

%Serial 0% interface Serial

%T1 0% controller T1

%E1 0% controller E1

%voice-port 0% voice-port

Example 1:

A network module with two FastEthernet ports plugged in Slot 2 would be referred in the configuration CLI as FastEthernet 2/0 and FastEthernet 2/1 and referred in the template as FastEthernet %FastEthernet 0% and FastEthernet %FastEthernet 1%:

!

interface FatsEthernet 2/0

ip address 10.10.1.1 255.255.255.0

!

interface FatsEthernet 2/1

ip address 20.20.1.1 255.255.255.0

!

Templates for these CLIs would be:

!

interface FastEthernet %FastEthernet 0%

ip address 10.10.1.1 255.255.255.0

!

interface FastEthernet %FastEthernet 1%

ip address 20.20.1.1 255.255.255.0

!

Example 2 (Voice card with two ports plugged in slot 3):

!

voice-port 3/0/0

description 4082224444

!

voice-port 3/0/0

description 4082225555

!

Templates for these CLIs would be:

!

voice-port %voice-port 0%

description 4082224444

!

voice-port %voice-port 1%

description 4082225555

!

The main device template does not include links to the subdevice templates. The subdevice templates are appended to the main device template. The line card numbers are a parameter in the subdevice templates.

All the CLI commands which reference a line card interface are specified in the subdevice template for that line card. This implies that any command in the global configuration mode, or otherwise, that refers to a particular line card interface is in the template for that subdevice (line card) and not in the main device template.

Only the CLI commands in the global configuration mode, and not pertaining to the any specific interface, are specified in the main device template.

The port number and channel number are not template parameters since these are fixed for a given line card. The network administrator can configure specific channels on the interfaces by explicitly specifying the channels in the subdevice templates.

For example:

interface Serial %Serial 0%:0

Sample Templates for Modular Router

The names of the attributes for slot, slot-unit, line card type and so forth, are used for demonstration purposes.

Main Device Template

!

version 12.2

no parser cache

no service single-slot-reload-enable

service timestamps debug uptime

service timestamps log uptime

no service password-encryption

!

hostname 2600

!

logging rate-limit console 10 except errors

!

memory-size iomem 25

ip subnet-zero

!

!

!

no ip dhcp-client network-discovery

lcp max-session-starts 0

!

ip classless

no ip http server

!

call rsvp-sync

!

no mgcp timer receive-rtcp

!

mgcp profile default

!

dial-peer cor custom

!

!

!

!

line con 0

line aux 0

line vty 0 4

login

line vty 5 15

login

!

FastEthernet Template

Interface FastEthernet %FastEthernet 0%

ip address 10.0.0.1 255.0.0.0

shutdown

speed auto

Voice-port Template

voice-port %voice-port 0%

playout-delay mode adaptive

!

voice-port %voice-port 1%

!

dial-peer voice 10 pots

destination-pattern 200

port %voice-port 0%

forward-digits all

voice-port %voice-port 0%

!

dial-peer voice 20 pots

destination-pattern 100

port %voice-port 0%

!

voice-port %voice-port 1%

Modular Router Events

Modular router events are published to the event bus and are accessible to applications connected to the bus. The IOS device publishes the system hardware configuration in the cisco.cns.config.device-details event after hardware discovery. The Cisco Configuration Engine is configured to listen for this event, retrieve it, and extract the hardware configuration of the device.

Following is the DTD of the cisco.cns.config.device-details event that the Cisco IOS device sends:

Dynamic Templates

There might be times when the actual contents of a template needs to be dynamically generated. To do this, you would use the #call mechanism. This executes a JavaScript program whose output becomes part of the template. The program is re-executed each time a device asks for the template.

For example, you might want to distribute the load across the various event gateway processes without permanently assigning a device to a particular event gateway. This is useful because of the limit of 500 devices per event gateway daemon instance.

Let us take the following template as an example:

version 12.0

service timestamps debug uptime

service timestamps log uptime

no service password-encryption

service udp-small-servers

service tcp-small-servers

!

hostname DemoRouter

#call /opt/CSCOcnsie/Templates/event_setup.js

Here is an example of an event_setup.js that one might use:

/*

* An instance of Event Gateway resides on every odd port from 11011 to 11031.

* This will choose a random one in this range so that devices are spread out

* evenly among the various ports. Adjust the IP address in the println

* statement to be the address of the IE2100 itself.

*/

var port = Math.floor(Math.random() * 11) * 2 + 11011;

println("cns event 10.1.6.131 " + port.toString());

The result of this combination would be a template that appears as follows:

version 12.0

service timestamps debug uptime

service timestamps log uptime

no service password-encryption

service udp-small-servers

service tcp-small-servers

!

hostname DemoRouter

cns event 10.1.6.131 11017

The last line is programmatically determined and recalculated every time the template is requested by the device. So the next time a device requests this template, the last line might be:

cns event 10.1.6.131 11023

Simple modifications to event_setup.js could even be used to distribute devices across multiple host devices (by dynamically generating the IP address). It could also be used to affect any part of the device configuration—be it DNS servers or routing tables. Anything that is printed out by the JavaScript program becomes a dynamic part of the template.

Control Structures

The configuration template can include simple control structures such as, if, else and elseif. By using these control structures, the user can include or exclude a block of CLI commands based on a parameter stored in the directory.

The syntax for these # preprocessing control structures is as follows:

Syntax Description

#if<URL> = constant

cli-command(s)

#elseif<URL> = constant

cli-command(s)

#else

cli-command(s)

#endif

Where constant is an integer, boolean or a string in single quotes and the <URL> is a URL pointing to an attribute in the Directory or Database.

Note Nested #if and #elseif is NOT supported.

Usage Guidelines

The configuration template can include #define entries to define short names for long URLs.

The syntax for the #define preprocessing command is as follows:

#definedefinition-name <URL> | constant

where <URL> is a reference to an attribute in the directory.

The configuration template can contain another # preprocessing command #include, which allows the inclusion of other configuration templates or the results of an ASP page.

The syntax for the # preprocessing command is as follows:

#include <URL> | `<Filename>' | <Filename>

Whenever an #include directive is encountered, it is replaced by the content of the file.

The following configuration template sample includes either IP sub-template or ISDN sub-template based on the value of the parameter protocol in the directory or database.

Examples

!

version 12.0

service timestamps debug uptime

service timestamps log uptime

no service password-encryption

service udp-small-servers

service tcp-small-servers

!

hostname ${LDAP://this:attrName=IOShostname}

#if ${LDAP://this:attrName=IOSIPprotocol} == true then

#include ${LDAP://this:attrName=IPsubTemplate}

#else

#include ${LDAP://this:attrName=ISDNsubTemplate}

#endif

The parameter, ${LDAP://this:attrName=IPsubTemplate} contains the location of the file.

Managing Templates

To access Template management tasks, log into the system (see "Logging In" section on page 2-1). Then, from the Home page, click the Tools tab. The Tools page appears.