Skip to content

Extending onos-config with Model Plugins

onos-config is an extensible configuration management system, that allows the configuration of many types and versions of devices to be managed concurrently.

Information models in YANG format (RFC 6020) can be used to accurately define the configuration and state objects and attributes of a device. In practice a device's object model usually comprises a number of YANG files including augments and deviations, and must be considered as a combined unit.

In onos-config a set of these combined YANG files defining a particular version of a device type is known as a Model.

Over its lifecycle onos-config will have to deal with different models as its scope is expanded and as devices go through new release cycles. To allow this, models are loadable dynamically as plugins in the form of Linux or Mac shared object libraries (\*.so) using the YGOT library and are known as Model Plugins.

The benefit of loading the Model Plugin as a shared library, is that it is run in the same process as onos-config, and accessing it is very fast, without involving a network hop.

The model plugin must have been built with the same version of "go" and with the same version of dependencies to load correctly.

The diagram shows the connection between the Model Plugin and the configuration store - linked by Device Type and Version. Effectively the primary key of the Model Registry is the Model Name and Version, whereas the primary key of the Configuration is the Device Name and Version.

onos-config internals

Role of the Model Plugin

The Model Plugin enables the following functionality in onos-config:

  1. Ensures that invalid values are not saved in to the configuration (this covers wrong data type, data values beyond range or not matching a pattern, lists that are not within their cardinality limits)
  2. Ensuring that read only values are not allowed to be set (changed).
  3. Checking the validity of stores on startup
  4. Enabling the Operational State cache within onos-config
  5. Enabling the retrieval of attributes by type - CONFIG or OPERATIONAL
  6. Enabling clients to access the model metadata through the Admin NBI
  7. Enabling JSON Payloads in gNMI SetRequests to be interpreted

onos-operator deploy-time compilation of Model Plugins

onos-operator is a Kubernetes controller that ensures Model Plugin YANG files are compiled in to shared object libraries that can be loaded by onos-config. This compilation is performed at "deploy time" to avoid any Go module incompatibilities.

Two Kubernetes Custom Resource Definitions (CRDs) - Model and ModelRegistry are used to configure Model Plugins in the Kubernetes API. Instances of Model are loaded through Helm charts independent of onos-config. Different versions of a model can be loaded at the same time.

When the onos-config Helm Chart is loaded, the model-registry sidecar runs alongside onos-config container, and ensures that any Model entries are compiled and loaded. The model-registry also keeps a cache of any compiled plugins.

Structure of a Model Plugin

A Model Plugin is mainly generated by the generator command from the YGOT project, and a wrapper modelmain.go implementing the ConfigModel interface. They are compiled together with the go build command using the -buildmode=plugin option.

Many examples of Model Plugins can be found in config-models.

ModelPlugin Interface

The model plugin must implement the ConfigModel interface. This will allow it to be entered in to the Model Registry.

type ConfigModel interface {
    // Info returns the config model info
    Info() ModelInfo

    // Data returns the config model data
    Data() []*gnmi.ModelData

    // Schema returns the config model schema
    Schema() (map[string]*yang.Entry, error)

    // GetStateMode returns the get state mode
    GetStateMode() GetStateMode

    // Unmarshaler returns the config model unmarshaler function
    Unmarshaler() Unmarshaler

    // Validator returns the config model validator function
    Validator() Validator
}

Creating your own Model Plugin

YANG files

The YANG files to be used with model-registry should be collected together in a folder and named in the style:

  • \<modulename>.yang or
  • \<modulename>@<latestrevision>.yang

Note The Yang files provided are required not to contain overlapping or clashing namespaces at the same path level. This requirement is necessary during the model compilation in YGOT because this tool offers no support for namespaces in the form of /namespace:path/path2, e.g. /openconfig-system:system/clock. YGOT compilation of a model containing /openconfig-system:system/clock will result in the path being /system/clock

To visualize and further validate the collection of YANG files, the pyang tool can be used like:

> pyang -f tree <list of top level YANG files>

This writes a tree like format to standard out. It is recommeded to capture this in a file and persist it in the Helm chart with the extension .tree, for easy inspection

Creating templates/model.yaml

To populate the Model CRD a model.yaml is necessary for each Model Plugin.

It should contain a modules section that lists out only the top level YANG files

YANG Files that are imported (e.g. with type definitions) do not need to be listed here

An example of a model.yaml is Devicesim 1.0.0 model

Verifying compilation and installation of Model Plugin

Since the Model is a CRD, it can be managed through kubectl

kubectl -n micro-onos get Models
NAME                                         AGE
onos-umbrella-1.0.0-config-model-devicesim   164m
onos-umbrella-1.0.0-config-model-stratum     164m

Likewise with ModelRegistry:

kubectl -n micro-onos get ModelRegistry
NAME          AGE
onos-config   165m

The model-registry can be seen in the onos-config Pod description with:

kubectl -n micro-onos describe $(kubectl -n micro-onos get pods -l type=config -o name)

and its logs can be seen with:

kubectl -n micro-onos logs --follow $(kubectl -n micro-onos get pods -l type=config -o name) model-registry

The onos-cli also has a command for accessing the model-registry:

