- About
- NSO 5.7 Getting Started Guide
- NSO 5.7 User Guide
- NSO Installation Guide
- NSO 5.7 Administration Guide
- NSO 5.7 Northbound APIs
- NSO 5.7 Development Guide
- Preface
- The Configuration Database and YANG
- Basic Automation with Python
- Creating a Service
- Applications in NSO
- The NSO Java VM
- The NSO Python VM
- Embedded Erlang applications
- The YANG Data Modeling Language
- Using CDB
- Java API Overview
- Python API Overview
- NSO Packages
- Package Development
- Developing NSO Services
- Templates
- NED Upgrades and Migration
- Developing Alarm Applications
- SNMP Notification Receiver
- The web server
- Kicker
- Scheduler
- Progress Trace
- Nano Services for Staged Provisioning
- Encryption Keys
- External Logging
- NSO 5.7 Web UI
- NSO CDM Migration Guide
- NSO Layered Service Architecture
- NSO 5.7 NED Development
- NSO 5.7 Manual Pages
- SDK API Reference
- NSO on DevNet
- Get Support
Up until this point, this user guide has described how to use NSO to configure devices. NSO can also manage the life-cycle for services like VPNs, BGP peers, ACLs. It is important to understand what is meant by service in this context.
-
NSO abstracts the device specific details. The user only needs to enter attributes relevant to the service.
-
The service instance has configuration data itself that can be represented and manipulated.
-
A service instance configuration change is applied to all affected devices.
These are the features NSO uses to support service configuration.
-
Service Modeling: network engineers can model the service attributes and the mapping to device configurations. For example, this means that a network engineer can specify at data-model for VPNs with router interfaces, VLAN id, VRF and route distinguisher.
-
Service life-cycle: while less sophisticated configuration management systems can only create an initial service instance in the network they do not support changing or deleting a service instance. With NSO you can at any point in time modify service elements like the VLAN id of a VPN and NSO can generate the corresponding changes to the network devices.
-
The NSO service instance has configuration data that can be represented and manipulated. The service model run-time updates all NSO northbound interfaces so a network engineer can view and manipulate the service instance over CLI, WebUI, REST etc.
-
NSO maintains references between service instances and device configuration. This means that a VPN instance knows exactly which device configurations it created/modified. Every configuration stored in the CDB is mapped to the service instance that created it.
An example is the best method to illustrate how services are created and used in NSO. As described in the sections about devices and NEDs it was said that NEDs come in packages. The same is true for services, either if you do design the services yourself or use ready-made service applications it ends up in a package that is loaded into NSO.
The example
examples.ncs/service-provider/mpls-vpn
will
be used to explain NSO Service Management features. This example
illustrates Layer3 VPNs in a service provider MPLS network.
The example network consists of Cisco ASR 9k and Juniper core
routers (P and PE) and Cisco IOS based CE routers.
The Layer3 VPN service configures the CE/PE routers for all
endpoints in the VPN with BGP as the CE/PE routing
protocol. Layer2 connectivity between CE and PE routers are
expected to be done through a Layer2 ethernet access network,
which is out of scope for this example.
The Layer3 VPN service includes VPN connectivity as well as
bandwidth and QOS parameters.
The service configuration only has references to CE devices for the end-points in the VPN. The service mapping logic reads from a simple topology model that is configuration data in NSO, outside the actual service model, and derives what other network devices to configure. The topology information has two parts. The first part lists connections in the network and is used by the service mapping logic to find out which PE router to configure for an endpoint. The snippets below show the configuration output in the Cisco style NSO CLI.
topology connection c0 endpoint-1 device ce0 interface GigabitEthernet0/8 ip-address 192.168.1.1/30 endpoint-2 device pe0 interface GigabitEthernet0/0/0/3 ip-address 192.168.1.2/30 link-vlan 88 ! topology connection c1 endpoint-1 device ce1 interface GigabitEthernet0/1 ip-address 192.168.1.5/30 endpoint-2 device pe1 interface GigabitEthernet0/0/0/3 ip-address 192.168.1.6/30 link-vlan 77 !
The second part lists devices for each role in the network and is in this example only used to dynamically render a network map in the Web UI.
topology role ce device [ ce0 ce1 ce2 ce3 ce4 ce5 ] ! topology role pe device [ pe0 pe1 pe2 pe3 ] !
QOS configuration in service provider networks is complex, and often require a lot of different variations. It is also often desirable to be able to deliver different levels of QOS. This example shows how a QOS policy configuration can be stored in NSO and be referenced from VPN service instances. Three different levels of QOS policies are defined; GOLD, SILVER and BRONZE with different queuing parameters.
qos qos-policy GOLD class BUSINESS-CRITICAL bandwidth-percentage 20 ! class MISSION-CRITICAL bandwidth-percentage 20 ! class REALTIME bandwidth-percentage 20 priority ! ! qos qos-policy SILVER class BUSINESS-CRITICAL bandwidth-percentage 25 ! class MISSION-CRITICAL bandwidth-percentage 25 ! class REALTIME bandwidth-percentage 10 !
Three different traffic classes are also defined with a DSCP value that will be used inside the MPLS core network as well as default rules that will match traffic to a class.
qos qos-class BUSINESS-CRITICAL dscp-value af21 match-traffic ssh source-ip any destination-ip any port-start 22 port-end 22 protocol tcp ! ! qos qos-class MISSION-CRITICAL dscp-value af31 match-traffic call-signaling source-ip any destination-ip any port-start 5060 port-end 5061 protocol tcp ! !
Make sure you start clean, i.e. no old configuration data is present. If you have been running this or some other example before, make sure to stop any NSO or simulated network nodes (ncs-netsim) that you may have running. Output like 'connection refused (stop)' means no previous NSO was running and 'DEVICE ce0 connection refused (stop)...' no simulated network was running, which is good.
Copy$
This will setup the environment and start the simulated network.
Before creating a new L3VPN service we must sync the configuration from all network devices and then enter config mode. (A hint for this complete section is to have the README file from the example and cut and paste the CLI commands).
Copyncs#
Add another VPN (prompts ommitted):
top ! vpn l3vpn ford as-number 65200 endpoint main-office ce-device ce2 ce-interface GigabitEthernet0/5 ip-network 192.168.1.0/24 bandwidth 10000000 ! endpoint branch-office1 ce-device ce3 ce-interface GigabitEthernet0/5 ip-network 192.168.2.0/24 bandwidth 5500000 ! endpoint branch-office2 ce-device ce5 ce-interface GigabitEthernet0/5 ip-network 192.168.7.0/24 bandwidth 1500000 ! commit
The above sequence showed how NSO can be used to manipulate service abstractions on top of devices. Services can be defined for various purpose such as VPNs, Access Control Lists, firewall rules etc. Support for services is added to NSO via a corresponding service package.
A service package in NSO comprises two parts:
-
Service model: the attributes of the service, input parameters given when creating the service. In this example name, as-number, and end-points.
-
Mapping: what is the corresponding configuration of the devices when the service is applied. The result of the mapping can be inspected by the commit dry-run outformat native command.
We later in this guide show how to define this, for now assume that the job is done.
When NSO applies services to the network, NSO stores the
service configuration along with resulting device
configuration changes. This is used as a base for the Tail-f
FASTMAP algorithm which automatically can derive device
configuration changes from a service change. So going back
to the example L3 VPN above any part of volvo
VPN instance can be modified. A simple change like changing
the as-number
on the service results in many
changes in the network. NSO does this automatically.
ncs(config)#vpn l3vpn volvo as-number 65102
ncs(config-l3vpn-volvo)#commit dry-run outformat native
native { device { name ce0 data no router bgp 65101 router bgp 65102 neighbor 192.168.1.2 remote-as 100 neighbor 192.168.1.2 activate network 10.10.1.0 ! ... ncs(config-l3vpn-volvo)#commit
Let us look at a more challenging modification. A common use-case is of course to add a new CE device and add that as an end-point to an existing VPN. Below follows the sequence to add two new CE devices and add them to the VPN's. (In the CLI snippets below we omit the prompt to enhance readability). First we add them to the topology.
top ! topology connection c7 endpoint-1 device ce7 interface GigabitEthernet0/1 ip-address 192.168.1.25/30 endpoint-2 device pe3 interface GigabitEthernet0/0/0/2 ip-address 192.168.1.26/30 link-vlan 103 ! topology connection c8 endpoint-1 device ce8 interface GigabitEthernet0/1 ip-address 192.168.1.29/30 endpoint-2 device pe3 interface GigabitEthernet0/0/0/2 ip-address 192.168.1.30/30 link-vlan 104 ! ncs(config)#commit
Note well that the above just updates NSO local information on topological links. It has no effect on the network. The mapping for the L3 VPN services does a look-up in the topology connections to find the corresponding pe router.
Then we add them to the VPN's
top ! vpn l3vpn ford endpoint new-branch-office ce-device ce7 ce-interface GigabitEthernet0/5 ip-network 192.168.9.0/24 bandwidth 4500000 ! vpn l3vpn volvo endpoint new-branch-office ce-device ce8 ce-interface GigabitEthernet0/5 ip-network 10.8.9.0/24 bandwidth 4500000 !
Before we send anything to the network, lets see look at the device configuration using dry-run. As you can see, both new CE devices are connected to the same PE router, but for different VPN customers.
ncs(config)#commit dry-run outformat native
And commit the configuration to the network
(config)#commit
Next we will show how NSO can be used to check if the service configuration in the network is up to date. In a new terminal window we connect directly to the device ce0 that is a Cisco device emulated by the tool ncs-netsim.
$ncs-netsim cli-c ce0
We will now reconfigure an edge interface that we previously configured using NSO.
ce0>enable
ce0#configure
Enter configuration commands, one per line. End with CNTL/Z. ce0(config)#no policy-map volvo
ce0(config)#exit
ce0# exit
Going back to the terminal with NSO, check the status of the network configuration:
ncs#devices check-sync
sync-result { device ce0 result out-of-sync info got: c5c75ee593246f41eaa9c496ce1051ea expected: c5288cc0b45662b4af88288d29be8667 ... ncs#vpn l3vpn * check-sync
vpn l3vpn ford check-sync in-sync true vpn l3vpn volvo check-sync in-sync true ncs#vpn l3vpn * deep-check-sync
vpn l3vpn ford deep-check-sync in-sync true vpn l3vpn volvo deep-check-sync in-sync false }
The CLI sequence above performs 3 different comparisons:
-
Real device configuration versus device configuration copy in NSO CDB
-
Expected device configuration from service perspective and device configuration copy in CDB.
-
Expected device configuration from service perspective and real device configuration.
Notice that the service 'volvo' is out of sync from the service configuration. Use the check-sync outformat cli to see what the problem is:
ncs# vpn l3vpn volvo deep-check-sync outformat cli
cli devices {
devices {
device ce0 {
config {
+ ios:policy-map volvo {
+ class class-default {
+ shape {
+ average {
+ bit-rate 12000000;
+ }
+ }
+ }
+ }
}
}
}
}
Assume that a network engineer considers the real device configuration to be authoritative:
ncs# devices device ce0 sync-from
result true
And then restore the service:
ncs# vpn l3vpn volvo re-deploy dry-run { outformat native }
native {
device {
name ce0
data policy-map volvo
class class-default
shape average 12000000
!
!
}
}
ncs# vpn l3vpn volvo re-deploy
In the same way as NSO can calculate any service configuration change it can also automatically delete the device configurations that resulted from creating services:
ncs(config)#no vpn l3vpn ford
ncs(config)#commit dry-run
cli devices { device ce7 { config { - ios:policy-map ford { - class class-default { - shape { - average { - bit-rate 4500000; - } - } - } - } ...
It is important to understand the two diffs shown above. The first
diff as an output to show configuration
shows the
diff at service level. The second diff shows the output generated
by NSO to clean up the device configurations.
Finally, we commit the changes to delete the service.
(config)# commit
Service instances live in the NSO data-store as well as a copy of the device configurations. NSO will maintain relationships between these two.
Show the configuration for a service
ncs(config)# show full-configuration vpn l3vpn
vpn l3vpn volvo
as-number 65102
endpoint branch-office1
ce-device ce1
ce-interface GigabitEthernet0/11
ip-network 10.7.7.0/24
bandwidth 6000000
!
...
You can ask NSO to list all devices that are touched by a service and vice versa:
ncs#show vpn l3vpn device-list
NAME DEVICE LIST ---------------------------------------- volvo [ ce0 ce1 ce4 ce8 pe0 pe2 pe3 ] ncs#show devices device service-list
NAME SERVICE LIST ------------------------------------- ce0 [ "/l3vpn:vpn/l3vpn{volvo}" ] ce1 [ "/l3vpn:vpn/l3vpn{volvo}" ] ce2 [ ] ce3 [ ] ce4 [ "/l3vpn:vpn/l3vpn{volvo}" ] ce5 [ ] ce6 [ ] ce7 [ ] ce8 [ "/l3vpn:vpn/l3vpn{volvo}" ] p0 [ ] p1 [ ] p2 [ ] p3 [ ] pe0 [ "/l3vpn:vpn/l3vpn{volvo}" ] pe1 [ ] pe2 [ "/l3vpn:vpn/l3vpn{volvo}" ] pe3 [ "/l3vpn:vpn/l3vpn{volvo}" ]
Note that operational mode in the CLI was used above. Every service instance has an operational attribute that is maintained by the transaction manager and shows which device configuration it created. Furthermore every device configuration has backwards pointers to the corresponding service instances:
ncs(config)#show full-configuration devices device ce3 \ config | display service-meta-data
devices device ce3 config ... /* Refcount: 1 */ /* Backpointer: [ /l3vpn:vpn/l3vpn:l3vpn[l3vpn:name='ford'] ] */ ios:interface GigabitEthernet0/2.100 /* Refcount: 1 */ description Link to PE / pe1 - GigabitEthernet0/0/0/5 /* Refcount: 1 */ encapsulation dot1Q 100 /* Refcount: 1 */ ip address 192.168.1.13 255.255.255.252 /* Refcount: 1 */ service-policy output ford exit ncs(config)#show full-configuration devices device ce3 config \ | display curly-braces | display service-meta-data
... ios:interface { GigabitEthernet 0/1; GigabitEthernet 0/10; GigabitEthernet 0/11; GigabitEthernet 0/12; GigabitEthernet 0/13; GigabitEthernet 0/14; GigabitEthernet 0/15; GigabitEthernet 0/16; GigabitEthernet 0/17; GigabitEthernet 0/18; GigabitEthernet 0/19; GigabitEthernet 0/2; /* Refcount: 1 */ /* Backpointer: [ /l3vpn:vpn/l3vpn:l3vpn[l3vpn:name='ford'] ] */ GigabitEthernet 0/2.100 { /* Refcount: 1 */ description "Link to PE / pe1 - GigabitEthernet0/0/0/5"; encapsulation { dot1Q { /* Refcount: 1 */ vlan-id 100; } } ip { address { primary { /* Refcount: 1 */ address 192.168.1.13; /* Refcount: 1 */ mask 255.255.255.252; } } } service-policy { /* Refcount: 1 */ output ford; } } ncs(config)#show full-configuration devices device ce3 config \ | display service-meta-data | context-match Backpointer
devices device ce3 /* Refcount: 1 */ /* Backpointer: [ /l3vpn:vpn/l3vpn:l3vpn[l3vpn:name='ford'] ] */ ios:interface GigabitEthernet0/2.100 devices device ce3 /* Refcount: 2 */ /* Backpointer: [ /l3vpn:vpn/l3vpn:l3vpn[l3vpn:name='ford'] ] */ ios:interface GigabitEthernet0/5
The reference counter above makes sure that NSO will not delete shared resources until the last service instance is deleted. The context-match search is helpful, it displays the path to all matching configuration items.
In order to have NSO deploy services across devices, two pieces are needed:
-
A service model in YANG: the service model shall define the black-box view of a service; which are the input parameters given when creating the service? This YANG model will render an update of all NSO northbound interfaces, for example the CLI.
-
Mapping, given the service input parameters, what is the resulting device configuration? This mapping can be defined in templates, code or a combination of both.
The first step is to generate a skeleton package for a service.
(For details on packages see the section called “Packages”). In order to reuse an
existing environment for NSO and netsim we will reuse the
examples.ncs/getting-started/using-ncs/1-simulated-cisco-ios/
example. Make sure you have stopped any running NSO and
netsim. Navigate to the simulated ios directory and create a new package
for the VLAN service model:
$cd examples.ncs/getting-started/using-ncs/1-simulated-cisco-ios/packages
The next step is to create the template skeleton by using the
ncs-make-package
utility:
$ ncs-make-package --service-skeleton template --augment /ncs:services vlan
This results in a directory structure:
vlan load-dir package-meta-data.xml src templates
For now lets focus on the src/yang/vlan.yang
file.
module vlan { namespace "http://com/example/vlan"; prefix vlan; import ietf-inet-types { prefix inet; } import tailf-ncs { prefix ncs; } augment /ncs:services { list vlan { key name; uses ncs:service-data; ncs:servicepoint "vlan"; leaf name { type string; } // may replace this with other ways of refering to the devices. leaf-list device { type leafref { path "/ncs:devices/ncs:device/ncs:name"; } } // replace with your own stuff here leaf dummy { type inet:ipv4-address; } } } }
If this is your first exposure to YANG you can see that the modeling language is very straightforward and easy to understand. See RFC 6020 for more details and examples for YANG. The concepts to understand in the above generated skeleton are:
-
The vlan service list will be augmented into the services tree in NSO. This specifies the path to reach vlans in the CLI, REST etc. There are no requirements on where the service shall be added into NSO. If you want vlans to be in the top (in the CLI for example), just remove the augments statement.
-
The two lines of
uses ncs:service-data
andncs:servicepoint "vlan"
tells NSO that this is a service. This will be explained more later in the document.
So if a user wants to create a new VLAN in the network what should be
the parameters? - A very simple service model would look like below
(modify the src/yang/vlan.yang
file):
augment /ncs:services { list vlan { key name; uses ncs:service-data; ncs:servicepoint "vlan"; leaf name { type string; } leaf vlan-id { type uint32 { range "1..4096"; } } list device-if { key "device-name"; leaf device-name { type leafref { path "/ncs:devices/ncs:device/ncs:name"; } } leaf interface-type { type enumeration { enum FastEthernet; enum GigabitEthernet; enum TenGigabitEthernet; } } leaf interface { type string; } } } }
This simple VLAN service model says:
-
We give a VLAN a name, for example net-1, this must also be unique, it is specified as "key".
-
The VLAN has an id from 1 to 4096
-
The VLAN is attached to a list of devices and interfaces. In order to make this example as simple as possible the interface reference is selected by picking the type and then the name as a plain string.
The good thing with NSO is that already at this point you could load the service model to NSO and try if it works well in the CLI etc. Nothing would happen to the devices since we have not defined the mapping, but this is normally the way to iterate a model, test the CLI towards the network engineers.
To build this service model cd to
$NCS_DIR/examples.ncs/getting-started/using-ncs/1-simulated-cisco-ios/packages/vlan/src
and type make (assuming you have the make build
system installed).
$ make
Go to the root directory of the simulated-ios
example:
$ cd $NCS_DIR/examples.ncs/getting-started/using-ncs/1-simulated-cisco-ios
Start netsim, NSO and the CLI:
$ncs-netsim start
$ncs --with-package-reload
$ncs_cli -C -u admin
When starting NSO above we give NSO a parameter to reload all packages so that our newly added vlan package is included. Packages can also be reloaded without restart. At this point we have a service model for VLANs, but no mapping of VLAN to device configurations. This is fine, we can try the service model and see if it makes sense. Create a VLAN service:
admin@ncs(config)#services vlan net-0 vlan-id 1234 \ device-if c0 interface-type FastEthernet interface 1/0
admin@ncs(config-device-if-c0)#top
admin@ncs(config)#show configuration
services vlan net-0 vlan-id 1234 device-if c0 interface-type FastEthernet interface 1/0 ! ! admin@ncs(config)#services vlan net-0 vlan-id 1234 \ device-if c1 interface-type FastEthernet interface 1/0
admin@ncs(config-device-if-c1)# top admin@ncs(config)#show configuration
services vlan net-0 vlan-id 1234 device-if c0 interface-type FastEthernet interface 1/0 ! device-if c1 interface-type FastEthernet interface 1/0 ! ! admin@ncs(config)# admin@ncs(config)#commit dry-run outformat native
admin@ncs(config)#commit
Commit complete. admin@ncs(config)#no services vlan
admin@ncs(config)#commit
Commit complete.
Committing service changes has no effect on the devices since we have not defined the mapping. The service instance data will just be stored in NSO CDB.
Note that you get tab completion on the devices since they are leafrefs to device names in CDB, the same for interface-type since the types are enumerated in the model. However the interface name is just a string, and you have to type the correct interface-name. For service-models where there is only one device-type like in this simple example, we could have used a reference to the ios interface name according to the IOS model. However that makes the service model dependent on the underlying device types and if another type is added, the service model needs to be updated and this is most often not desired. There are techniques to get tab completion even when the data-type is string, but this is omitted here for simplicity.
Make sure you delete the vlan service instance as above before moving on with the example.
Now it is time to define the mapping from service configuration to actual device configuration. The first step is to understand the actual device configuration. Hard-wire the vlan towards a device as an example. This concrete device configuration is a boiler-plate for the mapping, it shows the expected result of applying the service.
admin@ncs(config)#devices device c0 config ios:vlan 1234
admin@ncs(config-vlan)#top
admin@ncs(config)#devices device c0 config ios:interface \ FastEthernet 10/10 switchport trunk allowed vlan 1234
admin@ncs(config-if)#top
admin@ncs(config)#show configuration
devices device c0 config ios:vlan 1234 ! ios:interface FastEthernet10/10 switchport trunk allowed vlan 1234 exit ! ! admin@ncs(config)#commit
The concrete configuration above has the interface and VLAN hard-wired. This is what we now will make into a template instead. It is always recommended to start like above and create a concrete representation of the configuration the template shall create. Templates are device-configuration where parts of the config is represented as variables. These kind of templates are represented as XML files. Show the above as XML:
admin@ncs(config)# show full-configuration devices device c0 \ config ios:vlan | display xml <config xmlns="http://tail-f.com/ns/config/1.0"> <devices xmlns="http://tail-f.com/ns/ncs"> <device> <name>c0</name> <config> <vlan xmlns="urn:ios"> <vlan-list> <id>1234</id> </vlan-list> </vlan> </config> </device> </devices> </config> admin@ncs(config)# show full-configuration devices device c0 \ config ios:interface FastEthernet 10/10 | display xml <config xmlns="http://tail-f.com/ns/config/1.0"> <devices xmlns="http://tail-f.com/ns/ncs"> <device> <name>c0</name> <config> <interface xmlns="urn:ios"> <FastEthernet> <name>10/10</name> <switchport> <trunk> <allowed> <vlan> <vlans>1234</vlans> </vlan> </allowed> </trunk> </switchport> </FastEthernet> </interface> </config> </device> </devices> </config> admin@ncs(config)#
Now, we shall build that template. When the package was created a skeleton
XML file was created in packages/vlan/templates/vlan.xml
<config-template xmlns="http://tail-f.com/ns/config/1.0" servicepoint="vlan"> <devices xmlns="http://tail-f.com/ns/ncs"> <device> <!-- Select the devices from some data structure in the service model. In this skeleton the devices are specified in a leaf-list. Select all devices in that leaf-list: --> <name>{/device}</name> <config> <!-- Add device-specific parameters here. In this skeleton the service has a leaf "dummy"; use that to set something on the device e.g.: <ip-address-on-device>{/dummy}</ip-address-on-device> --> </config> </device> </devices> </config-template>
We need to specify the right path to the devices. In our case the devices are
identified by /device-if/device-name
(see the YANG service model).
For each of those devices we need to add the VLAN and change the specified interface configuration. Copy the XML config from the CLI and replace with variables:
<config-template xmlns="http://tail-f.com/ns/config/1.0" servicepoint="vlan"> <devices xmlns="http://tail-f.com/ns/ncs"> <device> <name>{/device-if/device-name}</name> <config> <vlan xmlns="urn:ios"> <vlan-list tags="merge"> <id>{../vlan-id}</id> </vlan-list> </vlan> <interface xmlns="urn:ios"> <?if {interface-type='FastEthernet'}?> <FastEthernet tags="nocreate"> <name>{interface}</name> <switchport> <trunk> <allowed> <vlan tags="merge"> <vlans>{../vlan-id}</vlans> </vlan> </allowed> </trunk> </switchport> </FastEthernet> <?end?> <?if {interface-type='GigabitEthernet'}?> <GigabitEthernet tags="nocreate"> <name>{interface}</name> <switchport> <trunk> <allowed> <vlan tags="merge"> <vlans>{../vlan-id}</vlans> </vlan> </allowed> </trunk> </switchport> </GigabitEthernet> <?end?> <?if {interface-type='TenGigabitEthernet'}?> <TenGigabitEthernet tags="nocreate"> <name>{interface}</name> <switchport> <trunk> <allowed> <vlan tags="merge"> <vlans>{../vlan-id}</vlans> </vlan> </allowed> </trunk> </switchport> </TenGigabitEthernet> <?end?> </interface> </config> </device> </devices> </config-template>
Walking through the template can give a better idea of how it
works. For every /device-if/device-name
from the service
model do the following:
-
Add the vlan to the vlan-list, the tag merge tells the template to merge the data into an existing list (default is replace).
-
Fore every interface within that device, add the vlan to the allowed vlans and set mode to trunk. The tag "nocreate" tells the template to not create the named interface if it does not exist
It is important to understand that every path in the template above
refers to paths from the service model in vlan.yang
.
Request NSO to reload the packages:
admin@ncs# packages reload
reload-result {
package cisco-ios
result true
}
reload-result {
package vlan
result true
}
Previously we started ncs with a reload package option, the above shows how to do the same without starting and stopping NSO.
We can now create services that will make things happen in the network. (Delete any dummy service from the previous step first). Create a VLAN service:
admin@ncs(config)#services vlan net-0 vlan-id 1234 device-if c0 \ interface-type FastEthernet interface 1/0
admin@ncs(config-device-if-c0)#top
admin@ncs(config)#services vlan net-0 device-if c1 \ interface-type FastEthernet interface 1/0
admin@ncs(config-device-if-c1)#top
admin@ncs(config)#show configuration
services vlan net-0 vlan-id 1234 device-if c0 interface-type FastEthernet interface 1/0 ! device-if c1 interface-type FastEthernet interface 1/0 ! ! admin@ncs(config)#commit dry-run outformat native
native { device { name c0 data interface FastEthernet1/0 switchport trunk allowed vlan 1234 exit } device { name c1 data vlan 1234 ! interface FastEthernet1/0 switchport trunk allowed vlan 1234 exit } } admin@ncs(config)#commit
Commit complete.
When working with services in templates there is a useful debug option for commit which will show the template and XPATH evaluation.
admin@ncs(config)#commit | debug
Possible completions: template Display template debug info xpath Display XPath debug info admin@ncs(config)#commit | debug template
We can change the VLAN service:
admin@ncs(config)#services vlan net-0 vlan-id 1222
admin@ncs(config-vlan-net-0)#top
admin@ncs(config)#show configuration
services vlan net-0 vlan-id 1222 ! admin@ncs(config)#commit dry-run outformat native
native { device { name c0 data no vlan 1234 vlan 1222 ! interface FastEthernet1/0 switchport trunk allowed vlan 1222 exit } device { name c1 data no vlan 1234 vlan 1222 ! interface FastEthernet1/0 switchport trunk allowed vlan 1222 exit } }
It is important to understand what happens above. When the VLAN id is changed, NSO is able to calculate the minimal required changes to the configuration. The same situation holds true for changing elements in the configuration or even parameters of those elements. In this way NSO does not need to explicit mapping to define a VLAN change or deletion. NSO does not overwrite a new configuration on the old configuration. Adding an interface to the same service works the same:
admin@ncs(config)#services vlan net-0 device-if c2 interface-type FastEthernet interface 1/0
admin@ncs(config-device-if-c2)#top
admin@ncs(config)#commit dry-run outformat native
native { device { name c2 data vlan 1222 ! interface FastEthernet1/0 switchport trunk allowed vlan 1222 exit } } admin@ncs(config)#commit
Commit complete.
To clean up the configuration on the devices, run the delete command as shown below:
admin@ncs(config)#no services vlan net-0
admin@ncs(config)#commit dry-run outformat native
native { device { name c0 data no vlan 1222 interface FastEthernet1/0 no switchport trunk allowed vlan 1222 exit } device { name c1 data no vlan 1222 interface FastEthernet1/0 no switchport trunk allowed vlan 1222 exit } device { name c2 data no vlan 1222 interface FastEthernet1/0 no switchport trunk allowed vlan 1222 exit } } admin@ncs(config)#commit
Commit complete.
To make the VLAN service package complete edit the package-meta-data.xml to reflect the service model purpose. This example showed how to use template-based mapping. NSO also allows for programmatic mapping and also a combination of the two approaches. The latter is very flexible, if some logic need to be attached to the service provisioning that is expressed as templates and the logic applies device agnostic templates.
FASTMAP is the NSO algorithm that renders any service change from the single definition of the create service. As seen above, the template or code only has to define how the service shall be created, NSO is then capable of defining any change from that single definition.
A limitation in the scenarios described so far is that the mapping definition could immediately do its work as a single atomic transaction. This is sometimes not possible. Typical examples are: external allocation of resource such as IP addresses from an IPAM, spinning up VMs, and sequencing in general.
Reactive FASTMAP addresses these scenarios. The general idea is that the create definition does not only write device configuration but also state data for the service. An external process subscribes to that state data and performs the side-effects. The external process will then call service redeploy which will run the create method again, checking available states like allocated IP address, running VM etc.
The example in
getting-started/developing-with-ncs/4-rfs-service
has a package called vlan-reactive-fastmap
that
implements external allocation of a unit and a vlan-id for the
service to illustrate this concept.
A very common situation when we wish to deploy NSO in an existing network is that the network already has existing services implemented in the network. These services may have been deployed manually or through an other provisioning system. The task is to introduce NSO, import the existing services into NSO. The goal is to use NSO to manage existing services, and to add additional instances of the same service type, using NSO. This is a non-trivial problem since existing services may have been introduced in various ways. Even if the service configuration has been done consistently it resembles the challenges of a general solution for rendering a corresponding C-program from assembler.
One of the prerequisites for this to work is that it is possible to construct a list of the already existing services. Maybe such a list exists in an inventory system, an external database, or maybe just an Excel spreadsheet. It may also be the case that we can:
-
Import all managed devices into NSO.
-
Execute a full sync-from on the entire network.
-
Write a program, using Python/Maapi or Java/Maapi that traverses the entire network configuration and computes the services list.
The first thing we must do when we wish to reconcile existing services is to define the service YANG model. The second thing is to implement the service mapping logic, and do it in such a way that given the service input parameters, when we run the service code, they would all result in configuration that is already there in the existing network.
The basic principles for reconciliation is:
-
Read the device configuration to NSO using the
sync-from
action. This will get the device configuration that is a result of any existing services as well. -
Instantiate the services according to the principles above
Performing the above actions with the default behaviour would not render the correct reference counters since NSO did not actually create the original configuration. The service activation can be run with dedicated flags to take this into account. See the NSO User Guide for a detailed process.
In many cases a service activation solution like NSO is deployed in parallel with existing activation solutions. It is then desirable to make sure that NSO does not conflict with the device configuration rendered from the existing solution.
NSO has a commit-flag that will restrict the device
configuration to not overwrite data that NSO did not create:
commit no-overwrite