Showing results for 
Search instead for 
Did you mean: 
Cisco Employee
Cisco Employee

Hi All,

One common complaint I often hear from NSO service developers is the amount of work it takes updating templates anytime there is a change to an underlying NED, so I thought that it might be worthwhile to investigate as to whether or not I could automatically generate an NSO template based on the CLI configuration. The remainder of this blog will discuss the proof-of-concept I came up with and I'll provide a link to the package I created as a result of the effort.

Solution Description:

The proof-of-concept is basically a package called ntool or tailf-ntool. The idea is that you can create a local install with the appropriate NEDs you will be deploying, your service package(s) and the ntool package. Uncompress the service package you want to generate templates for and load the packages. The tool doesn't require that your package actually loads correctly. One you have the environment in place you can try out the tool.

Before we get into the details there are a few limitations with the current version of the tool:

      • Ntool (available on the NSO Package Library) is not a supported package, but rather a proof-of-concept for template auto generation. You are free to modify/contribute to it and hopefully it improves over time.
      • Ntool works with templates that use variables {$VAR} as opposed to reading directly from the service model. This support is pretty straightforward and should be added in the near term
      • Ntool for now only handles a single device type per CLI configuration file. If you have multiple NED types in a template you will need to create a .cfg file for each device type and manually combine the output of the tool.

Using Ntool:

Step(1): Create CLI configuration files

Most service developers know the exact CLI configuration they want to NSO to deploy on CLI devices. To use the CLI tool the user creates a config file which contains the template variables and CLI configuration. The configuration file format is expected to be <TEMPLATE_FILE_NAME>.cfg. Tail-f ntool will then generate a template file <TEMPLATE_FILE_NAME>.xml

Consider the following example bridge_group.cfg:

        • The first line of the .cfg file must the NED package name
        • Variables show in {$[0-9A-Za-z\-\_] } present the variable part of the configuration.
        • Variables which are non-string like ip addresses or VLAN can be assigned an initial value to give the template generator a correct value for initially generating the template (See line 11 below)

  1 +NED:cisco-iosxr            First line of every .cfg file is the NED package required


  3 l2vpn

  4   bridge group {$BG-NAME}

  5   bridge-domain {$BG-NAME}

  6     mac

  7       withdraw state-down

  8     exit

  9     mtu 9800

10     vfi {$BG-NAME}

11     vpn-id {$VPN-ID=34}

12     autodiscovery bgp

13       rd auto

14       route-target {$BG-ROUTE-TARGET}

15     exit

16     exit

17   exit

18   exit

19 exit

Which generates the following template:

  1 <config-template xmlns="">

  2   <!--

  3     tailf-ntool Generated File using NED package cisco-iosxr version [6.0.6]

  4   -->

  5   <devices xmlns="">

  6   <device>

  7     <name>{$DEVICE}</name>

  8       <config>

  9         <l2vpn xmlns="">

10           <bridge>

11             <group>

12               <group-name>{$BG-NAME}</group-name>

13               <bridge-domain>

14                 <bridge-domain-name>{$BG-NAME}</bridge-domain-name>

15                 <mac>

16                   <withdraw>

17                     <state-down/>

18                   </withdraw>

19                 </mac>

20                 <mtu>9800</mtu>

21                 <vfi>

22                   <name>{$BG-NAME}</name>

23                   <vpn-id>{$VPN-ID}</vpn-id>

24                   <autodiscovery>

25                     <bgp>

26                       <rd>auto</rd>

27                       <route-target>

28                         <route-target-list>

29                           <name>{$BG-ROUTE-TARGET}</name>

30                         </route-target-list>

31                       </route-target>

32                     </bgp>

33                   </autodiscovery>

34                 </vfi>

35               </bridge-domain>

36             </group>

37           </bridge>

38         </l2vpn>

39       </config>

40   </device>

41 </devices>

42 </config-template>

The template generator substitutes the initial value for the variable name in the CLI "snippet". In some cases there might be some variable which cannot be set if they are null. Consider the following configuration example below, on line(s) 8 and 9:

  1 +NED:alu-sr

  2 exit all

  3 configure

  4 router Base

  5 bgp

  6   group {$PEER_GROUP}

  7   bfd-enable

  8   export     {$EXPORT-POLICY=nonull}

  9   import     {$IMPORT-POLICY=nonull}

