-
Notifications
You must be signed in to change notification settings - Fork 25
Description
I am experiencing an issue with providing operational data for a mounted module (using ietf-yang-schema-mount).
I constructed a minimal example below to demonstrate the problem:
My goal is to write a plugin for module minimal with the following definition:
module minimal {
yang-version 1.1;
namespace "urn:minimal";
prefix "min";
import ietf-yang-schema-mount {
prefix yangmnt;
}
container wrap {
container root {
yangmnt:mount-point "root";
}
leaf test {
type string;
config false;
}
}
}As you can see, the module contains a mount point within a nested container (wrap/root).
Using the program below, I am able to write and read back configuration data to an arbitrary module mounted at label root.
I can also see the changes made to modules in my callback function module_change_cb (tested with ietf-system).
However, if my callback (oper_data_cb) for the operational data of module minimal is called and I return operational data for let's say ietf-interfaces within the mount point, then its is skipped as an "unknown element" and I cannot see it in the response that I receive.
Please find below the program I used to produce the error as well as exemplary calls for netopeer2-cli and console logs.
import logging
import sys
import signal
import sysrepo
MINIMAL_NAME = "minimal"
SCHEMA_MOUNT_NAME = "ietf-yang-schema-mount"
def oper_data_schema_mount_cb(xpath, private_data):
print(f"{SCHEMA_MOUNT_NAME}: oper_data_cb called for", xpath)
return {
"schema-mounts": {
"mount-point": [
{
# enable mount point "root" in module "minimal"
"module": "minimal",
"label": "root",
"shared-schema": {},
},
],
}
}
def module_change_cb(event, req_id, changes, private_data):
print(f"{MINIMAL_NAME}: module_change_cb called with event '{event}'")
if event in ("update", "change"):
print(changes)
def oper_data_cb(xpath, private_data):
print(f"\n{MINIMAL_NAME}: oper_data_cb called for", xpath)
return {
"minimal:wrap": {
"root": {
# should not be ignored
"ietf-interfaces:interfaces-state": {
"interface": [
{
"name": "lo",
"type": "iana-if-type:softwareLoopback",
}
]
},
},
"foo": "bar", # should be ignored
"test": "test-string", # should not be ignored
}
}
def init_plugin(conn):
session = conn.start_session()
session.subscribe_oper_data_request(SCHEMA_MOUNT_NAME, f"/{SCHEMA_MOUNT_NAME}:schema-mounts", oper_data_schema_mount_cb)
# extra session for module with mount point
session_mp = conn.start_session()
session_mp.subscribe_module_change(MINIMAL_NAME, None, module_change_cb)
session_mp.subscribe_oper_data_request(MINIMAL_NAME, f"/{MINIMAL_NAME}:wrap", oper_data_cb)
return [session, session_mp]
if __name__ == "__main__":
logging.basicConfig(stream=sys.stdout, level=logging.DEBUG)
conn = sysrepo.SysrepoConnection()
sessions = init_plugin(conn)
def signal_handler(signum, frame):
for session in sessions:
session.stop()
conn.disconnect()
print("sysrepo connection closed")
sys.exit(0)
signal.signal(signal.SIGINT, signal_handler)
signal.signal(signal.SIGTERM, signal_handler)
print("setup done")
signal.pause()Get-requests to retrieve operational data using netopeer2-cli:
> get --filter-xpath /minimal:wrap/root/ietf-interfaces:interfaces-state
DATA
<data xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"/>
> get --filter-xpath /minimal:wrap
DATA
<data xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
<wrap xmlns="urn:minimal">
<test>test-string</test>
</wrap>
</data>
> get --filter-xpath /minimal:wrap/root
DATA
<data xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
</data>Program output for the three requests above:
minimal: oper_data_cb called for /minimal:wrap/root/ietf-interfaces:interfaces-state
WARNING:libyang.data:/minimal:wrap/root: skipping unknown element 'ietf-interfaces:interfaces-state'
WARNING:libyang.data:/minimal:wrap: skipping unknown element 'foo'
minimal: oper_data_cb called for /minimal:wrap
WARNING:libyang.data:/minimal:wrap/root: skipping unknown element 'ietf-interfaces:interfaces-state'
WARNING:libyang.data:/minimal:wrap: skipping unknown element 'foo'
minimal: oper_data_cb called for /minimal:wrap/root
WARNING:libyang.data:/minimal:wrap/root: skipping unknown element 'ietf-interfaces:interfaces-state'
WARNING:libyang.data:/minimal:wrap: skipping unknown element 'foo'I tried to follow my data through the sysrepo-python code to see where my mount point operational information is getting lost and it seems that the function Module.parse_data_dict of libyang-python ignores the contents of the mount point.
It is called here in the operational data callback handler of syrepo-python.
I am unsure whether this is an unwanted behavior of libyang-python, whether sysrepo-python should use a different function there or whether I have to set up something else before.
Regards