summaryrefslogtreecommitdiff
path: root/ncserver/base/modman.py
diff options
context:
space:
mode:
authorA. Wilcox <AWilcox@Wilcox-Tech.com>2020-09-09 00:30:22 -0500
committerA. Wilcox <AWilcox@Wilcox-Tech.com>2020-09-09 00:30:27 -0500
commit476926d55163574389ccb7a06ee86992cba6f4ff (patch)
tree7e5698a4b708e95e6565625556d761ba651846fb /ncserver/base/modman.py
parent34b2a9526408fa8c5cfea99ead5a48e88120fbfd (diff)
downloadnetconfapk-476926d55163574389ccb7a06ee86992cba6f4ff.tar.gz
netconfapk-476926d55163574389ccb7a06ee86992cba6f4ff.tar.bz2
netconfapk-476926d55163574389ccb7a06ee86992cba6f4ff.tar.xz
netconfapk-476926d55163574389ccb7a06ee86992cba6f4ff.zip
Add proper capabilities output
This includes support for tracking features in modules via optional M_FEATURES list.
Diffstat (limited to 'ncserver/base/modman.py')
-rw-r--r--ncserver/base/modman.py51
1 files changed, 41 insertions, 10 deletions
diff --git a/ncserver/base/modman.py b/ncserver/base/modman.py
index 2c24788..a3b8aad 100644
--- a/ncserver/base/modman.py
+++ b/ncserver/base/modman.py
@@ -176,18 +176,51 @@ class ModuleManager:
MODULE_SET_CHANGE_SIGNAL.call(name, mod)
return name
+ def capabilities(self) -> list:
+ """Determine the NETCONF capabilities for this server."""
+ capabs = []
+
+ def _cap_for_module(module):
+ base = '{ns}?module={mod}&revision={rev}'.format(
+ ns=module.M_NS, mod=module.M_NAME, rev=module.M_REVISION
+ )
+ if getattr(module, 'M_FEATURES', None) is not None:
+ return '{base}&features={feat}'.format(
+ base=base, feat=','.join(module.M_FEATURES)
+ )
+ return base
+
+ def _cap_for_import(imname, improp):
+ name, rev = imname.split('@')
+ return '{ns}?module={mod}&revision={rev}'.format(
+ ns=improp['ns'], mod=name, rev=rev
+ )
+
+ for imdata in self.imports.items():
+ capabs.append(_cap_for_import(*imdata))
+ for module in self.modules.values():
+ capabs.append(_cap_for_module(module))
+ capabs.append('{ns}?revision={rev}&module-set-id={id}'.format(
+ ns='urn:ietf:params:netconf:capability:yang-library:1.0',
+ rev='2019-01-04', id=self._module_set_id()
+ ))
+
+ return capabs
+
def running(self, node):
"""Return running configuration information."""
# ietf-yang-library is state-only.
- def _gen_yang_library(self, node, content_id):
+ def _module_set_id(self):
+ """Retrieve the module set ID for this server."""
+ module_set_id = hashlib.sha256(','.join(self.modules.keys()).encode())
+ return module_set_id.hexdigest()
+
+ def _gen_yang_library(self, node):
"""Generate yanglib:yang-library node.
:param node:
The XML node to append to.
-
- :param content_id:
- The unique Content ID for this library.
"""
lib = util.subelm(node, 'yanglib:yang-library')
modset = util.subelm(lib, 'yanglib:module-set')
@@ -206,20 +239,18 @@ class ModuleManager:
dsnode.append(util.leaf_elm('name', store))
dsnode.append(util.leaf_elm('schema', 'apkschema'))
- lib.append(util.leaf_elm('yanglib:content-id', content_id))
+ lib.append(util.leaf_elm('yanglib:content-id', self._module_set_id()))
return lib
def operational(self, node):
"""Return configuration and device state information."""
- module_set_id = hashlib.sha256(','.join(self.modules.keys()).encode())
- content_id = module_set_id.hexdigest()
-
# NDMA-enabled yang-library node.
- self._gen_yang_library(node, content_id)
+ self._gen_yang_library(node)
# Deprecated modules-state node.
modstate = util.subelm(node, 'yanglib:modules-state')
- modstate.append(util.leaf_elm('yanglib:module-set-id', content_id))
+ modstate.append(util.leaf_elm('yanglib:module-set-id',
+ self._module_set_id()))
for module in self.modules.values():
modnode = _gen_modnode(modstate, module)
modnode.append(util.leaf_elm('yanglib:conformance-type',