10   exit

11 exit

12 exit

13 exit all

Generates the following template and you can see on lines 15 and 16 a when constraint is added to insure the variable name is constrained by a when condition requiring the variable(s) be non-null:

  1 <config-template xmlns="">

  2   <!--

  3     tailf-ntool Generated File using NED package alu-sr version [6.1.1]

  4   -->

  5   <devices xmlns="">

  6   <device>

  7     <name>{$DEVICE}</name>

  8       <config>

  9         <router xmlns="">

10           <router-name>Base</router-name>

11           <bgp>

12             <group>

13               <id>{$PEER_GROUP}</id>

14               <bfd-enable/>

15               <export when="{$EXPORT-POLICY!=''}">{$EXPORT-POLICY}</export>

16               <import when="{$IMPORT-POLICY!=''}">{$IMPORT-POLICY}</import>

17             </group>

18           </bgp>

19         </router>

20       </config>

21   </device>

22 </devices>

23 </config-template>

After creating the .cfg files which are then placed in a cli directory at the top level of the NSO package you wish to generate template files for.

Step(2): Execute the ntool command

admin@ncs> ntool cli template package sharedpackage     

Generating Service Configuration Template(s)

  Changing directory to package directory .............................. Success

  Searching for package [sharedpackage] ................................ Found

  Parsing [ADVA-825-FLOW-1CLASS-POP-1.cfg] ............................. Success

  NED Type:    adva-825

  NED Version: 3.6.9

  Parsing [ADVA-825-FLOW-1CLASS-POP-1.cfg] ............................. Completed

  Generating template from [ADVA-825-FLOW-1CLASS-POP-1.cfg] ............ Success

  Saving template file [ADVA-825-FLOW-1CLASS-POP-1.xml] ................ Success

  Parsing [ALU-BGP.cfg] ................................................ Success

  NED Type:    alu-sr

  NED Version: 6.1.1

Cisco Employee
Cisco Employee

Hi Daniel, I can't see the show package output in your above reply, I suppose it got truncated. Below is my show packages output:

admin@ncs# show packages package package-version


NAME           VERSION


cisco-ios      5.8.2   

cisco-iosxr    6.5     


juniper-junos  3.0.14  

ntool          1.8     

simple_radius  1.0

Also, the command syntax seems to be different from what is mentioned in the github page, e.g. below doesn't work for me:

ntool template type iosxr template-type config file /Users/Dan/Desktop/ospf.text

Cisco Employee
Cisco Employee

Hi Umesh,

Can you try to go to the source directory of ntool and type make clean all. After that try a package reload.


Cisco Employee
Cisco Employee

Not much luck, same behavior after make clean too ☹


UWANKHED-M-C2QA:src umesh$ make clean all

