From 0fb6a466f8fd7a292bb840245da1c13ea1cbe836 Mon Sep 17 00:00:00 2001 From: "A. Wilcox" Date: Fri, 20 Nov 2020 10:54:27 -0600 Subject: NMSA: Add ability to read 'live' values This allows us to have a true picture of the system for the operational datastore, separate from the config datastore. --- doc/network.rst | 12 +++++++++- ncserver/module/nms_ifupdownng.py | 47 ++++++++++++++++++++++++++++++++++----- 2 files changed, 53 insertions(+), 6 deletions(-) diff --git a/doc/network.rst b/doc/network.rst index 37c67b7..7291249 100644 --- a/doc/network.rst +++ b/doc/network.rst @@ -179,7 +179,7 @@ Parameters ---------- For manipulating parameters in the section `Data model definition`_, -three methods exist. +four methods exist. ``get_param(iface, parameter)`` @@ -189,6 +189,16 @@ Retrieve the parameter for the specified interface. If the parameter is not set for the specified interface, ``None`` will be returned. +``curr_param(iface, parameter)`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Retrieve the current, live value for the parameter for the specified +interface. If the parameter is not set for the specified interface, +``None`` will be returned. The value returned from ``curr_param`` may +differ from ``get_param`` if a network administrator has changed the +value externally, or if the system configuration store is malfunctioning. + + ``set_param(iface, parameter, value)`` ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/ncserver/module/nms_ifupdownng.py b/ncserver/module/nms_ifupdownng.py index 1b71051..5a06f47 100644 --- a/ncserver/module/nms_ifupdownng.py +++ b/ncserver/module/nms_ifupdownng.py @@ -12,6 +12,7 @@ SPDX-License-Identifier: NCSA import ipaddress import logging +import pathlib import socket import subprocess import yaml @@ -162,6 +163,11 @@ def _remove_one(iface: str, key: str): return +def _iface_path(iface: str) -> pathlib.Path: + """Retrieve the system device path for the specified interface.""" + return pathlib.Path("/sys/class/net/" + iface) + + ############################# # P A R A M E T E R S # ############################# @@ -187,6 +193,16 @@ def get_auto(iface: str, _): return _find_one(iface, 'auto') +def live_enabled(iface: str, _): + """Determine if the interface is enabled or not.""" + statepath = _iface_path(iface) / "operstate" + if statepath.exists(): + with open(statepath, 'r') as state_file: + return state_file.read().strip() == "up" + + return False + + def set_auto(iface: str, _, value: bool): """Set the auto flag for the specified interface.""" _replace_one(iface, 'auto', value) @@ -198,9 +214,9 @@ def unset_auto(iface: str, _): _PARAMETERS = { - # "name": (getter, setter, unsetter) - "description": (get_desc, set_desc, unset_desc), - "enabled": (get_auto, set_auto, unset_auto) + # "name": (getter, live getter, setter, unsetter) + "description": (get_desc, get_desc, set_desc, unset_desc), + "enabled": (get_auto, live_enabled, set_auto, unset_auto) } """Describes all supported parameters and their methods.""" @@ -267,6 +283,27 @@ def get_param(iface: str, parameter: str): return _PARAMETERS[parameter][0](iface, parameter) +def curr_param(iface: str, parameter: str): + """Retrieve the current parameter value for the specified interface.""" + _load_config() + + # XXX how do we want to handle interfaces that are missing from /e/n/i + # but are still present in the system? + if iface not in _CONFIG.keys(): + LOGGER.warning( + _("requested parameter %s for non-existent interface %s"), + parameter, iface + ) + return None + + if parameter not in _PARAMETERS.keys(): + LOGGER.error(_("requested non-existent parameter %s for interface %s"), + parameter, iface) + return None + + return _PARAMETERS[parameter][1](iface, parameter) + + def set_param(iface: str, parameter: str, value): """Set the parameter for the specified interface.""" _load_config() @@ -282,7 +319,7 @@ def set_param(iface: str, parameter: str, value): if iface not in _CONFIG.keys(): _CONFIG[iface] = list() - _PARAMETERS[parameter][1](iface, parameter, value) + _PARAMETERS[parameter][2](iface, parameter, value) def unset_param(iface: str, parameter: str): @@ -303,7 +340,7 @@ def unset_param(iface: str, parameter: str): ) return - _PARAMETERS[parameter][2](iface, parameter) + _PARAMETERS[parameter][3](iface, parameter) def list_addresses(iface: str) -> list: -- cgit v1.2.3-70-g09d2