$ onos modelregistry list
Devicesim: 1.0.0     4 YANGS
Name                      File                           Revision   Organization
openconfig-interfaces     openconfig-interfaces.yang     2017-07-14   OpenConfig working group 
openconfig-openflow       openconfig-openflow.yang       2017-06-01   OpenConfig working group 
openconfig-platform       openconfig-platform.yang       2016-12-22   OpenConfig working group 
openconfig-system         openconfig-system.yang         2017-07-06   OpenConfig working group 

Stratum: 1.0.0     21 YANGS
Name                      File                           Revision   Organization
iana-if-type              iana-if-type.yang              2017-01-19                            
ietf-inet-types           ietf-inet-types.yang           2013-07-15                            
ietf-interfaces           ietf-interfaces.yang           2014-05-08-modified                          
ietf-yang-types           ietf-yang-types.yang           2013-07-15                            
openconfig-interfaces     openconfig-interfaces.yang     2018-11-21   OpenConfig working group 
openconfig-if-ip          openconfig-if-ip.yang          2018-11-21   OpenConfig working group 
openconfig-lacp           openconfig-lacp.yang           2018-11-21   OpenConfig working group 
openconfig-platform       openconfig-platform.yang       2019-04-16   OpenConfig working group 
openconfig-platform-linecard openconfig-platform-linecard.yang 2018-11-21   OpenConfig working group 
openconfig-platform-port  openconfig-platform-port.yang  2018-11-21   OpenConfig working group 
openconfig-platform-transceiver openconfig-platform-transceiver.yang 2018-11-25   OpenConfig working group 
openconfig-vlan           openconfig-vlan.yang           2018-11-21   OpenConfig working group 
openconfig-system         openconfig-system.yang         2019-01-29   OpenConfig working group 
openconfig-hercules-platform-linecard openconfig-hercules-platform-linecard.yang 2018-06-01   OpenConfig working group 
openconfig-hercules-qos   openconfig-hercules-qos.yang   2018-06-01   OpenConfig working group 
openconfig-hercules-platform openconfig-hercules-platform.yang 2018-06-01   OpenConfig working group 
openconfig-hercules-platform-chassis openconfig-hercules-platform-chassis.yang 2018-06-01   OpenConfig working group 
openconfig-hercules-platform-port openconfig-hercules-platform-port.yang 2018-06-01   OpenConfig working group 
openconfig-hercules       openconfig-hercules.yang       2018-06-01   OpenConfig working group 
openconfig-hercules-interfaces openconfig-hercules-interfaces.yang 2018-06-01   OpenConfig working group 
openconfig-hercules-platform-node openconfig-hercules-platform-node.yang 2018-06-01   OpenConfig working group 

Capabilities on gNMI Northbound interface

The CapabilitiesResponse on the gNMI northound interface is generated dynamically from the combined modules of all the loaded Model Plugins.

At runtime when devices are connected to onos-config the response to the Capabilities request are compared with the modules for their corresponding ModelPlugin - if there is not an exact match a warning is displayed.

OpenConfig Models

Some devices that support OpenConfig Models report their capabilities using an OpenConfig versioning scheme e.g. 0.5.0, rather than the YANG revision date in the format 2017-07-06. If the device can correct its capabilities to give the revision then it should to be more consistent with non OpenConfig YANG models.

Accessing OpenConfig model of a specific revision requires a number of steps in Github.

For instance if a device reports it used openconfig-interfacess.yang 2.0.0, then to get this file do:

  • Browse to openconfig-interfaces.yang
  • Observe in the list of revision items in the YANG file that the reference 2.0.0 corresponds to a release date of 2017-07-14
  • Click in the History button
  • In the History page for this file, see that the next commit after this date was on Aug 9, 2017
  • Click on the related commit message
  • In the list of files modified in that commit click the ... next to the file openconfig-interfacess.yang and choose View File
  • In the page that displays the historical version of the file, click the Raw button
  • In the resulting raw display of the YANG file verify that the latest revision is 2017-07-14
  • Save the file locally as openconfig-interfaces@2017-07-14.yang

If the generator program reports that a dependency was required e.g. openconfig-inet-types.yang then the version of this file with a date equal to or before 2017-07-14 should be downloaded - it is openconfig-inet-types@2017-07-14.yang

Readonly paths in YANG models

When an item (leaf, cntainer or list) in a YANG file has "config false" it is effectively a read-only attribute. Usually read-only items are interspersed throughout the YANG model.

When the Model Plugin is loaded, setting of an attribute like state/address should give an appropriate error

> gnmi_cli -address onos-config:5150 -set \
    -proto "update: <path: <target: 'devicesim-1', elem: <name: 'system'> elem: <name: 'openflow'> elem: <name: 'controllers'> elem: <name: 'controller' key: <key: 'name' value: 'main'>> elem: <name: 'connections'> elem: <name: 'connection' key: <key: 'aux-id' value: '0'>> elem: <name: 'state'> elem: <name: 'address'>> val: <string_val: '192.0.2.11'>>" \
    -timeout 5s -en PROTO -alsologtostderr \
    -client_crt /etc/ssl/certs/client1.crt -client_key /etc/ssl/certs/client1.key -ca_crt /etc/ssl/certs/onfca.crt

gives the error:

rpc error: code = InvalidArgument desc = update contains a change to a read only
  path /system/openflow/controllers/controller[name=main]/connections/connection[aux-id=0]/state/address. Rejected