From 6efc149e3246919b39cc831c8fa5110c19c68ace Mon Sep 17 00:00:00 2001 From: John Estabrook Date: Mon, 7 Apr 2025 15:40:46 -0500 Subject: T7321: add VyconfSession class and methods Encapsulation of standard config session functions, to replace legacy versions in configsession.py. --- python/vyos/vyconf_session.py | 99 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 99 insertions(+) create mode 100644 python/vyos/vyconf_session.py (limited to 'python/vyos/vyconf_session.py') diff --git a/python/vyos/vyconf_session.py b/python/vyos/vyconf_session.py new file mode 100644 index 000000000..cff3769fb --- /dev/null +++ b/python/vyos/vyconf_session.py @@ -0,0 +1,99 @@ +# Copyright 2025 VyOS maintainers and contributors +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this library. If not, see . +# +# + +import tempfile +import shutil + +from vyos.proto import vyconf_client +from vyos.migrate import ConfigMigrate +from vyos.migrate import ConfigMigrateError +from vyos.component_version import append_system_version + + +def output(o): + out = '' + for res in (o.output, o.error, o.warning): + if res is not None: + out = out + res + return out + + +class VyconfSession: + def __init__(self, token: str = None): + if token is None: + out = vyconf_client.send_request('setup_session') + self.__token = out.output + else: + self.__token = token + + def set(self, path: list[str]) -> tuple[str, int]: + out = vyconf_client.send_request('set', token=self.__token, path=path) + return output(out), out.status + + def delete(self, path: list[str]) -> tuple[str, int]: + out = vyconf_client.send_request('delete', token=self.__token, path=path) + return output(out), out.status + + def commit(self) -> tuple[str, int]: + out = vyconf_client.send_request('commit', token=self.__token) + return output(out), out.status + + def discard(self) -> tuple[str, int]: + out = vyconf_client.send_request('discard', token=self.__token) + return output(out), out.status + + def session_changed(self) -> bool: + out = vyconf_client.send_request('session_changed', token=self.__token) + return not bool(out.status) + + def load_config(self, file: str, migrate: bool = False) -> tuple[str, int]: + # pylint: disable=consider-using-with + if migrate: + tmp = tempfile.NamedTemporaryFile() + shutil.copy2(file, tmp.name) + config_migrate = ConfigMigrate(tmp.name) + try: + config_migrate.run() + except ConfigMigrateError as e: + tmp.close() + return repr(e), 1 + file = tmp.name + else: + tmp = '' + + out = vyconf_client.send_request('load', token=self.__token, location=file) + if tmp: + tmp.close() + + return output(out), out.status + + def save_config(self, file: str, append_version: bool = False) -> tuple[str, int]: + out = vyconf_client.send_request('save', token=self.__token, location=file) + if append_version: + append_system_version(file) + return output(out), out.status + + def show_config(self, path: list[str] = None) -> tuple[str, int]: + if path is None: + path = [] + out = vyconf_client.send_request('show_config', token=self.__token, path=path) + return output(out), out.status + + def __del__(self): + out = vyconf_client.send_request('teardown', token=self.__token) + if out.status: + print(f'Could not tear down session {self.__token}: {output(out)}') -- cgit v1.2.3 From 957eb2d49edeca10dadfd0204bdf54edf7c09601 Mon Sep 17 00:00:00 2001 From: John Estabrook Date: Fri, 11 Apr 2025 12:23:17 -0500 Subject: T7321: add decorator to raise named exception on error --- python/vyos/vyconf_session.py | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) (limited to 'python/vyos/vyconf_session.py') diff --git a/python/vyos/vyconf_session.py b/python/vyos/vyconf_session.py index cff3769fb..506095625 100644 --- a/python/vyos/vyconf_session.py +++ b/python/vyos/vyconf_session.py @@ -17,6 +17,8 @@ import tempfile import shutil +from functools import wraps +from typing import Type from vyos.proto import vyconf_client from vyos.migrate import ConfigMigrate @@ -33,25 +35,44 @@ def output(o): class VyconfSession: - def __init__(self, token: str = None): + def __init__(self, token: str = None, on_error: Type[Exception] = None): if token is None: out = vyconf_client.send_request('setup_session') self.__token = out.output else: self.__token = token + self.on_error = on_error + + @staticmethod + def raise_exception(f): + @wraps(f) + def wrapped(self, *args, **kwargs): + if self.on_error is None: + return f(self, *args, **kwargs) + o, e = f(self, *args, **kwargs) + if e: + raise self.on_error(o) + return o, e + + return wrapped + + @raise_exception def set(self, path: list[str]) -> tuple[str, int]: out = vyconf_client.send_request('set', token=self.__token, path=path) return output(out), out.status + @raise_exception def delete(self, path: list[str]) -> tuple[str, int]: out = vyconf_client.send_request('delete', token=self.__token, path=path) return output(out), out.status + @raise_exception def commit(self) -> tuple[str, int]: out = vyconf_client.send_request('commit', token=self.__token) return output(out), out.status + @raise_exception def discard(self) -> tuple[str, int]: out = vyconf_client.send_request('discard', token=self.__token) return output(out), out.status @@ -60,6 +81,7 @@ class VyconfSession: out = vyconf_client.send_request('session_changed', token=self.__token) return not bool(out.status) + @raise_exception def load_config(self, file: str, migrate: bool = False) -> tuple[str, int]: # pylint: disable=consider-using-with if migrate: @@ -81,12 +103,14 @@ class VyconfSession: return output(out), out.status + @raise_exception def save_config(self, file: str, append_version: bool = False) -> tuple[str, int]: out = vyconf_client.send_request('save', token=self.__token, location=file) if append_version: append_system_version(file) return output(out), out.status + @raise_exception def show_config(self, path: list[str] = None) -> tuple[str, int]: if path is None: path = [] -- cgit v1.2.3