Labnms 2500 LG
Labnms 2500 LG
Pre-requisite...................................................................................................................................... 4
Overview ........................................................................................................................................... 4
Step 5. Complete l2vpn template to map service model to device model mapping ............... 19
Task 2: Service discovery and reconciliation A: Create L2Vpn service instances from pre-existing
configuration. .............................................................................................................................. 27
Step 13. Try to delete the service instance created at Step 10 ............................................ 36
Step 17. Implement the action call back function to reconcile pre-exisiting L2VPN service. 46
Step 18. Define the helper functions used in reconcile action. ............................................ 51
Step 20. Test the action script to discover all pre-existing L2VPN services .......................... 56
Learning Objectives
Upon completion of this lab, you will be able to:
Use Cisco Network Services Orchestrator (NSO) to create, deploy and test a service package
(L2VPN).
Understand the brownfield service deployment challenges.
Discover and reconcile pre-existing L2VPN services manually
Create an action to discover and reconcile the pre-existing L2VPN services automatically.
Pre-requisite
Basic understanding of network orchestration, NETCONF/Yang
Basic knowledge of Cisco Network Services Orchestrator (NSO)
Overview
As an industry leading orchestration platform, NSO is widely used to provide service lifecycle
orchestration for hybrid networks. While new services are deployed using NSO service packages,
service providers normally have brownfield network, in which there are pre-existing configuration in
the network orchestrated by legacy tools. For brownfield network, NSO needs to discover and
reconcile pre-existing services.
In this lab, you will create a simple L2VPN service package to configure Layer 2 Transport
encapsulation on Bundle Ethernet sub-interfaces; you will also discover and reconcile pre-existing
L2VPN services from the network.
Figure 1 illustrates the network topology. The network is composed of simulated NSO NETSIM ASR
devices (Cisco IOS-XR). You will create L2VPN services from CE-PE. This lab focuses on PE
configuration. To simulate the brownfield network, the PE devices are populated with pre-existing
L2VPN services.
PE
PE
PE
CE
NSO application is pre-installed on Linux VM, with the details as in Table 1. NSO runtime directory is
set to /home/nso/ncs-run (NSO runtime directory is to keep NSO’s database, state files, logs and
other files. At any time if you need to start NSO, make sure that you are situated at NSO runtime
directory)
Installed Details
NSO version 5.0.1
NSO Install type local
NSO Install location /home/nso/ncs-5.0.1
NSO runtime directory /home/nso/ncs-run
NSO packages: cisco-iosxr version 6.6
Devices added to NSO application asr9k0, asr9k1, asr9k2
user Jump start Jump Start Server credential nso application nso
server (RDP) host application
server
credential
Lab user 1 128.107.235.22 WEIGANG\labuser1/c1sco123# 172.23.123.211 nso/cisco123
Lab user 2 WEIGANG\labuser2/c1sco123# 172.23.123.212
Lab user 3 WEIGANG\labuser3/c1sco123# 172.23.123.213
Lab user 4 WEIGANG\labuser4/c1sco123# 172.23.123.214
Lab user 5 WEIGANG\labuser5/c1sco123# 172.23.123.215
Lab user 6 WEIGANG\labuser6/c1sco123# 172.23.123.216
Lab user 7 WEIGANG\labuser7/c1sco123# 172.23.123.217
Lab user 8 WEIGANG\labuser8/c1sco123# 172.23.123.218
Lab user 9 WEIGANG\labuser9/c1sco123# 172.23.123.219
Lab user 10 WEIGANG\labuser10/c1sco123# 172.23.123.220
Lab user 11 WEIGANG\labuser11/c1sco123# 172.23.123.221
Lab user 12 WEIGANG\labuser12/c1sco123# 172.23.123.222
Lab user 13 WEIGANG\labuser13/c1sco123# 172.23.123.223
Lab user 14 WEIGANG\labuser14/c1sco123# 172.23.123.224
Lab user 15 WEIGANG\labuser15/c1sco123# 172.23.123.225
Lab user 16 WEIGANG\labuser16/c1sco123# 172.23.123.226
Lab user 17 WEIGANG\labuser17/c1sco123# 172.23.123.227
Lab user 18 WEIGANG\labuser18/c1sco123# 172.23.123.228
Lab user 19 WEIGANG\labuser19/c1sco123# 172.23.123.229
Lab user 20 WEIGANG\labuser20/c1sco123# 172.23.123.230
from desktop, to open a putty connection, enter IP address as listed in Table 2 Lab access
information.
Make sure you entered the ip address assigned to you. (172.23.123.211 for
labuser1, 172.23.123.212 for labuser2, ….)
[nso@cl-lab-211]$ cd ncs-run
[nso@cl-lab-211 ncs-run]$ pwd
/home/nso/ncs-run
[nso@cl-lab-211 ncs-run]$ ncs --version
5.0.20181016.1
5. Make sure NSO is running, if you get “connection refused” as the following, start NSO
application:
Note: If you get errors for “ncs” command, make sure you are in your nso runtime
directory: /home/nso/ncs-run
8. Sync up the devices to bring the PE devices configuration into NSO’s device model.
You have finished Task 0: Verify Lab Setup. Now you are ready to move on to the next Task: Create a
service package.
Our job is to create the service package. As shown in Table 3 and Table 4, the service gets a list of
PE’s. For each PE, it needs to create a Layer 2 transport Bundle-Ethernet sub-interface, where the PE
Port number is to identify the Bundle-Ethernet interface. Service tag (stag) is the VLAN id to be
encapsulated. stag is also used as sub-interface id of Bundle-Ethernet port. Customer name and
order number need to be put as the description of the sub-interfaces.
In this task, you will create a service package skeleton, and a service Yang model to capture the
service attributes as in Table 3. You will then create service to device mapping to support the
configuration of CLIs as in Table 4. At the end, you will deploy the service package onto your NSO
host.
The service model is illustrated in Figure 2. As shown in the diagram, L2Vpn is modelled as a list of
ncs services. “sr-name” is the key of the list. Each L2Vpn contains leaf nodes of order-number and
customer-name. In addition, it contains a list of pe-devices, each with a Bundle-Ether port and an
stag (service tag).
9. From NSO application VM, create a service skeleton package using “ncs-make-package”
command, name it L2Vpn.
10. “ncs-make-package” creates a directory structure (L2Vpn), and skeleton of service files.
11. Inspect the skeleton files, make sure files Makefile, L2Vpn.yang and L2Vpn-
template.xml are created:
jump server using ( ). Edit the file using editors such as Sublime ( ), Notepad++(
). If you take Option 2, remember copy the file back to NSO server.
12. The auto-generated L2Vpn.yang file contains several skeleton blocks. You need to update L2Vpn
block to add service attributes. Modify the generated Yang file, locate the block starts with
“list L2Vpn”:
augment /ncs:services {
list L2Vpn {
description "This is an RFS skeleton service";
key sr-name;
leaf sr-name {
tailf:info "Unique service name";
tailf:cli-allow-range;
type string;
}
uses ncs:service-data;
ncs:servicepoint L2Vpn-servicepoint;
14. Add other service attributes: order-number, customer-name, and pe-devices after
sr-name block. Note, attribute pe-devices is a list with device-name as the key. We use
leaf reference (leafref) points to NSO’s device model:
(/ncs:devices/ncs:device/ncs:name)
list L2Vpn {
description "This is an RFS skeleton service";
key sr-name;
leaf sr-name {
tailf:info "Unique service name";
tailf:cli-allow-range;
type string;
}
leaf order-number {
type string;
}
leaf customer-name {
type string;
}
list pe-devices {
key device-name;
leaf device-name {
type leafref {
path “/ncs:devices/ncs:device/ncs:name”;
}
}
list pe-devices {
key device-name;
leaf device-name {
type leafref {
path "/ncs:devices/ncs:device/ncs:name";
}
}
leaf Bundle-Ether {
type string;
}
leaf stag {
type uint16 {
range 1..4095;
}
}
}
}
}
}
revision 2016-01-01 {
description
"Initial revision.";
}
//AUGMENT_BEGIN
augment /ncs:services {
list L2Vpn {
leaf order-number {
type string;
}
leaf customer-name {
type string;
}
list pe-devices {
key device-name;
leaf device-name {
type leafref {
path "/ncs:devices/ncs:device/ncs:name";
}
}
leaf Bundle-Ether {
type string;
}
leaf stag {
type uint16 {
range 1..4095;
}
}
}
}
}
}
17. Save the updated L2Vpn.yang file. If you edit the file at jump start server, remember to copy
Step 5. Complete l2vpn template to map service model to device model mapping
You have created the service model in the previous step. Next, L2Vpn service needs to send the
proper CLI’s (as in Table 4) to PE devices. In NSO term, this is called service model to device model
mapping.
In most cases, the service to device mapping can be easily implemented through xml template. You
will use this approach for L2Vpn. The skeleton of mapping template xml file, L2Vpn-
template.xml is auto generated. In this step, you will add the contents.
We start with creating a sample Bundle Ether sub-interface (sub-interface 100.100, with vlan id 100)
to a PE through NSO CLI. NSO’s operation “commit dry-run” will have NSO’s cisco-iosxr Ned calculate
the device CLI’s. “commit dry-run outformat xml” displays the output in xml format. This output is
the starting point of the mapping template.
19. At NSO server, configure a Bundle Ether sub-interface 100.100 to the PE device asr9k0 through
nsc cli. (refer Table 4.).
Make sure the green highlighted is entered as one line:
[edit]
admin@ncs% set devices device asr9k0 config cisco-ios-xr:interface
Bundle-Ether-subinterface Bundle-Ether 100.100 mode l2transport
description test-desc encapsulation dot1q vlan-id 100
[ok][2017-04-29 03:07:44]
[edit]
admin@ncs%
20. From ncs cli config mode, issue “commit dry run outformat xml”. This command will show the
configuration changes to be sent to device as xml format.
[edit]
21. We don’t want to commit the above changes to devices. Exit from ncs cli without committing:
admin@ncs% exit no
[ok][2017-06-02 01:47:29]
admin@ncs> exit
[nso@cl-lab-211 src]$
window’s jump server using ( ). Edit the file using editors such as Sublime ( ),
Notepad++( ). If you take Option 2, remember copy the file back to NSO server.
<config-template xmlns="http://tail-f.com/ns/config/1.0">
<devices xmlns="http://tail-f.com/ns/ncs">
<device>
<name>asr9k0</name>
<config>
<interface xmlns="http://tail-f.com/ned/cisco-ios-xr">
<Bundle-Ether-subinterface>
<Bundle-Ether>
<id>100.100</id>
<description>test-desc</description>
<mode>l2transport</mode>
<encapsulation>
<dot1q>
<vlan-id>100</vlan-id>
</dot1q>
</encapsulation>
</Bundle-Ether>
</Bundle-Ether-subinterface>
</interface>
</config>
</device>
</devices>
</config-template>
The final template file L2Vpn-template.xml should look like the following, note the yellow
highlighted parts are replaced with service attributes:
<config-template xmlns="http://tail-f.com/ns/config/1.0">
<devices xmlns="http://tail-f.com/ns/ncs">
<device>
<name>{/pe-devices/device-name}</name>
<config>
<interface xmlns="http://tail-f.com/ned/cisco-ios-xr">
<Bundle-Ether-subinterface>
<Bundle-Ether>
<id>{./Bundle-Ether}.{./stag}</id>
<description>{/customer-name}-{/order-number}</description>
<mode>l2transport</mode>
<encapsulation>
<dot1q>
<vlan-id>{./stag}</vlan-id>
</dot1q>
</encapsulation>
</Bundle-Ether>
</Bundle-Ether-subinterface>
</interface>
</config>
</device>
</devices>
</config-template>
25. Save L2Vpn-template.xlm. If you edit the file from the windows jumpstart server, remember
to copy the file to NSO server, to ~/packages/L2Vpn/templates/
26. At NSO server, check current packages in your NSO installation, make sure cisco-iosxr ned
(highlighted line) appear under ncs-run/packages:
[nso@cl-lab-211]$ ls –l ~/ncs-run/packages
lrwxrwxrwx. 1 nso nso 54 Dec 9 04:46 cisco-iosxr-cli-6.6 ->
/home/nso/ncs-5.0.1/packages/neds/cisco-iosxr-cli-6.6/
27. Make package L2Vpn available for NSO. Creating a symbolic link to L2Vpn at the packages
directory of your NSO runtime (/home/nso/ncs-run/packages):
[nso@cl-lab-211]$ cd ~/ncs-run/packages
[nso@cl-lab-211 packages]$ ln -s /home/nso/packages/L2Vpn/
[nso@cl-lab-211 packages]$ ls -l
total 0
lrwxrwxrwx. 1 nso nso 54 Dec 9 04:46 cisco-iosxr-cli-6.6 ->
/home/nso/ncs-5.0.1/packages/neds/cisco-iosxr-cli-6.6/
lrwxrwxrwx. 1 nso nso 25 Dec 9 08:19 L2Vpn ->
/home/nso/packages/L2Vpn/
Note: Make sure you are creating the symbolic link at ~/ncs-run/packages
directory.
28. From NSO cli (ncs_cli), reload packages to complete the package deployment process.
Make sure the reload result is true. If you see errors, check the solution from
~/packages/solution directory for reference.
[ok][2018-12-09 08:23:00]
29. Create an L2Vpn service instance, name it “test”, set customer name as ciscolive, and
order-number 123. In addition, set pe-devices as asr9k0, Bundle-Ether 100, and stag
100 :
[edit]
admin@ncs% set services L2Vpn test customer-name ciscolive order-
number 123 pe-devices asr9k0 Bundle-Ether 100 stag 100
[ok][2017-04-29 08:21:00]
[edit]
30. Operation “Commit dry run” shows the CLI’s to be configured to asr9k0:
31. Commit the service instance test. After commit, the service instance test is persistent in
NSO’s in memory database cdb, and the highlighted cli’s from above are committed to
asr9k0.
admin@ncs% commit
Commit complete.
[ok][2017-04-29 08:21:18]
[edit]
admin@ncs% show services L2Vpn test
order-number 123;
customer-name ciscolive;
pe-devices asr9k0 {
Bundle-Ether 100;
stag 100;
}
[ok][2017-04-29 08:21:33]
[edit]
admin@ncs%
32. Check device configuration to see the intended CLI’s are configured at asr9k0. Open another
putty terminal, logged in as user nso/cisco123 (check Table 2 Lab access information). From NSO
application server, connect to the netsim device asr9k0 to confirm Bundle-Ether sub-interface,
100.100 is created with the correct customer name, order number and vlan tag:
[nso@cl-lab-211]$ cd ~/ncs-run
[nso@cl-lab-211 ncs-run]$ ncs-netsim cli-c asr9k0
33. Delete service instance “test” from NSO CLI (config mode).
Note: you can get back to nso cli config mode by “ncs_cli –u admin” followed by
“config” from your NSO’s VM, linux prompt.
[edit]
admin@ncs% commit
Commit complete.
[ok][2017-04-29 08:42:31]
[edit]
admin@ncs%
34. Check device configuration to confirm that Bundle-Ether sub-interface 100.100 created through
service instance test is removed. (from the putty terminal, you opened at item 32):
You have completed Task1. In this task, you created, deployed and tested L2Vpn service package.
Next, you will learn service discovery and reconcile when dealing with brownfield network.
One of the typical brownfield service orchestration requirements is to have NSO discover and
reconcile the pre-existing services in the network. The pre-existing service configurations can be
brought into NSO’s device model through NSO CLI operation “sync-from”. By default, NSO assumes
that devices own the pre-existing configuration. This is to ensure that the out-of-band configurations
are not accidentally overwritten by NSO’s service operations.
However, in many cases, we need to have NSO fully manage the lifecycle of the pre-existing services.
This is called NSO service discovery and reconciliation.
NSO service discovery and reconciliation for brownfield starts with creating service instances (the
service instances that match the out-of-band service configurations. After the service instances are
created, we need to transfer the ownership of the configuration to NSO.
In this lab, the PE devices (asr9k0, asr9k1 and asr9k2) all have pre-existing L2VPN services that are
configured out-of-band. Table 6 lists part of them. They are synced to NSO’s device model via
NSO’s “sync-from” operation.
In this task, you will create L2Vpn service instances to match the pre-existing configurations. You will
also observe service lifecycle management issues without transferring the ownership of the pre-
existing configuration.
35. Perform a sync-from to bring the pre-existing configurations to NSO’s device model
[edit]
Recall what we have done at Task 1: Create L2VPN Service Package, this is reverse mapping of device
model to service model. Similar to Table 5, let’s build device attribute to service attribute mapping
example table, Table 7
37. Create two service instances, name them as test1 and test2 to match two pre-existing
configurations (refer Table 7):
Note: Since you are creating L2Vpn service instances to match the pre-existing
configurations, make sure the service attributes (highlighted) match exactly to what
appear in device configuration.
[edit]
admin@ncs% set services L2Vpn test1 order-number L1111318
customer-name L_ford_318 pe-devices asr9k0 Bundle-Ether 100 stag
2188
[ok][2017-04-29 09:36:33]
[edit]
admin@ncs% set services L2Vpn test2 order-number L1111318
customer-name L_unitedhealth_318 pe-devices asr9k0 Bundle-Ether
100 stag 2234
[ok][2017-04-29 09:39:25]
[edit]
39. After confirm the output of “commit dry-run outformat native” does not contain
any CLI, continue commit the service instances, and then exit from ncs cli. We will commit with
option “no-networking”, this option makes sure the instances are committed to cdb without
changing the configuration of network devices.
Make sure you are still in ncs cli’s config mode. With option “no-networking”, NSO is
committing the changes only to cdb.
[edit]
admin@ncs% exit
[ok][2017-06-02 07:58:37]
admin@ncs> exit
[nso@cl-lab-211 packages]$
[edit]
[edit]
admin@ncs% delete services L2Vpn test1
[ok][2017-04-29 10:04:40]
[edit]
admin@ncs% commit dry-run outformat native
native {
}
[ok][2017-04-29 10:04:47]
[edit]
admin@ncs% commit
Commit complete.
[ok][2017-04-29 10:04:56]
[edit]
41. After commit the delete operation, confirm service instance test1 is no longer in cdb of NSO.
[edit]
admin@ncs%
42. Although the service instance test1is deleted from NSO, the associated Bundle Ether sub-
interface 100.2188 remains in asr9k0. The out-of-band configuration can’t be modified
through NSO!
You have completed Task 2. You created two L2Vpn service instances to match the pre-existing
configurations. You also observed that deleting or modifying the service instances does not change
the out-of-band device configuration. This implies that NSO is not managing the lifecycle of service
instances of pre-existing configuration.
In next Task, you will learn to complete service reconciliation by resetting the reference count of
pre-existing services.
NSO uses an annotation tag of reference count to keep track of the configuration ownership. In this
task, you will learn how to transfer the ownership of pre-existing configuration from device’s out-of-
band to NSO by ref-count reset operation. Once the ref-count is reset, NSO can manage the lifecycle
of the pre-existing L2VPN services. You will test by deleting the service instances and see the
associated Bundle-Ether-sub interfaces are removed from the devices.
In this task, you will work on instance test2 to complete the service discovery/reconcile through
resetting the reference count (ref-count).
43. Check ref-count of the Bundle Ether sub-interfaces. As you can see, Bundle-Ether 100.2234 has
backpointers point to the service instance test2 (which we created at Step 9). The value of ref-
count is 2. This indicates that NSO service instance test2 is not the sole owner of the
configuration.
44. Reset ref-count of Bundel-Ether 100.2234 through the operation “service L2Vpn re-
deploy reconcile”. This reset the value of ref-count, service instance test2 will then be
the sole owner of the configurations.
[edit]
[edit]
admin@ncs% delete services L2Vpn test2
[ok][2017-04-29 11:34:32]
[edit]
admin@ncs% commit dry-run outformat native
native {
device {
name asr9k0
data no interface Bundle-Ether 100.2234 l2transport
}
}
[ok][2017-04-29 11:34:39]
[edit]
admin@ncs% commit
Commit complete.
[ok][2017-04-29 11:34:47]
[edit]
49. Now check device model to see Bundle-Ether 100.2234 no longer exists in asr9k0.
[edit]
From Task 1, you learned how to generate NSO service packages. You created a service package
L2Vpn with service Yang model, and template xml to generate device configlet.
From Task 2 and Task 3, you learnt how to perform service discovery with brownfield network. You
created L2Vpn instances from pre-existing device configurations, observed the issues, reset the
reference count to fully manage the lifecycle of L2Vpn service instances.
The next task is to extend the service discovery process from manual to automatic. It is
recommended to go through the task and learn how to create massive service instances from pre-
existing configurations, and reset ref-count automatically.
There are several ways to auto-discover services. One of them is creating service instances from
device model using NSO’s maapi and magic API’s, followed by resetting the ref-count for the service
instances programmatically.
In this task, you will learn how to create an NSO action to discover pre-existing L2VPN services
through an NSO action.
Note: This task requires python programming, and knowledge of NSO maagic and
maapi API’s.
In NSO, action callbacks are used to implement arbitrary operations in java or python. These
operations can be basically anything, e.g. downloading a file, performing some test, resetting alarms,
etc. We will create an action package, l2vpnreconcile, to perform L2Vpn service discovery. Although
it can be easily extended, for simplicity, this lab designs the action to perform service discovery from
one PE device.
Similar to what we did at Step 3, you will create the package skeleton first.
[nso@cl-lab-211]$ cd ~/packages
[nso@cl-lab-211 packages]$ ncs-make-package --service-skeleton
python --action-example l2vpnreconcile
[nso@cl-lab-211 packages]$ cd l2vpnreconcile
[nso@cl-lab-211 l2vpnreconcile]$ ls
package-meta-data.xml python README src templates test
server to window’s jump server using ( ). Edit the file using editors such as Sublime (
), Notepad++( ). If you take Option 2, remember copy the file back to NSO server.
module l2vpnreconcile {
namespace "http://example.com/l2vpnreconcile";
prefix l2vpnreconcile;
import ietf-inet-types { prefix inet; }
import tailf-common { prefix tailf; }
import tailf-ncs { prefix ncs; }
description
"L2Vpn Reconcile Action";
container action {
tailf:action reconcile-l2vpn {
tailf:actionpoint reconcile;
input {
leaf device-name {
type leafref {
path "/ncs:devices/ncs:device/ncs:name" ;
}
}
}
output {
leaf message {
type string;
}
leaf success {
type boolean;
}
}
}
}
}
Note: Check
~/solution/l2vpnreconcile/src/yang/l2vpnreconcile.yang for
reference.
54. Save l2vpnreconcile.yang. If you edit the file from the windows jump start server, make
sure you copy the file back to NSO server, to
/home/nso/packages/l2vpnreconcile/src/yang/
server to window’s jump server using ( ). Edit the file using editors such as Sublime (
), Notepad++( ). If you take Option 2, remember copy the file back to NSO server.
56. Delete the highlighted “Service Call Back Example” class (make sure the whole class
ServiceCallbacks is deleted)
# ------------------------
# SERVICE CALLBACK EXAMPLE
# ------------------------
class ServiceCallbacks(Service):
# @Service.post_modification
# def cb_post_modification(self, tctx, op, kp, root, proplist):
# self.log.info('Service premod(service=', kp, ')')
57. Remove service registration from Main class, delete the highlighted line:
class Main(ncs.application.Application):
def setup(self):
# The application class sets up logging for us. It is accessible
# through 'self.log' and is a ncs.log.Log instance.
self.log.info('Main RUNNING')
58. Rename the auto generated action class name from DoubleAction(Action) to
Reconcile(Action). Remove the contents of cb_action (We will replace the contents at
later steps):
class Reconcile(Action):
@Action.action
def cb_action(self, uinfo, name, kp, input, output):
59. in Main function, change the action registration accordingly, i.e, replace DoubleAction with
Reconcile.
Step 17. Implement the action call back function to reconcile pre-exisiting L2VPN service.
In this step, you will add python code to action call back function cb_action. Inside
cb_action, you will create L2Vpn service instances from device model, and reset reference count
of the service instances.
Creating service instances from device model is a reverse process as compare to creating a service
package. You now need to map device NED attributes to service attributes. (Refer Table 7 NSO Ned
(cisco-iosxr) to L2Vpn attribute mapping example).
After a sync-from operation, the pre-existing configurations are brought into NSO’s device model. To
create L2Vpn service instances, we need to open a write transaction of cdb, walk through device
model, populate service instance attributes and commit the service instances to cdb.
The logic flow is illustrated as pseudo code in the following table. We will take several steps to go
through the implementation.
import ncs
from ncs.application import Service
from ncs.dp import Action
import random
import _ncs
61. We will create L2Vpn service instances in cdb. Inside cb_action, open write transaction after
initialize local variables pe_device and srs:
@Action.action
def cb_action(self, uinfo, name, kp, input, output):
pe_device = ''
srs = []
with ncs.maapi.Maapi() as m:
with ncs.maapi.Session(m, uinfo.username, uinfo.context):
with m.start_write_trans() as t:
We add check (the if len(bundleEths) == 0: block) to cover the case when the device
has no Bundle Ether sub-interfaces, in which, there is no need to create any service instances,
the block will return with message of reconciliation finished.
@Action.action
def cb_action(self, uinfo, name, kp, input, output):
pe_device = ''
srs = []
with ncs.maapi.Maapi() as m:
with ncs.maapi.Session(m, uinfo.username, uinfo.context):
with m.start_write_trans() as t:
try:
root = ncs.maagic.get_root(t)
pe_device = self.getDevice(input.device_name, root);
int_path = '/ncs:devices/ncs:device{%s}/config/cisco-ios-
xr:interface/Bundle-Ether-subinterface/Bundle-Ether' %input["device-
name"]
if t.exists(int_path):
bundleEths = ncs.maagic.get_node(t,int_path)
if len(bundleEths) == 0:
output.success = True
output.message = "finish reconcile"
return
63. For each Bundle Ether sub-interface in device config, create one L2Vpn service instance. Similar
to manual service instance creation as in Task 2: Step 9, item 37, we use device attributes to
populate service instance attributes. Use interface description plus pe device name as sr-name
for L2Vpn service instance, and set attributes order-number and customer-name. (Refer Table 9)
Table 9 NSO Device (cisco-iosxr) to L2Vpn attribute mapping example for auto service instance creation
Note: Make sure the green highlighted line is entered as one line. (no line breaks).
A couple of checks added to cover cases when the Bundle Ether sub-interface does not have stag
(vlan_id) populated, or when the description is not populated properly.
order_number = ''
customer = ''
if description is None:
order_number = self.getRs()
customer = 'ciscolive'
sr_name = 'reconcile-'+ customer + '-'+order_number
else:
sr_name = description + '-' + input.device_name
customer,order_number = description.split('-')
sr_path = 'ncs:services/L2Vpn:L2Vpn{%s}' %(sr_name)
if t.exists(sr_path):
self.log.info('sr ' + sr_name + 'exists, skipping')
continue
sr_node = ncs.maagic.get_node(t,
"/ncs:services/L2Vpn:L2Vpn")
obj = sr_node.create(sr_name)
obj.sr_name = sr_name
obj.order_number = order_number
obj.customer_name = customer
stag = bundleEther.encapsulation.dot1q.vlan_id
pe_path = sr_path + '/pe-devices'
pes_node = ncs.maagic.get_node(t,pe_path)
pe_obj = pes_node.create(input.device_name)
pe_obj.stag = bstag
pe_obj.Bundle_Ether = id
srs.append(sr_name)
65. After all the Bundle-Ether-subinterfaces are processed, we perform dry-run action to make sure
the output is empty (outside the for loop). Commit the service instances only if the dry run result
is empty. Function isDryRunEmpty is defined later.
if len(srs) > 0:
if not self.isDryRunEmpty(root):
output.success = False
output.message = 'commit dry-run output not empty, stop
reconcilation'
return
t.apply(flags=_ncs.maapi.COMMIT_NCS_NO_NETWORKING)
66. Now we are ready to reset the reference count as we have done at Task 3: (Service discovery
and reconciliation B: Reset ) at Step 12 via ncs cli.
Add the following to reset reference count, and close cb_action. Function redeploySrs
is defined later.
pe_device.sync_from()
self.redeploySrs(root,srs)
time.sleep(100)
output.success = True
output.message = "Successfully created the services."
except Exception as e:
self.log.error(str(e))
output.success = False
output.message = str(e)
finally:
self.log.info('Context: %s' % uinfo.context )
67. Define function getDevice in Reconcile class. This is to return the device object from cdb,
with name from the input parameter (device-name)
class Reconcile(Action):
68. Define function isDryRunEmpty in Reconcile class, this is to make sure the service
instances we created match to the pre-existing configuration.
class Reconcile(Action):
…………
def isDryRunEmpty(self,root):
input = root.services.commit_dry_run.get_input()
input.outformat = "native"
result = root.services.commit_dry_run(input)
for dvc in result.native.device:
if dvc.data is not None:
return False
return True
69. Define redeploySrs in Reconcile class. It performs the same operation via maapi as we
have done at Task 3: (Service discovery and reconciliation B: Reset ) at Step 12, perform service
redeploy with option of reconcile for each L2Vpn service instance:
class Reconcile(Action):
…………
def redeploySrs(self,root, srs):
self.log.info('Executing redeplySrs(...)')
if srs is None or len(srs) == 0:
return
for sr in srs:
action = root.services.L2Vpn[sr].re_deploy
input = action.get_input()
reconcile = input.reconcile.create()
output = action(reconcile)
import ncs
from ncs.application import Service
from ncs.dp import Action
import random
import _ncs
class Reconcile(Action):
def getRs(self):
return str(random.randint(1, 1500))
def isDryRunEmpty(self,root):
input = root.services.commit_dry_run.get_input()
input.outformat = "native"
result = root.services.commit_dry_run(input)
for dvc in result.native.device:
if dvc.data is not None:
return False
return True
@Action.action
def cb_action(self, uinfo, name, kp, input, output):
pe_device = ''
srs = []
self.log.info('start reconcile')
root = ncs.maagic.get_root(t)
pe_device = self.getDevice(input.device_name, root);
if pe_device is None:
output.success = False
output.message = 'device ' + input.device_name + 'not in system'
return
message = pe_device.sync_from()
int_path = '/ncs:devices/ncs:device{%s}/config/cisco-ios-
xr:interface/Bundle-Ether-subinterface/Bundle-Ether' %input["device-name"]
if t.exists(int_path):
bundleEths = ncs.maagic.get_node(t,int_path)
if len(bundleEths) == 0:
output.success = True
output.message = "finish reconcile"
return
for bundleEther in bundleEths:
id , bstag = bundleEther.id.split('.')
description = bundleEther.description
stags = bundleEther.encapsulation.dot1q.vlan_id
if stags is None or len(stags)==0:
continue
stag = 0
for stag in stags:
if int(stag) == int(bstag):
break
if stag == 0:
self.log.warning('vlan tag not configured, or does not match
sub-interface id for Bundle-Ether-subinterface %s, use sub-interface
id'%bundleEther.id)
order_number = ''
customer = ''
if description is None:
order_number = self.getRs()
customer = 'ciscolive'
sr_name = 'reconcile-'+ customer + '-'+order_number
else:
sr_name = description + '-' + input.device_name
customer,order_number = description.split('-')
sr_path = 'ncs:services/L2Vpn:L2Vpn{%s}' %(sr_name)
if t.exists(sr_path):
self.log.info('sr ' + sr_name + 'exists, skipping')
continue
sr_node = ncs.maagic.get_node(t, "/ncs:services/L2Vpn:L2Vpn")
obj = sr_node.create(sr_name)
obj.order_number = order_number
obj.customer_name = customer
pe_path = sr_path + '/pe-devices'
pes_node = ncs.maagic.get_node(t,pe_path)
pe_obj = pes_node.create(input.device_name)
pe_obj.stag = bstag
pe_obj.Bundle_Ether = id
srs.append(sr_name)
t.apply(flags=_ncs.maapi.COMMIT_NCS_NO_NETWORKING)
message = pe_device.sync_from()
self.redeploySrs(root,srs)
output.success = True
output.message = "Successfully created the services."
except Exception as e:
self.log.error(str(e))
output.success = False
output.message = str(e)
finally:
self.log.info('Context: %s' % uinfo.context)
class Main(ncs.application.Application):
def setup(self):
self.log.info('Main RUNNING')
self.register_action('reconcile', Reconcile)
def teardown(self):
self.log.info('Main FINISHED')
71. Save main.py. If you edit the file from windows jump start server, make sure you copy the file
back to NSO server, at location /home/nso/packages/l2vpnreconcile/python/l2vpnreconcile/
[nso@cl-lab-211 packages]$ ln –s
/home/nso/packages/l2vpnreconcile/
total 0
lrwxrwxrwx. 1 nso nso 54 Dec 9 04:46 cisco-iosxr-cli-6.6 ->
/home/nso/ncs-5.0.1/packages/neds/cisco-iosxr-cli-6.6/
lrwxrwxrwx. 1 nso nso 25 Dec 9 08:19 L2Vpn ->
/home/nso/packages/L2Vpn/
lrwxrwxrwx. 1 nso nso 34 Dec 9 09:14 l2vpnreconcile ->
/home/nso/packages/l2vpnreconcile/
[nso@cl-lab-211 packages]$
Step 20. Test the action script to discover all pre-existing L2VPN services
In this step, you will run the reconcile-l2vpn action to discover the pre-existing L2VPN services in
devices.
75. Check the discovered L2Vpn services. note, in service instance creation code, we set description
as the service instance name:
[edit]
76. Try to delete one of them to confirm that NSO is managing the lifecycle of reconciled services
correctly.
[edit]
admin@ncs% delete services L2Vpn L_3m_318-L1111318-asr9k0
[ok][2017-06-05 06:17:50]
[edit]
admin@ncs% commit dry-run outformat native
native {
device {
name asr9k0
data no interface Bundle-Ether 100.276 l2transport
}
}
[ok][2017-06-05 06:17:57]
[edit]
77. Commit the above delete operation. After that, we can see the device configuration of Bundle-
Ether 100.276 is deleted:
admin@ncs% commit
Commit complete.
[ok][2017-04-30 13:12:49]
[edit]
admin@ncs% show devices device asr9k0 config cisco-ios-
xr:interface Bundle-Ether-subinterface Bundle-Ether 100.276
------------------------------------------------------------------
-----------------------------------------^
syntax error: element does not exist
[error][2017-04-30 13:13:22]
[edit]