Commit b9d8d474 authored by Pedro Duarte's avatar Pedro Duarte
Browse files

skip unadvertised gnmi models

parent 4baa91ce
Loading
Loading
Loading
Loading
+12 −1
Original line number Diff line number Diff line
@@ -46,6 +46,7 @@ class GnmiSessionHandler:
        self._subscriptions = Subscriptions()
        self._in_subscriptions = queue.Queue()
        self._out_samples = queue.Queue()
        self._capabilities : Dict[str, Any] = {}

    def __del__(self) -> None:
        self._logger.info('Destroying YangValidator...')
@@ -69,7 +70,7 @@ class GnmiSessionHandler:
        with self._lock:
            self._channel = get_grpc_channel(self._address, self._port, self._use_tls, self._logger)
            self._stub = gNMIStub(self._channel)
            check_capabilities(self._stub, self._username, self._password, timeout=120)
            self._capabilities = check_capabilities(self._stub, self._username, self._password, timeout=120)
            self._monit_thread = MonitoringThread(
                self._stub, self._logger, self._settings, self._in_subscriptions, self._out_samples)
            self._monit_thread.start()
@@ -93,6 +94,7 @@ class GnmiSessionHandler:
        get_request.type = GetRequest.DataType.ALL
        get_request.encoding = Encoding.Value(self._encoding) if self._encoding else Encoding.JSON_IETF
        #get_request.use_models.add() # kept empty: return for all models supported
        supported_models = self._capabilities.get('supported_models', set())
        for i,resource_key in enumerate(resource_keys):
            str_resource_name = 'resource_key[#{:d}]'.format(i)
            try:
@@ -100,6 +102,10 @@ class GnmiSessionHandler:
                self._logger.debug('[GnmiSessionHandler:get] resource_key = {:s}'.format(str(resource_key)))
                str_path = get_path(resource_key)
                self._logger.debug('[GnmiSessionHandler:get] str_path = {:s}'.format(str(str_path)))
                parent_namespace = str_path.split(':')[0].strip('/') if ':' in str_path else None
                if parent_namespace is not None and parent_namespace not in supported_models:
                    self._logger.warning('Skipping path %s because model %s is not advertised', str_path, parent_namespace)
                    continue
                get_request.path.append(path_from_string(str_path))
            except Exception as e: # pylint: disable=broad-except
                MSG = 'Exception parsing {:s}: {:s}'
@@ -111,6 +117,11 @@ class GnmiSessionHandler:
        if len(parsing_results) > 0:
            return parsing_results

        # If no valid paths were added (e.g., all filtered by unsupported models), skip the Get call
        if len(get_request.path) == 0:
            self._logger.warning('No GET paths requested after capability filtering; returning empty result set')
            return []

        metadata = [('username', self._username), ('password', self._password)]
        timeout = None # GNMI_SUBSCRIPTION_TIMEOUT = int(sampling_duration)
        get_reply = self._stub.Get(get_request, metadata=metadata, timeout=timeout)
+13 −7
Original line number Diff line number Diff line
@@ -12,14 +12,14 @@
# See the License for the specific language governing permissions and
# limitations under the License.

from typing import Optional, Set, Union
from typing import Any, Dict, Optional
from common.tools.grpc.Tools import grpc_message_to_json
from ..gnmi.gnmi_pb2 import CapabilityRequest   # pylint: disable=no-name-in-module
from ..gnmi.gnmi_pb2_grpc import gNMIStub

def check_capabilities(
    stub : gNMIStub, username : str, password : str, timeout : Optional[int] = None
) -> Set[Union[str, int]]:
) -> Dict[str, Any]:
    metadata = [('username', username), ('password', password)]
    req = CapabilityRequest()
    reply = stub.Capabilities(req, metadata=metadata, timeout=timeout)
@@ -30,11 +30,11 @@ def check_capabilities(
    if gnmi_version is None or gnmi_version != '0.7.0':
        raise Exception('Unsupported gNMI version: {:s}'.format(str(gnmi_version)))

    #supported_models = {
    #    supported_model['name']: supported_model['version']
    #    for supported_model in data.get('supported_models', [])
    #}
    # TODO: check supported models and versions
    supported_models = {
        supported_model.get('name')
        for supported_model in data.get('supported_models', [])
        if isinstance(supported_model, dict) and 'name' in supported_model
    }

    supported_encodings = {
        supported_encoding
@@ -47,3 +47,9 @@ def check_capabilities(
    if len({'JSON_IETF', 'PROTO'}.intersection(supported_encodings)) == 0:
        # pylint: disable=broad-exception-raised
        raise Exception('JSON_IETF or PROTO encodings not supported')

    return {
        'gNMI_version': gnmi_version,
        'supported_models': supported_models,
        'supported_encodings': supported_encodings,
    }