cancel
Showing results for 
Search instead for 
Did you mean: 

A Few Tips and Tricks When Creating NCM Config Change Templates

Level 18

As you probably know, Config Change Templates (CCT) are a very powerful feature of the Network Configuration Manager. On top of the Execute Script functionality, they add flow control statements such as conditions and loops. You can also use custom properties, define input parameters etc. -- please see for details. Just remember that your device must be inventoried in NCM in order to be targeted with Config Change Templates.

You can use one of the templates provided with NCM out of the box, import from thwack, or create your own from scratch. Today I would like to show you a few tips and tricks that you might find useful when creating your own, advanced templates.

How to Use Special Symbols in CLI Statements

Imagine you need to include the following command in a CLI statement of your CCT:

show clock | append disk0:show_tech

You can not do it directly -- the pipe symbol breaks the script. Here is the trick:

script BaseChangeTemplate(NCM.Nodes @ContextNode)

  string @PipeSymbol='|'                               Define a string variable to carry the special symbol.

  CLI

  {

    show clock @PipeSymbol append disk0:show_tech      Place the variable in the command.

  }

}

The same trick can be used for other special characters such as the '@' symbol.

How to Add Variables to CLI Statements

You may want to include certain variables, that you normally use e.g. in device templates, in your CCT. This approach helps you keep your template as device-independent as possible. Additionally, you can include e.g. IP address (of your TFTP server, for example) in a clean way which will not make you modify the CCT source code when this IP address changes. The trick is basically identical to the previous case. The following fragment can be used e.g. when handling firmware.

script BaseChangeTemplate(NCM.Nodes @ContextNode)

  string @myTFTPImage='${StorageAddress}' + '/image.bin'    ${StorageAddress} is the IP address of TFTP server that comes with NCM. It is used e.g. in device templates for config downloads.

  CLI

  {

    copy tftp://@myTFTPImage flash                          You do not have to hard-code the IP address in the command.

    ...

  }

}

Resulting script:

copy tftp://${StorageAddress}/image.bin flash

Using Custom Properties in CCTs

Unlike variables, custom properties are tied with nodes, and therefore can be referenced via the node parameter:


script BaseChangeTemplate (NCM.Nodes @ContextNode)
{
  CLI
  {
    show @ContextNode.MyCustomProperty
  }
}

Details about the use of custom properties in Config Change Templates is described in .

Configuring Specific Interfaces

A customer once asked how he could run a command on an interface with a specific IP address. (He wanted to set logging source interface on a Cisco router.) All you have to do is to iterate through interfaces and their IP addresses:

script BaseChangeTemplate(NCM.Nodes @ContextNode)

{

    foreach (@interfaceItem in @ContextNode.Interfaces)                        Iterate through all interfaces of the node.

    {

foreach(@ip in @interfaceItem.IpAddresses)                              Iterate through all IP addresses of that interface.

{

        if (@ip.IPAddress contains '10.199.2.1')                               Test the IP address.

        {

          CLI

          {

            logging source-interface @interfaceItem.InterfaceDescription       Set logging source.

          }

        }

      }

    }

}


Simultaneous Execution of CCTs

Last but not least, you can configure the number of devices for that can execute in parallel. In the Web UI (NCM v7.1), go to Settings -> NCM Settings -> Configs -> Config Transfer -> Simultaneous Downloads/Uploads.


Config-Settings.png


The default value is 10, i.e. when you run a template on 50 devices, the task will be carried out in 5 batches (10 devices each).

34 Comments
cem_a.
Level 9

Let's say I want to execute a command only if a specific command exists on configuration, is there way to do this?

for example:

if(runningconfig() contains "access-list 10")

{

     CLI

    {

        access-list 10 permit 1.2.3.4

    }

}

else if (runningconfig() contains "access-list 11")

     CLI

    {

        access-list 11 permit 1.2.3.4

    }

}

cvachovecj
Level 18

Hi,

This functionality is currently not available.

Regards,

Jiri

wanine39
Level 13

also look at TCL commands on IOS CLI

i use one called ipconfig on all my rtrs, simply google it

here is a sample output. it look best with fixed width fonts

#ipconfig

Interface            IP Address             MTU State

==============================================================

FastEthernet0/0      10.99.1.1/29          1500 up/down

FastEthernet0/1      173.35.184.130/23     1500 up

GigabitEthernet0/3/0 10.0.1.1/29           1500 up