rm -rf ../load-dir/*

rm -f ../jar/.jar

cd java && ant -q clean || true


Total time: 0 seconds

rm -f java/src/com/tailf/ntool/namespaces/*.java

/Users/umesh/Work/ncs-4.6/bin/ncsc `ls ntool-ann.yang > /dev/null 2>&1 && echo "-a ntool-ann.yang"` \

--yangpath yang -c -o ../load-dir/ntool.fxs yang/ntool.yang

/Users/umesh/Work/ncs-4.6/bin/ncsc --java-disable-prefix --exclude-enums --fail-on-warnings --java-package com.tailf.ntool.namespaces --emit-java java/src/com/tailf/ntool/namespaces/ ../load-dir/ntool.fxs

/Users/umesh/Work/ncs-4.6/bin/ncsc --emit-python ../python/_namespaces/ ../load-dir/ntool.fxs

cd java && ant -q all

warning: bootstrap class path not set in conjunction with -source 1.6

1 warning


Total time: 1 second

UWANKHED-M-C2QA:src umesh$ pwd


UWANKHED-M-C2QA:src umesh$ cd ../..

UWANKHED-M-C2QA:packages umesh$ pwd


UWANKHED-M-C2QA:packages umesh$ ncs_cli -C -u admin

admin connected from using console on UWANKHED-M-C2QA

admin@ncs# packages reload

reload-result {

package cisco-ios

result true


reload-result {

package cisco-iosxr

result true


reload-result {

package cisco-nx

result true


reload-result {

package juniper-junos

result true


reload-result {

package ntool

result true


reload-result {

package simple_radius

result true



admin@ncs# ntool-commands verify device-type ios command-list "ip access-list extended rr"

result Error: on line 0: ip access-list extended rr

admin@ncs# ntool-commands create-template device-type ios command-list "router ospf 1"


Cisco Employee
Cisco Employee

Perhaps we could debug this together if that helps.


Cisco Employee
Cisco Employee

Dan, I will setup webex to go over the setup.



Cisco Employee
Cisco Employee

Thanks Dan for the help and resolving the issue in my setup. For benefit of others who face the similar issue, this is the resolution:

1. Reload script would fail in your environment:

admin@ncs# script reload all

/Users/umesh/Work/ncs-run-4.6/scripts: ok

/Users/umesh/Work/ncs-4.6/scripts: ok

    command: unchanged

/Users/umesh/Work/ncs-run-4.6/state/packages-in-use/1/ntool-master/scripts: ok ERROR: Skipping script. Script crashed (with return code 621) when invoked as " --command. ERROR: Skipping script. Script crashed (with return code 621) when invoked as " --command. ERROR: Skipping script. Script crashed (with return code 621) when invoked as " --command.

2. Check python path:

UWANKHED-M-C2QA:packages umesh$ which python


3. Under packages, go to ntool scripts dir, and edit .py files first line:





4. Reload packages (admin@ncs# packages reload) and bam! it works

5. admin@ncs# ntool template type iosxr template-type config file /Users/umesh/Work/releases/3.5/ntool/ospf.txt

Jan Lindblad
Cisco Employee
Cisco Employee

If you use

/usr/bin/env python

Jan Lindblad
Cisco Employee
Cisco Employee

[sorry, hit submit early]

If the first line of the script is

#!/usr/bin/env python

it should work across pretty much all Linux distros

Cisco Employee
Cisco Employee

Yes indeed, hashbang does the trick. It should work in linux and mac too. The code can be probably modified so that the problem doesn’t repeat for someone else too.


Cisco Employee
Cisco Employee

Hi Dan

I was looking at NSO northbound api docs as well as examples folder but couldn't figure out how to execute the generated config-template xml via API (REST or RESTCONF). Can you help me if you have it handy?


Cisco Employee
Cisco Employee

Great, I've made the changes to the repository. Thanks for the info!!


Cisco Employee
Cisco Employee
Dan - Love the tool and I might be doing something wrong but I am having issues applying the templates I create, I would also like to use the templates to create a compliance report, any thoughts?
Cisco Employee
Cisco Employee
Well there is part of the tool which creates device templates as well but I suppose I could allow you to generate device templates as opposed to service templates. What kind of issues are you having applying templates?
Level 1
Level 1

Hi @Dan.Sullivan


I loaded ntool for NSO 5.2.1 and I'm facing with some problems.

Our goal is to convert a device CLI command list into an XML template.

For example trying to convert the following commands:

interface Loopback 100
  ipv4 address

 from NSO CLI we execute the following command:

nso@ncs# ntool-commands create-template name PROVA ned-id cisco-iosxr-cli-7.15 command-list "interface Loopback 100\nipv4 address"

The result appears as follows:

result <config xmlns="">
  <devices xmlns="">
status success

As you can see the template is empty (commands are not present).

We expect something like this:

<devices xmlns="">
      <id xmlns:cisco-iosxr-cli-7.15="">cisco-iosxr-cli-7.15:cisco-iosxr-cli-7.15</id>
        <interface xmlns="">

Another aspect I would highlight is that the generated template is not stored on NSO CDB.

Have you any idea or suggestion on how to solve these problems?



Best Regards


Getting Started

Find answers to your questions by entering keywords or phrases in the Search bar above. New here? Use these resources to familiarize yourself with the NSO Developer community: