How do I use OpenDaylight with YDK?

YDK makes it easy to interact with OpenDaylight programmatically using the YANG model APIs.

Applications can be written using the Python model API in conjunction with a service and a provider.

Writing the app

In this example, we set some BGP configuration using the Cisco IOS XR model, the CRUD (Create/Read/Update/Delete) service and the OpenDaylightServiceProvider. The example in this document is a simplified version of the more complete sample that is available in core/samples/bgp_xr_opendaylight.py. Assuming you have performed the core and cisco-ios-xr bundle installations first(see Core Installation), the more complete sample can be run with the below steps:

ydk-py$ cd core/samples
samples$ ./bgp_xr_opendaylight.py http://<username>:<password>@<host-address>:<port>

What happens underneath

YDK performs the below actions when running this application:

  1. Establish a session with the OpenDaylight instance and fetch the details of the nodes mounted on the southbound

  2. Encode Python data objects to the protocol format (e.g. restconf JSON payload)

  3. For a chosen node on the southbound, perform transport operation with the device and collect the response (e.g. restconf reply)

  4. Decode response as Python object and return the result to app

  5. Raise Python exceptions for any errors that occurred

Import libraries

In our example YDK application, first, let us import the necessary libraries

 1import os
 2import sys
 3from argparse import ArgumentParser
 4if sys.version_info > (3,):
 5    from urllib.parse import urlparse
 6else:
 7    from urlparse import urlparse
 8
 9from ydk.types import Empty
10from ydk.services import CRUDService
11from ydk.providers import OpenDaylightServiceProvider
12from ydk.errors import YError
13from ydk.types import EncodingFormat
14from ydk.path import Repository
15from ydk.models.cisco_ios_xr import Cisco_IOS_XR_ipv4_bgp_cfg as xr_bgp
16from ydk.models.cisco_ios_xr import Cisco_IOS_XR_ipv4_bgp_datatypes as xr_bgp_types

OpenDaylight service provider

The first step in any application is to create a service provider instance. In this case, the OpenDaylight service provider is responsible for mapping between the CRUD service API and the underlying manageability protocol (Restconf).

We first instantiate a Repository using the location of the schema cache of the OpenDaylight instance. We instantiate an instance of the service provider that can communicate using Restconf with an OpenDaylight instance running at host address: 127.0.0.1 and port: 8181

17repo = Repository("/Users/home/distribution-karaf-0.5.2-Boron-SR2/cache/schema") # In this case, we have a ODL boron instance with this schema cache location
18odl_provider = OpenDaylightServiceProvider(repo, "127.0.0.1", "admin", "admin", 8181, EncodingFormat.XML)

Using the model APIs

After establishing the connection, let’s instantiate the entities and set some data. Now, create a Cisco IOS XR Bgp configuration object and set the attributes

19# Create BGP object
20bgp = xr_bgp.Bgp()
21
22# BGP instance
23instance = bgp.Instance()
24instance.instance_name = "test"
25instance_as = instance.InstanceAs()
26instance_as.as_ = 65001;
27four_byte_as = instance_as.FourByteAs()
28four_byte_as.as_ = 65001;
29four_byte_as.bgp_running = Empty();
30
31# global address family
32global_af = four_byte_as.DefaultVrf.Global_.GlobalAfs.GlobalAf()
33global_af.af_name = xr_bgp_types.BgpAddressFamilyEnum.ipv4_unicast;
34global_af.enable = Empty();
35four_byte_as.default_vrf.global_.global_afs.global_af.append(global_af)
36
37# add the instance to the parent BGP object
38instance_as.four_byte_as.append(four_byte_as)
39instance.instance_as.append(instance_as)
40bgp.instance.append(instance)

Invoking the CRUD Service

The CRUD service provides methods to create, read, update and delete entities on a device making use of the session provided by a service provider. In order to use the CRUD service, we need to instantiate the CRUDService class

41crud_service = CRUDService()

At this point we can explore the southbound device node-IDs using the function call: get_node_ids. Let us assume there is a XR device mounted with the node ID xr. We can obtain the ServiceProvider instance corresponding to this node using the : get_node_provider.

Finally, we invoke the create method of the CRUDService class passing in the service provider instance and our entity, bgp

42provider = odl_provider.get_node_provider('xr')
43crud_service.create(provider, bgp)

Note if there were any errors the above API will raise an exception with the base type YError

Logging

YDK uses common Python logging. See Logging.