GigabitEthernet0/3/0.1 no address                 up

FastEthernet1/0      no address                 up

FastEthernet1/1      no address                 up

FastEthernet1/2      no address                 up

FastEthernet1/3      no address                 up/down

rstoney00
Level 11

Jiri is correct on not available in the Config Change Templates area, however, you could do this with Compliance reporting.

Rule to search for your Access list, then run the scripts you want as a remediation script.

You would not be able to do the "else" portion, but that would be easily covered by two rules.

goodzhere
Level 14

How would I use this to set a password if the 'set password' command issued, replied with "Enter a password:" the first time and "Confirm the password:" after that.  I want to use my Cisco Password SNMPv3 Change NCM Template to change passwords for the Cisco UCS devices.  To do this, the prompt will change from "UCS_Device#" to "Enter a password:" to "Confirm the password:" and then back to the original.  How can I do this with a config change template?

cvachovecj
Level 18

In this context, both config change templates and scripts work in the same way. I think you could achieve this by the following sequence:

set password

password

password

Regards,

Jiri

ciobis
Level 9

Hi,

I am really new to NCM templates and scripts; this is something that I could use on our H3C switches:

"

script BaseChangeTemplate(NCM.Nodes @ContextNode)

{

    foreach (@interfaceItem in @ContextNode.Interfaces)                        Iterate through all interfaces of the node.

    {

foreach(@ip in @interfaceItem.IpAddresses)                              Iterate through all IP addresses of that interface.

{

        if (@ip.IPAddress contains '10.199.2.1')                               Test the IP address.

        {

          CLI

          {

            logging source-interface @interfaceItem.InterfaceDescription       Set logging source.

          }

        }

      }

    }

}

"

But, how do I customize this, so it looks for an interface with a description containing 'blabla' and apply a set of commands?

Thanks very much

cvachovecj
Level 18

Hi ciobis‌,

It depends on how the H3C switches reply to certain MIBs that NCM uses to collect information about interfaces. Update inventory and give it a try.

The code you are looking for would be:

script BaseChangeTemplate(NCM.Nodes @ContextNode)

{

    foreach (@interfaceItem in @ContextNode.Interfaces)                        Iterate through all interfaces of the node.

    {

        if (@interfaceItem.InterfaceDescription contains 'blabla')             Test the description.

        {

          CLI

          {

            command1

            command2

          }

        }

    }

}

Regards,

Jiri

ciobis
Level 9

hi Jiri,

Do I run the script through Configuration Management -->Execure Script? Sorry, not too much experience with this.

Thanks

cvachovecj
Level 18

Nope.

Configs -> Config Change Templates.

Jiri

ciobis
Level 9

Hi cvachovecj

I have to be in configuration mode to run the commands on the interfaces, so I modified the template like this:

script BaseChangeTemplate(NCM.Nodes @ContextNode)

{

  //enter configuration mode

  CLI

  {

   system-view

  }

  //loop through each interface

    foreach (@interfaceItem in @ContextNode.Interfaces)

    {

        if (@interfaceItem.InterfaceDescription contains 'blablabla')

        {

          CLI

          {

            description blabla

          }

        }

    }

}

But, when I run it, it only seems to only run the system-view command and not going further; I am sure I am missing a statement in between, due to my lack of scripting, just don't know where and what.

Thanks very much.

cvachovecj
Level 18

Have you updated inventory?

If yes, does the Interfaces report list the interfaces of your device? (Check Configs -> Reports -> Inventory -> Interfaces)

Jiri

ciobis
Level 9

I run the inventory update; The interfaces are displayed; one thing I needed to change is instead of "@interfaceItem.InterfaceDescription" use "@interfaceItem.InterfaceAlias"; the script is running, but it does not seem to loop through the interfaces. it attempts to apply the command in the config mode, instead of interface mode.

cvachovecj
Level 18

How about entering interface config mode at the beginning of the CLI statement in the inner-most loop:

...

if (@interfaceItem.InterfaceAlias contains 'blablabla')

        {

          CLI

          {

            @interfaceItem.InterfaceAlias

            description blabla

            exit

          }

        }

...

ciobis
Level 9

I have tried this as well, unfortunately no luck:

the output of the template running is this:

system-view

System View: return to User View with Ctrl+Z.

blablabla

[H3C-Switch]^

% Wrong parameter found at '^' position.

description blabla

[H3C-Switch]^

% Unrecognized command found at '^' position.

quit

ciobis
Level 9

