How do I use the Path API?
Table of Contents
The Path API (part of the YDK core) is a generic API which can be used to create and access YANG data nodes without having to use the model bundle APIs (for example, openconfig). The ydk
python package is sufficient to use the Path API. Apps can be written using xpath-like path expressions as illustrated below.
How do I create a basic configuration?
An example for using Path API to create a bgp
configuration using the openconfig-bgp
model in conjunction with the standard edit-config RPC is shown below:
1from ydk.path import NetconfSession
2from ydk.path import Codec
3from ydk.types import EncodingFormat
4
5# Create a NetconfSession instance to connect to the device
6session = NetconfSession('10.0.0.1', 'admin', 'admin')
7
8# Get the root schema node
9root_schema = session.get_root_schema()
10
11# Create the bgp configuration
12bgp = root_schema.create_datanode("openconfig-bgp:bgp", "")
13bgp.create_datanode("global/config/as", "65172")
14
15# Create a list instance of afi-safi. Note how the key (afi-safi-name) of the list is specified
16l3vpn_ipv4_unicast = bgp.create_datanode("global/afi-safis/afi-safi[afi-safi-name='openconfig-bgp-types:L3VPN_IPV4_UNICAST']", "")
17l3vpn_ipv4_unicast.create_datanode("config/afi-safi-name", "openconfig-bgp-types:L3VPN_IPV4_UNICAST")
18l3vpn_ipv4_unicast.create_datanode("config/enabled","true")
19
20# Create a list instance of neighbor. Note how the key (neighbor-address) of the list is specified
21neighbor = bgp.create_datanode("neighbors/neighbor[neighbor-address='172.16.255.2']", "")
22neighbor.create_datanode("config/neighbor-address", "172.16.255.2")
23neighbor.create_datanode("config/peer-as","65172")
24neighbor_af = neighbor.create_datanode("afi-safis/afi-safi[afi-safi-name='openconfig-bgp-types:L3VPN_IPV4_UNICAST']", "")
25neighbor_af.create_datanode("config/afi-safi-name" , "openconfig-bgp-types:L3VPN_IPV4_UNICAST")
26neighbor_af.create_datanode("config/enabled","true")
27
28codec_service = Codec()
29
30# Encode the bgp object to JSON string to examine the data
31json = codec_service.encode(bgp, EncodingFormat.JSON, True)
32print(json)
33
34# Encode the bgp object to XML string
35xml = codec_service.encode(bgp, EncodingFormat.XML, True)
36
37# Create the 'ietf-netconf:edit-config' RPC object
38edit_rpc = root_schema.create_rpc('ietf-netconf:edit-config')
39
40# Set the target to the candidate datastore
41edit_rpc.get_input_node().create_datanode('target/candidate')
42# Set the xml string to the 'config' field
43edit_rpc.get_input_node().create_datanode('config', xml)
44
45# Invoke the RPC
46edit_rpc(session)
How do I work with different RPCs?
To invoke the get-schema RPC to download the Cisco-IOS-XR-aaa-lib-cfg.yang
yang model from a netconf server using the path API, the below approach can be used.
1from ydk.path import NetconfSession
2from ydk.path import Codec
3from ydk.types import EncodingFormat
4
5# Create a NetconfSession instance to connect to the device
6netconf_session = NetconfSession(address='10.0.0.1' , username='admin', password='admin')
7
8c = Codec()
9
10# Get the root schema node
11root = netconf_session.get_root_schema()
12
13# Create the 'ietf-netconf-monitoring:get-schema' RPC object
14get_schema = root.create_rpc('ietf-netconf-monitoring:get-schema')
15
16# Set the 'identifier' to 'Cisco-IOS-XR-aaa-lib-cfg'
17get_schema.get_input_node().create_datanode('identifier','Cisco-IOS-XR-aaa-lib-cfg')
18
19# Invoke the RPC
20output_data = get_schema(netconf_session)
21
22# Encode the RPC reply to XML
23output_xml = c.encode(output_data, EncodingFormat.XML, True)
24
25# Print the XML
26print(output_xml)
How do I work with YANG 1.1 actions?
Path API can be used to work with a action
as defined in the YANG 1.1 standard in RFC 7950.
Consider the below snippet from an example action-config.yang
model compliant with the YANG 1.1 standard.
container data {
action action-node {
input {
leaf ip-test {
type string;
}
}
output {
leaf op-test {
type string;
}
}
}
}
The below script can be used to work with the above model
1from ydk.path import NetconfSession
2from ydk.path import Codec
3from ydk.types import EncodingFormat
4
5# Create a NetconfSession instance to connect to the device which supports the YANG 1.1 action-config model
6session = NetconfSession('10.0.0.1', 'admin', 'admin')
7
8# Get the root schema node
9root_schema = session.get_root_schema()
10
11# Create and populate the action data
12data = self.root_schema.create_datanode("action-config:data", "")
13action = action.create_action("action-node")
14action.create_datanode("ip-test", "xyz")
15
16# Invoke the data object containing the action on the session
17data(session)
What is the Path syntax?
Full XPath notation is supported for find operations on DataNode
(s). This XPath conforms to the YANG specification (RFC 6020 section 6.4). Some useful examples:
Get
list
instance withkey1
of value1
andkey2
of value2
(this can return morelist
instances if there are more keys thankey1
andkey2
)
/module-name:container/list[key1='1'][key2='2']
Get
leaf-list
instance with the valueval
/module-name:container/leaf-list[.='val']
Get
aug-leaf
, which was added tomodule-name
from an augment moduleaugment-module
/module-name:container/container2/augment-module:aug-cont/aug-leaf
A very small subset of this full XPath is recognized by DataNode::create
. Basically, only a relative or absolute path can be specified to identify a new data node. However, lists must be identified by all their keys and created with all of them, so for those cases predicates are allowed. Predicates must be ordered the way the keys are ordered and all the keys must be specified. Every predicate includes a single key with its value. Optionally, leaves and leaf-lists can have predicates specifying their value in the path itself. All these paths are valid XPath expressions. Example: (Relative to Root Data or ydk.path.RootSchemaNode
)
ietf-yang-library:modules-state/module[name='ietf-yang-library'][revision='']/conformance[.='implement']
Almost the same XPath is accepted by SchemaNode
methods. The difference is that it is not used on data, but schema, which means there are no key values and only one node matches one path. In effect, lists do not have to have any predicates. If they do, they do not need to have all the keys specified and if values are included, they are ignored. Nevertheless, any such expression is still a valid XPath, but can return more nodes if executed on a data tree. Examples (all returning the same node):
ietf-yang-library:modules-state/module/submodules
ietf-yang-library:modules-state/module[name]/submodules
ietf-yang-library:modules-state/module[name][revision]/submodules
ietf-yang-library:modules-state/module[name='ietf-yang-library'][revision]/submodules
Note
In all cases the node’s prefix is specified as the name of the appropriate YANG schema. Any node can be prefixed by the module name. However, if the prefix is omitted, the module name is inherited from the previous (parent) node. It means, that the first node in the path is always supposed to have a prefix.