Advanced NSO Template Service
Load blank.ssh.enabled.cfg
#IOS-XE
config replace flash:blank.ssh.enabled.cfg
#IOS-XR
configure
load bootflash:blank.ssh.enabled.cfg
commit replace
y
Task 1. Create a template service
Create one single template service that configures loopback99 on either IOS-XE or IOS-XR.
The YANG module should only allow one device per service.
The loopback should be restricted to the format 10.0.0.X.
The mask should always be /32.
The loopback address should always be required.
The loopback must be unique between multiple devices.
If you are starting this lab without doing the previous one, you can add all devices to NSO with this config:
Initial NSO Configuration
devices global-settings ssh-algorithms public-key [ ssh-ed25519 ecdsa-sha2-nistp256 ecdsa-sha2-nistp384 ecdsa-sha2-nistp521 rsa-sha2-512 rsa-sha2-256 ssh-rsa ssh-dss ]
devices device r1
address 10.254.0.101
authgroup default
device-type cli ned-id cisco-ios-cli-6.92
device-type cli protocol ssh
ssh host-key-verification none
state admin-state unlocked
devices device r2
address 10.254.0.102
authgroup default
device-type cli ned-id cisco-ios-cli-6.92
device-type cli protocol ssh
ssh host-key-verification none
state admin-state unlocked
devices device r3
address 10.254.0.103
authgroup default
device-type cli ned-id cisco-ios-cli-6.92
device-type cli protocol ssh
ssh host-key-verification none
state admin-state unlocked
devices device r4
address 10.254.0.104
authgroup default
device-type cli ned-id cisco-ios-cli-6.92
device-type cli protocol ssh
ssh host-key-verification none
state admin-state unlocked
devices device r5
address 10.254.0.105
authgroup default
device-type cli ned-id cisco-ios-cli-6.92
device-type cli protocol ssh
ssh host-key-verification none
state admin-state unlocked
devices device r6
address 10.254.0.106
authgroup default
device-type cli ned-id cisco-ios-cli-6.92
device-type cli protocol ssh
ssh host-key-verification none
state admin-state unlocked
devices device r7
address 10.254.0.107
authgroup default
device-type cli ned-id cisco-ios-cli-6.92
device-type cli protocol ssh
ssh host-key-verification none
state admin-state unlocked
devices device r8
address 10.254.0.108
authgroup default
device-type cli ned-id cisco-ios-cli-6.92
device-type cli protocol ssh
ssh host-key-verification none
state admin-state unlocked
devices device r9
address 10.254.0.109
authgroup default
device-type cli ned-id cisco-ios-cli-6.92
device-type cli protocol ssh
ssh host-key-verification none
state admin-state unlocked
devices device r10
address 10.254.0.110
authgroup default
device-type cli ned-id cisco-ios-cli-6.92
device-type cli protocol ssh
ssh host-key-verification none
state admin-state unlocked
devices device xr1
address 10.254.0.111
authgroup default
device-type cli ned-id cisco-iosxr-cli-7.49
device-type cli protocol ssh
ssh host-key-verification none
state admin-state unlocked
devices device xr2
address 10.254.0.112
authgroup default
device-type cli ned-id cisco-iosxr-cli-7.49
device-type cli protocol ssh
ssh host-key-verification none
state admin-state unlocked
devices device xr3
address 10.254.0.113
authgroup default
device-type cli ned-id cisco-iosxr-cli-7.49
device-type cli protocol ssh
ssh host-key-verification none
state admin-state unlocked
devices device xr4
address 10.254.0.114
authgroup default
device-type cli ned-id cisco-iosxr-cli-7.49
device-type cli protocol ssh
ssh host-key-verification none
state admin-state unlocked
devices device-group XE
device-name r1
device-name r2
device-name r3
device-name r4
device-name r5
device-name r6
device-name r7
device-name r8
device-name r9
device-name r10
devices device-group XR
device-name xr1
device-name xr2
device-name xr3
device-name xr4
devices device-group ALL
device-group XE
device-group XR
Task 1 Answer
# Stop ncs
cd ~/nso-instance
ncs --stop
# Navigate to the packages dir of the instance
cd ~/nso-instance/packages
# Create a skeleton template package
ncs-make-package --service-skeleton template loopback
# Edit the YANG data module
nano ~/nso-instance/packages/loopback/src/yang/loopback.yang
Change the leaf-list device line to just a leaf. By default, this service can be applied to a list of devices. However, we are configuring one service per device.
Change the dummy leaf to be an “ip-address” leaf. Add a constraint and make this leaf required. Use the pattern keyword, making sure to preface literal dots with two slashes (\\).
Require that the ip-address leaf value is unique among all instances of this service.
Grab the XML config from NCS using a template and outputting the dry-run in XML format. Previously, we created a template per-device type. However, NCS native templates allow you to specify a config per-NED type. We can use this to build a single package template that handles both XE and XR.
config
devices template LOOPBACK
ned-id cisco-iosxr-cli-7.49
config
interface Loopback 99
ipv4 address ip 10.0.0.1
ipv4 address mask 255.255.255.255
!
!
!
ned-id cisco-ios-cli-6.92
config
interface Loopback 99
ip address primary address 10.0.0.1
ip address primary mask 255.255.255.255
commit dry-run outformat xml
We’ll use both of the config sections for the package template. NCS is able to know whether to apply the IOS or IOSXR config to each device.
nano ~/nso-instance/packages/loopback/templates/loopback-template.xml
We’ll now make the package.
cd ~/nso-instance/packages/loopback/src
make
Start NCS and reload the packages.
cd ~/nso-instance
ncs
ncs_cli -Cu admin
packages reload
Task 2. Apply one service per device
Task 2 Answer
# Shown below is only R1, R2, XR1, and XR2
loopback R1
device r1
ip-address 10.0.0.1
!
loopback R2
device r2
ip-address 10.0.0.2
!
loopback XR1
device xr1
ip-address 10.0.0.11
!
loopback XR2
device xr2
ip-address 10.0.0.12
Notice how the YANG module affects the CLI. When we create a new service, we are prompted for the required IP address:
We are also constrainted to the format 10.0.0.X:
Additionally, we can only apply each service to one device, as we changed the device type from leaf-list to leaf. If device was a leaf-list, we would have an open bracket ([) as a possible completion:
When we commit the config, NSO only applys the IOS config to the IOS-XE routers, and the IOS-XR config to the IOS-XR routers.
Also, notice that the loopback IP address must be unique between services. We cannot assign the same IP address to different loopback services:
Task 2a. Auto-rollback Example
Currently R1 has 10.0.0.1/32 on a different interface:
Watch what happens when I commit:
On another device, such as R2, the configuration is changed, but then is automatically rolled back when NSO finds that the IP address overlaps with another existing interface.
This is called an atomic commit. NSO only allows the commit to complete on all devices if all devices are successful. If any one device has an issue, the commit is rolled back on all devices completely.
Task 3. Add BGP advertisement of the loopback to the template
Add configuration that advertises the loopback into BGP ASN 65000 to the template. Make sure that you account for the differences in IOS-XE vs. IOS-XR.
Task 3 Answer
# Edit the template to include the BGP configuration.
# Stage this in NSO first to capture the XML formating
devices device r1
config
router bgp 65000
network 1.1.1.1 mask 255.255.255.255
!
!
!
devices device xr1
config
router bgp 65000
address-family ipv4 unicast
network 1.1.1.1/32
commit dry-run outformat xml
Notice above that after the <config> stanza, we have the same router XMLNS (XML namespace) stanza. This means that we can simply take the config at this router stanza and paste it underneath our loopback config.
nano ~/nso-instance/packages/loopback/templates/loopback-template.xml
user@ubuntu22-server:~/nso-instance$ cat ~/nso-instance/packages/loopback/templates/loopback-template.xml
<config-template xmlns="http://tail-f.com/ns/config/1.0"
servicepoint="loopback">
<devices xmlns="http://tail-f.com/ns/ncs">
<device>
<name>{/device}</name>
<config>
<interface xmlns="http://tail-f.com/ned/cisco-ios-xr">
<Loopback>
<id>99</id>
<ipv4>
<address>
<ip>{ip-address}</ip>
<mask>255.255.255.255</mask>
</address>
</ipv4>
</Loopback>
</interface>
<router xmlns="urn:ios">
<bgp>
<as-no>65000</as-no>
<network>
<number>{ip-address}</number>
<mask>255.255.255.255</mask>
</network>
</bgp>
</router>
<interface xmlns="urn:ios">
<Loopback>
<name>99</name>
<ip>
<address>
<primary>
<address>{ip-address}</address>
<mask>255.255.255.255</mask>
</primary>
</address>
</ip>
</Loopback>
</interface>
<router xmlns="http://tail-f.com/ned/cisco-ios-xr">
<bgp>
<bgp-no-instance>
<id>65000</id>
<address-family>
<ipv4>
<unicast>
<network>
<net>{ip-address}/32</net>
</network>
</unicast>
</ipv4>
</address-family>
</bgp-no-instance>
</bgp>
</router>
</config>
</device>
</devices>
</config-template>
user@ubuntu22-server:~/nso-instance1$
We’ll now reload this package in NCS and apply it to our routers.
ncs_cli -Cu admin
packages reload
conf
loopback R1 ip-address 10.0.0.1 device r1
loopback XR1 ip-address 10.0.0.11 device xr1
Last updated