Skip to content

Commit

Permalink
north/gnmi: add support for Subscribe RPC
Browse files Browse the repository at this point in the history
This change adds a support for the Subscribe RPC to the gNMI server.
It uses the goldstone-telemetry model to provide streaming telemetry
updates to an external telemetry collector. It allows users to
synchronize the states between a device and a controller/collector.
  • Loading branch information
noguchiko committed Nov 11, 2022
1 parent 5696678 commit 2fe8417
Show file tree
Hide file tree
Showing 8 changed files with 2,637 additions and 43 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,6 @@ unittest-netlink:
unittest-gnmi:
$(MAKE) clean-sysrepo
cd src/north/gnmi && make proto
scripts/gs-yang.py --install xlate-oc --search-dirs yang sm/openconfig
scripts/gs-yang.py --install xlate-oc system-telemetry --search-dirs yang sm/openconfig
cd src/north/gnmi && PYTHONPATH=../../lib python -m unittest -v -f $(TEST_CASE)
cd src/north/gnmi && make clean
8 changes: 8 additions & 0 deletions src/lib/goldstone/lib/connector/sysrepo.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import sysrepo
import libyang
import logging
import inspect

logger = logging.getLogger(__name__)

Expand Down Expand Up @@ -127,6 +128,13 @@ def send_notification(self, name: str, notification: dict):
logger.debug(f"sending notification {name}: {notification}")
self.session.notification_send(name, notification)

def subscribe_notification(self, xpath, callback):
model = xpath.split("/")[1].split(":")[0]
asyncio_register = inspect.iscoroutinefunction(callback)
self.session.subscribe_notification(
model, xpath, callback, asyncio_register=asyncio_register
)

def subscribe_notifications(self, callback):
f = lambda xpath, notif_type, value, timestamp, priv: callback(
{xpath: value, "eventTime": timestamp}
Expand Down
3 changes: 1 addition & 2 deletions src/north/gnmi/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ The gNMI server supports following gNMI RPCs:
- `Capabilities`
- `Get`
- `Set`
- `Subscribe`

The gNMI server supports limited `Set` transaction. It has following limitations:

Expand All @@ -19,12 +20,10 @@ The gNMI server supports limited `Set` transaction. It has following limitations

Currently, the gNMI server does not yet support following features:

- `Subscribe` RPC
- `replace` operation for `Set` RPC
- `type` specification for `Get` RPC
- Wildcards in a `path` field
- Value encodings other than JSON
- RPC on TLS
- RPC authentication and authorization

## Prerequisites
Expand Down
22 changes: 20 additions & 2 deletions src/north/gnmi/goldstone/north/gnmi/repo/repo.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ def __init__(self, item):


class ApplyFailedError(Exception):
def __init__(self):
super().__init__("Apply changes to the repository failed")
def __init__(self, msg):
super().__init__("Apply changes to the repository failed: {}".format(msg))


class Repository:
Expand Down Expand Up @@ -95,3 +95,21 @@ def get_list_keys(self, path):
ValueError: 'path' has an invalid value.
"""
pass

def subscribe_notification(self, xpath, callback):
"""Subscribe a notification.
Args:
xpath (str): Path to the notification.
callback (func): Callback function to notify.
"""
pass

def exec_rpc(self, xpath, params):
"""Execute an RPC.
Args:
xpath (str): Path to the RPC.
params (dict): RPC parameters.
"""
pass
11 changes: 9 additions & 2 deletions src/north/gnmi/goldstone/north/gnmi/repo/sysrepo.py
Original file line number Diff line number Diff line change
Expand Up @@ -138,8 +138,9 @@ def apply(self):
self._connector.apply()
except ConnectorError as e:
# TODO: can split into detailed exceptions?
logger.error("apply failed. %s", e)
raise ApplyFailedError() from e
msg = f"apply failed. {e}"
logger.error(msg)
raise ApplyFailedError(msg) from e

def discard(self):
self._connector.discard_changes()
Expand All @@ -161,3 +162,9 @@ def get_list_keys(self, path):
for key in node.keys():
keys.append(key.name())
return keys

def subscribe_notification(self, xpath, callback):
self._connector.operational_session.subscribe_notification(xpath, callback)

def exec_rpc(self, xpath, params):
self._connector.operational_session.rpc(xpath, params)
Loading

0 comments on commit 2fe8417

Please sign in to comment.