diff options
| author | omnom62 <omnom62@outlook.com> | 2026-07-07 20:51:27 +1000 |
|---|---|---|
| committer | omnom62 <omnom62@outlook.com> | 2026-07-07 20:51:27 +1000 |
| commit | 121088ec0b11a8a36259e5afa3be33fc131b5ef2 (patch) | |
| tree | 61d3e5481c96ece28ecce4946a397ad9b33a22c1 /plugins/module_utils | |
| parent | be24a31fb8a4dcdd7c237eee28299cc4a20e4f9c (diff) | |
| download | rest.vyos-121088ec0b11a8a36259e5afa3be33fc131b5ef2.tar.gz rest.vyos-121088ec0b11a8a36259e5afa3be33fc131b5ef2.zip | |
T8323: vyos_vlan module
Diffstat (limited to 'plugins/module_utils')
| -rw-r--r-- | plugins/module_utils/vyos.py | 79 |
1 files changed, 79 insertions, 0 deletions
diff --git a/plugins/module_utils/vyos.py b/plugins/module_utils/vyos.py index 5eda204..fedcc13 100644 --- a/plugins/module_utils/vyos.py +++ b/plugins/module_utils/vyos.py @@ -27,6 +27,85 @@ from ansible_collections.vyos.rest.plugins.module_utils.vyos_rest import ( ) +# --------------------------------------------------------------------------- +# Dynamic config utilities +# --------------------------------------------------------------------------- + + +def _kebab_to_snake(s): + """Convert kebab-case string to snake_case.""" + return s.replace("-", "_") + + +def _snake_to_kebab(s): + """Convert snake_case string to kebab-case.""" + return s.replace("_", "-") + + +def normalize(raw): + """Recursively normalize an API response dict to snake_case keys.""" + if isinstance(raw, dict): + return {_kebab_to_snake(k): normalize(v) for k, v in raw.items()} + if isinstance(raw, list): + return [normalize(v) for v in raw] + return raw + + +def denormalize_path(path): + """Convert a snake_case path list to kebab-case for the API.""" + return [_snake_to_kebab(p) for p in path] + + +def _diff_value(want_val, have_val, path, cmds, delete_missing): + if isinstance(want_val, dict): + if not want_val: + if not have_val: + cmds.append(("set", denormalize_path(path))) + else: + have_dict = have_val if isinstance(have_val, dict) else {} + _diff_dict(want_val, have_dict, path, cmds, delete_missing) + elif isinstance(want_val, list): + have_set = set(have_val) if isinstance(have_val, list) else set() + for item in want_val: + if item not in have_set: + cmds.append(("set", denormalize_path(path + [str(item)]))) + if delete_missing: + want_set = set(str(i) for i in want_val) + for item in have_val or []: + if str(item) not in want_set: + cmds.append(("delete", denormalize_path(path + [str(item)]))) + else: + if want_val != have_val: + cmds.append(("set", denormalize_path(path + [str(want_val)]))) + + +def _diff_dict(want, have, path, cmds, delete_missing): + for key, want_val in want.items(): + _diff_value(want_val, have.get(key), path + [key], cmds, delete_missing) + if delete_missing: + for key in have: + if key not in want: + cmds.append(("delete", denormalize_path(path + [key]))) + + +def diff_configs(want, have, base_path, delete_missing=False): + """Diff two normalized config dicts and return API command tuples. + + Args: + want (dict): Desired configuration (snake_case keys). + have (dict): Current configuration (snake_case keys). + base_path (list): Base API path for commands. + delete_missing (bool): Generate delete commands for keys in + ``have`` absent from ``want``. + + Returns: + list: Tuples of ``("set", path)`` or ``("delete", path)``. + """ + cmds = [] + _diff_dict(want, have, base_path, cmds, delete_missing) + return cmds + + class VyOSModule: """Thin wrapper around VyOSRestClient for resource modules. |
