Showing results for 
Search instead for 
Did you mean: 

Navigating the OpenDaylight/Cisco OSC Restconf Topology API

Cisco Employee

First off we need to distinguish between the OpenDaylight and Cisco OSC API structure.

In OpenDaylight the restconf API is at http://controller-ip:8181/restconf  (replace controller-ip with your own controller's IP!)

In Cisco Open SDN Controller (OSC) the restconf API is at https://controller-ip/controller/restconf

So then there are 3 types of restconf data:

1) config - at restconf/config

2) operational (state data) - at restconf/operational

3) RPCs - at restconf/operations

The next thing to be aware of is that whenever you see a URL component (i.e. text between two slashes) that has a colon in then that data is interpreted as yang-module:top-level-data-item.

In this post I will focus on working with network topologies (and in particular on the NETCONF topology/inventory and how we can use that to configure the controller itself), but the basic ideas here are applicable to other parts of the restconf API.

All topology/inventory is under network-topology:network-topology.   If you look at network-topology.yang you will see it has a top level container called "network-topology".    Note that there are 2 versions of network-topology.yang in ODL - network-topology@2013-07-12.yang  and network-topology@2013-10-21.yang.  These correspond to draft-clemm-netmod-yang-network-topo-00 and draft-clemm-netmod-yang-network-topo-01.   Those drafts have now expired - the current equivalent is draft-ietf-i2rs-yang-network-topo-01.  Once that makes it to RFC we'd expect ODL to support it.

So e.g. to get all operational topologies you can go to "...restconf/operational/network-topology:network-topology"

The network-topology container in network-topology.yang contains a list called "topology".    To get a list entry in RESTCONF you need to give the list name and then a value for the list key.   The key to the topology list is the topology ID.  So, for example to get the NETCONF inventory in Lithium or later you need to add "/topology/topology-netconf" to the URL above.

(Note that in Hydrogen and Helium the NETCONF inventory was at opendaylight-inventory:nodes and that still works in Lithium, but will no longer work from Beryllium).

Note that each individual topology may augment the base IETF topology model.  So e.g. for PCE-P there's a yang model - network-topology-pcep.yang which augments the topology with PCE-P specific attributes and which adds 3 RPCs for add-lsp, update-lsp and remove-lsp.  So e.g. to add an LSP you can POST to "..restconf/operations/network-topology:network-topology/topology/pcep-topology/add-lsp" with the appropriate body.

So in the topology-netconf case the next thing to do is generally to select the node from the topology.    A topology contains a list of nodes and a list of links.   The list of nodes is called "node" and the key is the node-ID.  So to access e.g. the OpenDaylight config subsystem you add "/node/controller-config".

The OpenDaylight config subsystem is a special case of a netconf node.  It is part of OpenDaylight itself and it listens on port 1830.  So if you do a “netstat -an” on your ODL instance you ought to see a local connection on port 1830.

OpenDaylight also listens on port 830 but provides only limited model support there.

You can also configure ODL to listen on port 2830 if you enable the feature odl-netconf-mdsal.   In that instance ODL exposes the same set of models over NETCONF as over RESTCONF.

Now for any netconf node if you want to access models exposed by that node over RESTCONF you need to add “/yang-ext:mount”.

so if you go to ../restconf/operational/network-topology:network-topology/topollogy/topology-netconf/node/controller-config you will see all the models exposed by the config subsystem.

from the above URL you can see that the config subsystem exposes the "config" model.   That model has a top level container called modules.  So now you can add "/config:modules".

The modules container contains a list of “module” with a key of “type name”.  so you need to add something of the form “/module/type/name” to select a specific module (in RESTCONF when a list has multiple keys you put slashes between them).    One challenge here is that the type is typically defined in a different module somewhere.

so for example if you want to get the configuration of the ODL BGP RIB then the the type is "rib-impl" but it's defined in odl-bgp-rib-impl-cfg.yang.  We typically call our own RIB "example-bgp-rib" (that's the name given in the 41-bgp-example.xml file).  So you need to add "/module/odl-bgp-rib-impl-cfg:rib-impl/example-bgp-rib"

So the final URL is ../restconf/config/network-topology:network-topology/topology/topology-netconf/node/controller-config/yang-ext:mount/config:modules/module/odl-bgp-rib-impl-cfg:rib-impl/example-bgp-rib".  (Note this is config, not operational).

Easy, wasn't it?

Not if you want to modify that RIB you need to do a PUT to that same URL with a modified body.  POST worked for Hydrogen/Helium but as of Lithium it's only possible to use POST to add new data, not to modify existing data.