- Start
- What's New
- Getting Started
- User Guide
- About
- Basic Operations
- Network Element Drivers and Adding Devices
- Managing Network Services
- NSO CLI
- The NSO Device Manager
- SSH Key Management
- Alarm Manager
- Plug-and-play Scripting
- Compliance reporting
- NSO Packages
- Life-cycle Operations - Manipulating Existing Services and Devices
- Web User Interface
- Network Simulator
- Administration Guide
- Northbound APIs
- Development Guide
- Preface
- Development Environment and Resources
- The Configuration Database and YANG
- Basic Automation with Python
- Developing a Simple Service
- Applications in NSO
- Implementing Services
- Templates
- Services Deep Dive
- 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
- Service Development Using Java
- NED Development
- NED Upgrades and Migration
- Service Handling of Ambiguous Device Models
- Scaling and Performance Optimization
- NSO Concurrency Model
- Developing Alarm Applications
- SNMP Notification Receiver
- The web server
- Kicker
- Scheduler
- Progress Trace
- Nano Services for Staged Provisioning
- Encryption Keys
- External Logging
- NSO Developer Studio
- Web UI
- Layered Service Architecture
- Manual Pages
- NSO Documentation Home
- NSO SDK API Reference
- NSO Change Log Explorer
- NSO NED Change Log Explorer
- NSO NED Capabilities Explorer
- NSO on DevNet
- Get Support
OUTDATED
OUTDATED
This documentation corresponds to an older version of the product, is no longer updated, and may contain outdated information.
Please access the latest versions from https://cisco-tailf.gitbook.io/nso-docs and update your bookmarks. OK
All user code that needs to run in NSO must be part of a package. A package is basically a directory of files with a fixed file structure. A package consists of code, YANG modules, custom Web UI widgets etc., that are needed in order to add an application or function to NSO. Packages is a controlled way to manage loading and versions of custom applications.
A package is a directory where the package name is the same as
the directory name. At the toplevel of this directory a file called
package-meta-data.xml
must exist. The structure
of that file is defined by the YANG model
$NCS_DIR/src/ncs/yang/tailf-ncs-packages.yang
.
A package may also be a tar archive with the same directory
layout. The tar archive can be either uncompressed with suffix
.tar
, or gzip-compressed with suffix
.tar.gz
or .tgz
.
The archive file should also follow some naming conventions.
There are two acceptable naming conventions for archive files, one is that
after the introduction of CDM in the NSO 5.1, it can be named by
ncs-<ncs-version>-<package-name>-<package-version>.<suffix>,
e.g. ncs-5.3-my-package-1.0.tar.gz
and the other is
<package-name>-<package-version>.<suffix>,
e.g. my-package-1.0.tar.gz
.
-
package-name
- should use letters, digits and may include underscores (_) or dashes (-), but no additional punctuation and digits can not follow underscores or dashes immediately. -
package-version
- should use numbers and dot (.).
Packages are composed of components. The following types of components are defined: NED, Application, and Callback.
The file layout of a package is:
<package-name>/package-meta-data.xml load-dir/ shared-jar/ private-jar/ webui/ templates/ src/ doc/ netsim/
The package-meta-data.xml
defines several
important aspects of the package, such as the name,
dependencies on other packages, the package's components etc.
This will be thoroughly described later in this chapter.
When NSO starts, it needs to search for packages to load.
The ncs.conf
parameter
/ncs-config/load-path
defines a list of directories.
At initial startup, NSO searches these directories for packages,
copies the packages to a private directory tree in the directory
defined by the /ncs-config/state-dir
parameter in
ncs.conf
, and loads and starts all the
packages found. All .fxs (compiled YANG files) and .ccl
(compiled CLI spec files) files found in the directory
load-dir
in a package are loaded. On
subsequent startups, NSO will by default only load and start the
copied packages - see the section called “Loading Packages”
for different ways to get NSO to search the load path for
changed or added packages.
A package usually contains Java code. This Java code is
loaded by a class loader in the NSO Java VM. A package that
contains Java code must compile the Java code so that the
compilation results are divided into jar files where code that
is supposed to be shared among multiple packages is compiled into
one set of jar files, and code that is private to the package
itself is compiled into another set of jar files. The shared
and the common jar files shall go into the
shared-jar
directory and the
private-jar
directory, respectively. By
putting for example the code for a specific service in a
private jar, NSO can dynamically upgrade the service without
affecting any other service.
The optional webui
directory contains
webui customization files.
The NSO example collection for developers contains a number
of small self-contained examples. The collection resides at
$NCS_DIR/examples.ncs/getting-started/developing-with-ncs
Each of these examples defines a package. Let's take a look at
some of these packages. The example 3-aggregated-stats
has a
package ./packages/stats
. The
package-meta-data.xml
file for that
package looks like:
<ncs-package xmlns="http://tail-f.com/ns/ncs-packages"> <name>stats</name> <package-version>1.0</package-version> <description>Aggregating statistics from the network</description> <ncs-min-version>3.0</ncs-min-version> <required-package> <name>router-nc-1.0</name> </required-package> <component> <name>stats</name> <callback> <java-class-name>com.example.stats.Stats</java-class-name> </callback> </component> </ncs-package>
The file structure in the package looks like:
|----package-meta-data.xml |----private-jar |----shared-jar |----src | |----Makefile | |----yang | | |----aggregate.yang | |----java | |----build.xml | |----src | |----com | |----example | |----stats | |----namespaces | |----Stats.java |----doc |----load-dir
The package-meta-data.xml
file defines the name
of the package, additional settings, and one component.
Its settings are defined by
the $NCS_DIR/src/ncs/yang/tailf-ncs-packages.yang
YANG model, where the package list name gets renamed
to ncs-package. See
the tailf-ncs-packages.yang
module where all options
are described in more detail. To get an overview, use the IETF RFC 8340
based YANG tree diagram.
$ yanger -f tree tailf-ncs-packages.yang
submodule: tailf-ncs-packages (belongs-to tailf-ncs) +--ro packages +--ro package* [name] <-- renamed to "ncs-package" in package-meta-data.xml +--ro name string +--ro package-version version +--ro description? string +--ro ncs-min-version* version +--ro ncs-max-version* version +--ro python-package! | +--ro vm-name? string | +--ro callpoint-model? enumeration +--ro directory? string +--ro templates* string +--ro template-loading-mode? enumeration +--ro supported-ned-id* union +--ro supported-ned-id-match* string +--ro required-package* [name] | +--ro name string | +--ro min-version? version | +--ro max-version? version +--ro component* [name] +--ro name string +--ro description? string +--ro entitlement-tag? string +--ro (type) +--:(ned) | +--ro ned | +--ro (ned-type) | | +--:(netconf) | | | +--ro netconf | | | +--ro ned-id? identityref | | +--:(snmp) | | | +--ro snmp | | | +--ro ned-id? identityref | | +--:(cli) | | | +--ro cli | | | +--ro ned-id identityref | | | +--ro java-class-name string | | +--:(generic) | | +--ro generic | | +--ro ned-id identityref | | +--ro java-class-name string | +--ro device | | +--ro vendor string | | +--ro product-family? string | +--ro option* [name] | +--ro name string | +--ro value? string +--:(upgrade) | +--ro upgrade | +--ro (type) | +--:(java) | | +--ro java-class-name? string | +--:(python) | +--ro python-class-name? string +--:(callback) | +--ro callback | +--ro java-class-name* string +--:(application) +--ro application +--ro (type) | +--:(java) | | +--ro java-class-name string | +--:(python) | +--ro python-class-name string +--ro start-phase? enumeration
Note
The order of the XML entries in a
package-meta-data.xml
must
be in the same order as the model shown above.
A sample package configuration taken from
the $NCS_DIR/examples.ncs/development-guide/nano-services/netsim-vrouter
example:
$ ncs_load -o -Fp -p /packages
<config xmlns="http://tail-f.com/ns/config/1.0"> <packages xmlns="http://tail-f.com/ns/ncs"> <package> <name>router-nc-1.1</name> <package-version>1.1</package-version> <description>Generated netconf package</description> <ncs-min-version>5.7</ncs-min-version> <directory>./state/packages-in-use/1/router</directory> <component> <name>router</name> <ned> <netconf> <ned-id xmlns:router-nc-1.1="http://tail-f.com/ns/ned-id/router-nc-1.1"> router-nc-1.1:router-nc-1.1</ned-id> </netconf> <device> <vendor>Acme</vendor> </device> </ned> </component> <oper-status> <up/> </oper-status> </package> <package> <name>vrouter</name> <package-version>1.0</package-version> <description>Nano services netsim virtual router example</description> <ncs-min-version>5.7</ncs-min-version> <python-package> <vm-name>vrouter</vm-name> <callpoint-model>threading</callpoint-model> </python-package> <directory>./state/packages-in-use/1/vrouter</directory> <templates>vrouter-configured</templates> <template-loading-mode>strict</template-loading-mode> <supported-ned-id xmlns:router-nc-1.1="http://tail-f.com/ns/ned-id/router-nc-1.1"> router-nc-1.1:router-nc-1.1</supported-ned-id> <required-package> <name>router-nc-1.1</name> <min-version>1.1</min-version> </required-package> <component> <name>nano-app</name> <description>Nano service callback and post-actions example</description> <application> <python-class-name>vrouter.nano_app.NanoApp</python-class-name> <start-phase>phase2</start-phase> </application> </component> <oper-status> <up/> </oper-status> </package> </packages> </config>
Below is a brief list of the configurables in the
tailf-ncs-packages.yang
YANG model that applies to
meta data file. A more detailed description can be found in the YANG
model:
-
name
- the name of the package. All packages in the system must have unique names. -
package-version
- the version of the package. This is for administrative purposes only, NSO cannot simultaneously handle two versions of the same package. -
ncs-min-version
- the oldest known NSO version where the package works. -
ncs-max-version
- the latest known NSO version where the package works. -
python-package
- Python specific package data.-
vm-name
- the Python VM name for the package. Default is the packagevm-name
. Packages with the samevm-name
run in the same Python VM. Applicable only whencallpoint-model = threading
. -
callpoint-model
- A Python package run Services, Nano Services, and Actions in the same OS process. If thecallpoint-model
is set tomultiprocessing
each will get a separate worker process. Running Services, Nano Services, and Actions in parallel can, depending on the application, improve the performance at the cost of complexity. See the section called “The application component” for details.
-
-
directory
- the path to the directory of the package. -
templates
- the templates defined by the package. -
template-loading-mode
- control if the templates are interpreted in strict or relaxed mode. -
supported-ned-id
- the list of ned-ids supported by this package. An example of the expected format taken from the$NCS_DIR/examples.ncs/development-guide/nano-services/netsim-vrouter
example:<supported-ned-id xmlns:router-nc-1.1="http://tail-f.com/ns/ned-id/router-nc-1.1"> router-nc-1.1:router-nc-1.1</supported-ned-id>
-
supported-ned-id-match
- the list of regular expressions for ned-ids supported by this package. Ned-ids in the system that matches at least one of the regular expressions in this list are added to thesupported-ned-id
list. The following example demonstrates how all minor versions with a major number of 1 of therouter-nc
NED can be added to a package's list of supported ned-ids:<supported-ned-id-match>router-nc-1.\d+:router-nc-1.\d+</supported-ned-id-match>
-
required-package
- a list of names of other packages that are required for this package to work. -
component
- Each package defines zero or more components.
Each component in a package has a name. The names of all the components must be unique within the package. The YANG model for packages contain:
.... list component { key name; leaf name { type string; } ... choice type { mandatory true; case ned { ... } case callback { ... } case application { ... } case upgrade { ... } .... } ....
Lots of additional information can be found in the YANG module itself. The mandatory choice that defines a component must be one of ned, callback, application or upgrade. We have:
- ned
-
A Network Element Driver component is used southbound of NSO to communicate with managed devices (described in the section called “CLI NED Development”). The easiest NED to understand is the NETCONF NED which is built in into NSO.
There are 4 different types of NEDs:
-
netconf - used for NETCONF enabled devices such as Juniper routers, ConfD powered devices or any device that speaks proper NETCONF and also has YANG models. Plenty of packages in the NSO example collection have NETCONF NED components, for example
$NCS_DIR/examples.ncs/getting-started/developing-with-ncs/0-router-network/packages/router
. -
snmp - used for SNMP devices.
The example
$NCS_DIR/examples.ncs/snmp-ned/basic
has a package which has an SNMP NED component. -
cli - used for CLI devices. The package
$NCS_DIR/packages/neds/cisco-ios
is an example of a package that has a CLI NED component. -
generic - used for generic NED devices. The example
$NCS_DIR/examples.ncs/generic-ned/xmlrpc-device
has a package calledxml-rpc
which defines a NED component of type generic
A CLI NED and a generic NED component must also come with additional user written Java code, whereas a NETCONF NED and an SNMP NED have no Java code.
-
- callback
-
This defines component with one or many java classes that implements callbacks using the Java callback annotations.
If we look at the component in the
stats
package above we have:<component> <name>stats</name> <callback> <java-class-name> com.example.stats.Stats </java-class-name> </callback> </component>
The Stats class here implements a read-only data provider. See the section called “DP API”.
The callback type of component is used for a wide range of callback type Java applications, where one of the most important are the Service Callbacks. The following list of Java callback annotations apply to callback components.
-
ServiceCallback - to implement service to device mappings. See example:
$NCS_DIR/examples.ncs/getting-started/developing-with-ncs/4-rfs-service
See Implementing Services for a thorough introduction to services. -
ActionCallback - to implement user defined tailf:actions or YANG RPCs. See example:
$NCS_DIR/examples.ncs/getting-started/developing-with-ncs/2-actions
-
DataCallback - to implement the data getters and setters for a data provider. See example
$NCS_DIR/examples.ncs/getting-started/developing-with-ncs/3-aggregated-stats
-
TransCallback to implement the transaction portions of a data provider callback. See example
$NCS_DIR/examples.ncs/getting-started/developing-with-ncs/3-aggregated-stats
-
DBCallback - to implement an external database. See example:
$NCS_DIR/examples.ncs/getting-started/developing-with-ncs/6-extern-db
-
SnmpInformResponseCallback to implement an SNMP listener - See example
$NCS_DIR/examples.ncs/snmp-notification-receiver
-
TransValidateCallback, ValidateCallback - to implement a user defined validation hook that gets invoked on every commit.
-
AuthCallback - to implement a user hook that gets called whenever a user is authenticated by the system.
-
AuthorizationCallback - to implement a authorization hook that allow/disallow users to do operations and/or access data. Note, this callback should normally be avoided since, by nature, invoking a callback for any operation and/or data element is an performance impairment.
A package that has a callback component usually has some YANG code and then also some Java code that relates to that YANG code. By convention the YANG and the Java code resides in a src directory in the component. When the source of the package is built, any resulting fxs files (compiled YANG files) must reside in the load-dir of the package and any resulting Java compilation results must reside in the shared-jar and private-jar directories. Study the 3-aggregated-stats example to see how this is achieved.
-
- application
-
Used to cover Java applications that do not fit into the callback type. Typically this is functionality that should be running in separate threads and work autonomously.
The example
$NCS_DIR/examples.ncs/getting-started/developing-with-ncs/1-cdb
contains three components that are of type application. These components must also contain a java-class-name element. For application components, that Java class must implement the ApplicationComponent Java interface. - upgrade
-
Used to migrate data for packages where the yang model has changed and the automatic cdb upgrade is not sufficient. The upgrade component consists of a java class with a main method that is expected to run one time only.
The example
$NCS_DIR/examples.ncs/getting-started/developing-with-ncs/14-upgrade-service
illustrates user cdb upgrades using upgrade components.
NSO ships with a tool ncs-make-package that can be used to create packages. Package Development discusses in depth how to develop a package.
This use case applies if we have a set of YANG files that define
a managed device. If we wish to develop an EMS solution
for an existing device and that device
has YANG files and also speaks NETCONF, we need to create
a package for that device in order to be able to manage it.
Assuming all YANG files for the device are stored in
./acme-router-yang-files
, we can create
a package for the router as:
$ ncs-make-package --netconf-ned ./acme-router-yang-files acme $ cd acme/src; make
The above command will create a package called acme
in ./acme
.
The acme package can be used for two
things; managing real acme routers and also be used as input
to the ncs-netsim tool to simulate a network
of acme routers.
In the first case, managing real acme routers, all we really need to do is to put the newly generated package in the load-path of NSO, start NSO with package reload (see the section called “Loading Packages”), and then add one or more acme routers as managed devices to NSO. The ncs-setup tool can be used to do this:
$ ncs-setup --ned-package ./acme --dest ./ncs-project
The above command generates a directory
./ncs-project
which is suitable for running
NSO. Assume we have an existing router at IP address
10.2.3.4
and that we can log into that
router over the NETCONF interface using user name
bob
, and password secret
.
The following session shows how to setup NSO to manage this router:
$ cd ./ncs-project $ ncs $ ncs_cli -u admin > configure > set devices authgroups group southbound-bob umap admin \ remote-name bob remote-password secret > set devices device acme1 authgroup southbound-bob address 10.2.3.4 > set devices device acme1 device-type netconf > commit
We can also use the newly generated acme package to simulate a network of acme routers. During development this is especially useful. The ncs-netsim tool can create a simulated network of acme routers as:
$ ncs-netsim create-network ./acme 5 a --dir ./netsim $ ncs-netsim start DEVICE a0 OK STARTED DEVICE a1 OK STARTED DEVICE a2 OK STARTED DEVICE a3 OK STARTED DEVICE a4 OK STARTED $
And finally, ncs-setup can be used to initialize an environment where NSO is used to manage all devices in an ncs-netsim network:
$ ncs-setup --netsim-dir ./netsim --dest ncs-project
Similarly, if we have a device that has a set of MIB files, we can use ncs-make-package to generate a package for that device. An SNMP NED package can, similarly to a NETCONF NED package, be used to both manage real devices and also be fed to ncs-netsim to generate a simulated network of SNMP devices.
Assuming we have a set of MIB files in
./mibs
, we can generate a package for a
device with those mibs as:
$ ncs-make-package --snmp-ned ./mibs acme $ cd acme/src; make
For CLI NEDs and Generic NEDs, we cannot (yet) generate the package.
Probably the best option for such packages is to start with one
of the examples. A good starting point for a CLI NED is
$NCS_DIR/packages/neds/cisco-ios
and a good starting
point for a Generic NED is the example
$NCS_DIR/examples.ncs/generic-ned/xmlrpc-device
The ncs-make-package can be used to generate empty skeleton packages for a data provider and a simple service. The flags --service-skeleton and --data-provider-skeleton
Alternatively one of the examples can be modified to provide
a good starting point. For example
$NCS_DIR/examples.ncs/getting-started/developing-with-ncs/4-rfs-service