diff options
author | Daniil Baturin <daniil@vyos.io> | 2022-11-18 13:42:08 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-11-18 13:42:08 +0000 |
commit | 97056cad18664bea06310d59e8a769add077f6d0 (patch) | |
tree | 7fe5078144c074a447aec93831c8ec493f436ecb /python | |
parent | 0094bdfd15b4732a4be417f1777e903a41a8a954 (diff) | |
parent | b8bda7c8d54fb500716c78ca39107e33988311ea (diff) | |
download | vyos-1x-97056cad18664bea06310d59e8a769add077f6d0.tar.gz vyos-1x-97056cad18664bea06310d59e8a769add077f6d0.zip |
Merge pull request #1662 from jestabro/config-script-dependency
firewall: T4821: correct calling of conf_mode script dependencies
Diffstat (limited to 'python')
-rw-r--r-- | python/vyos/configdep.py | 65 | ||||
-rw-r--r-- | python/vyos/util.py | 8 |
2 files changed, 73 insertions, 0 deletions
diff --git a/python/vyos/configdep.py b/python/vyos/configdep.py new file mode 100644 index 000000000..e6b82ca93 --- /dev/null +++ b/python/vyos/configdep.py @@ -0,0 +1,65 @@ +# Copyright 2022 VyOS maintainers and contributors <maintainers@vyos.io> +# +# 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 <http://www.gnu.org/licenses/>. + +import os +from inspect import stack + +from vyos.util import load_as_module + +dependents = {} + +def canon_name(name: str) -> str: + return os.path.splitext(name)[0].replace('-', '_') + +def canon_name_of_path(path: str) -> str: + script = os.path.basename(path) + return canon_name(script) + +def caller_name() -> str: + return stack()[-1].filename + +def run_config_mode_script(script: str, config): + from vyos.defaults import directories + + path = os.path.join(directories['conf_mode'], script) + name = canon_name(script) + mod = load_as_module(name, path) + + config.set_level([]) + try: + c = mod.get_config(config) + mod.verify(c) + mod.generate(c) + mod.apply(c) + except (VyOSError, ConfigError) as e: + raise ConfigError(repr(e)) + +def def_closure(script: str, config): + def func_impl(): + run_config_mode_script(script, config) + return func_impl + +def set_dependent(target: str, config): + k = canon_name_of_path(caller_name()) + l = dependents.setdefault(k, []) + func = def_closure(target, config) + l.append(func) + +def call_dependents(): + k = canon_name_of_path(caller_name()) + l = dependents.get(k, []) + while l: + f = l.pop(0) + f() diff --git a/python/vyos/util.py b/python/vyos/util.py index a80584c5a..9ebe69b6c 100644 --- a/python/vyos/util.py +++ b/python/vyos/util.py @@ -1143,3 +1143,11 @@ def camel_to_snake_case(name: str) -> str: pattern = r'\d+|[A-Z]?[a-z]+|\W|[A-Z]{2,}(?=[A-Z][a-z]|\d|\W|$)' words = re.findall(pattern, name) return '_'.join(map(str.lower, words)) + +def load_as_module(name: str, path: str): + import importlib.util + + spec = importlib.util.spec_from_file_location(name, path) + mod = importlib.util.module_from_spec(spec) + spec.loader.exec_module(mod) + return mod |