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
2
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="http://tail-f.com/ns/config/1.0">
2 <!--
3 tailf-ntool Generated File using NED package cisco-iosxr version [6.0.6]
4 -->
5 <devices xmlns="http://tail-f.com/ns/ncs">
6 <device>
7 <name>{$DEVICE}</name>
8 <config>
9 <l2vpn xmlns="http://tail-f.com/ned/cisco-ios-xr">
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="http://tail-f.com/ns/config/1.0">
2 <!--
3 tailf-ntool Generated File using NED package alu-sr version [6.1.1]
4 -->
5 <devices xmlns="http://tail-f.com/ns/ncs">
6 <device>
7 <name>{$DEVICE}</name>
8 <config>
9 <router xmlns="http://tail-f.com/ned/alu-sr">
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