This is the one that finally worked, even though extremely slow, more than 20 min to run on one device:

script BaseChangeTemplate(NCM.Nodes @ContextNode)
{
  CLI
  {
     system-view
  }

  foreach (@interfaceItem in @ContextNode.Interfaces)
  {
      if (@interfaceItem.InterfaceAlias contains 'blablabla')
      {
          CLI
          {
              interface @interfaceItem.InterfaceDescription
              description blabla
              quit
          }
      }
  }
}


Thanks for help

goodzhere
Level 14

cvachovecj‌  In reference to this:

HOW TO ADD VARIABLES TO CLI STATEMENTS

You may want to include certain variables, that you normally use e.g. in device templates, in your CCT. This approach helps you keep your template as device-independent as possible. Additionally, you can include e.g. IP address (of your TFTP server, for example) in a clean way which will not make you modify the CCT source code when this IP address changes. The trick is basically identical to the previous case. The following fragment can be used e.g. when handling firmware.

script BaseChangeTemplate(NCM.Nodes @ContextNode)

{

  string @myTFTPImage='${StorageAddress}' + '/image.bin'    ${StorageAddress} is the IP address of TFTP server that comes with NCM. It is used e.g. in device templates for config downloads.

  CLI

  {

    copy tftp://@myTFTPImage flash                          You do not have to hard-code the IP address in the command.

    ...

  }

}

Resulting script:

copy tftp://${StorageAddress}/image.bin flash

Can NCM 10.6.1 pull these pre-canned variables (${StorageAddress}) into Config Change Templates?  When I put the variable '${StorageAddress}' into a config change template, it does not work.  I get an error without the single quote and I get ${StorageAddress} with the single quotes.  I can get it to work when executing scripts, but I cannot when using in the CCTs.  Am I missing something?

cvachovecj
Level 18

Sorry, which version of NCM do you mean? (10.6.1 would be NPM.)

The above syntax should work with any NCM version 7+.

Jiri

goodzhere
Level 14

Sorry.  I messed that one up.  I am running 7.1.1. It is not working in the template.

cvachovecj
Level 18

Would you please share your code? I tried it myself and it works. I tried it with NCM 7.4 RC, but when I wrote this post back in 2012, 7.1.1 was the version I used.

goodzhere
Level 14

I can't attach the file to this reply.  Here is one of the templates with the code in it:

/*

.CHANGE_TEMPLATE_DESCRIPTION

        This template by Chris Good is used to upgrade the IOS on Cisco 3800 routers.

.CHANGE_TEMPLATE_TAGS

  Cisco, 3800 IOS

.PLATFORM_DESCRIPTION

        This runs on Cisco 3800 IOS devices.

 

.PARAMETER_LABEL @ContextNode

        NCM Node

.PARAMETER_DESCRIPTION @ContextNode

        The node the template will operate on.  All templates require this by default. The target node is selected during the first part of the wizard so it will not be available for selection when defining values of variables.

.PARAMETER_LABEL @IOS_FILENAME

        New IOS Filename

.PARAMETER_DESCRIPTION @IOS_FILENAME

        This should be a valid Cisco IOS file.  No spaces are allowed in this field.  A script will not be generated for a Cisco IOS

filename that includes a space.

        Example: c3825-advipservicesk9-mz.151-4.M4.bin

.PARAMETER_LABEL @SCPname

        SCP username

.PARAMETER_DESCRIPTION @SCPname

        Enter the SCP Server username.

        Example: scpuser

.PARAMETER_LABEL @SCPpassword

        SCP Password

.PARAMETER_DESCRIPTION @SCPpassword

        Enter the SCP password.  Password is case sensitive.

*/

  script Upgrade3800IOS (

                         NCM.Nodes @ContextNode,

                         string @IOS_FILENAME,

                         string @SCPname,

                         string @SCPpassword       )

{

  // Only select Cisco 3800 devices

  foreach ( @node in @ContextNode )

  {

string @CommandLine = 'upgrade automatic getversion scp://' + @SCPname + ':' + @SCPpassword + '@' + '${StorageAddress}' + '/Cisco/3800/' + @IOS_FILENAME + ' at now disk-management auto'

string @Pause='${Delay:15}'

    if ( @node.SysDescr contains 'Cisco IOS Software, 3800' )

    {

    // Send these lines if Cisco 3800 

      CLI

      {

configure terminal

autoupgrade disk-cleanup image

exit

wr

@CommandLine

@Pause

upgrade automatic runversion at now

      }

    }

  }

}

cvachovecj
Level 18

Remove the foreach ( @node in @ContextNode ) loop. The config change template is applied to each node separately.


Then you change

if ( @node.SysDescr contains 'Cisco IOS Software, 3800' )

to

if ( @ContextNode.SysDescr contains 'Cisco IOS Software, 3800' )

Jiri

goodzhere
Level 14

OK.  I tried this on the 7.3 and I ended up with the same issue.  Then I troubleshot a little and found that it was working all along.  I found what the disconnect was.  When I would go to execute the config change template, I would get to the preview portion and it would show the variable (${StorageAddress}) instead of the actual ip address that it was GOING to push to the device.  This is very misleading.  It would be nice if preview portion showed what it was going to push and not the variable that it is using.

cyates
Level 9

I am having trouble with a string inside a foreach loop - i get the error 'Cannot initialize as it has already been declared'

/*

.CHANGE_TEMPLATE_DESCRIPTION

     

.CHANGE_TEMPLATE_TAGS

  Cisco, CDP

.PLATFORM_DESCRIPTION

        Cisco IOS

.PARAMETER_LABEL @ContextNode

        NCM node

.PARAMETER_DESCRIPTION @ContextNode

        The node the template will operate on.  All templates require this by default. The target node is selected during the first part of the wizard so it will not be available for selection when defining values of variables.

*/

script ConfigureCDPInterfacesDescription  (NCM.Nodes @ContextNode)

{

    CLI

  {

    configure terminal

  }

foreach (@cdpItem in @ContextNode.CiscoCdp)

{

  string @Description = @cdpItem.RemoteDevice + ':' + @cdpItem.RemotePort

  foreach (@interfaceItem in @ContextNode.Interfaces)

  {

     if (@interfaceItem.InterfaceIndex== @cdpItem.ifIndex)

  {

         CLI

          {

             interface @interfaceItem.InterfaceDescription

      description @Description

      exit

          }

  }

  }

}

  CLI

  {

    end

  }

}

rschroeder
Level 21

Wow.  You all are my heroes!  I love the script wizard detail & expertise displayed herel.

michael.kent
Level 13

I still haven't found a way to do coherent error checking, say to null route but stop them entering /2 rather than /32?

bps
Level 10

have you found a solution for you problem, to execute a Command only if a specific command exists on configuration?? regards Pascal

goodzhere
Level 14

You can do this through the compliance piece of ncm.  It can search a config and then you can set a remediation action.

bartley
Level 10

Is there a way to use the current configuration settings as a dependency?

Example: only add a piece of configuration as the port is an access port?

We need to add this below, but only on access ports.

   snmp trap mac-notification change added
   snmp trap mac-notification change removed
macauxdragon
Level 7

I found a bug about CCT. As the below code (copy from Jiri Cvachovec and change a bit), when I use a symbol slash "/" and follow by "t", the result code will become a space, not "/t".
bug0.PNG

bug1.PNG

bug2.PNG

mbeckett
Level 7

I'm trying to use the script that is in the original post, shown here:

CONFIGURING SPECIFIC INTERFACES

A customer once asked how he could run a command on an interface with a specific IP address. (He wanted to set logging source interface on a Cisco router.) All you have to do is to iterate through interfaces and their IP addresses:

script BaseChangeTemplate(NCM.Nodes @ContextNode)

{

    foreach (@interfaceItem in @ContextNode.Interfaces)                        Iterate through all interfaces of the node.

    {

foreach(@ip in @interfaceItem.IpAddresses)                              Iterate through all IP addresses of that interface.

{

        if (@ip.IPAddress contains '10.199.2.1')                               Test the IP address.

        {

          CLI

          {

            logging source-interface @interfaceItem.InterfaceDescription       Set logging source.

          }

        }

      }

    }

}

However when I try to execute the config change template I get the following error:

   

Error:RunQuery failed, check fault information.

Conversion failed when converting from string to uniqueidentifier.

Any assistance would be greatly appreciated!

prady15kr
Level 7

I'm trying to use the data type available in NCM for data manipulation and not able to achieve expected results. Anyone please help to find how to call NCM.Vlans array of a particular node inside the script instead of user selection.

aussery
Level 12

Is there any way to run a command and set a conditional based on the output of the command?    

ferrashoo
Level 12

This is very cool, will try some of these out next week.

Labels