From e5e4aba47e53e7bea9046e21fa00cef69de69183 Mon Sep 17 00:00:00 2001 From: Daan Date: Thu, 26 Dec 2024 00:14:08 +0100 Subject: [PATCH] Progress on rewrite. --- meshbook/meshbook.py | 16 ------- meshbook/requirements.txt | 8 ++-- meshbook/rewrite.py | 95 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 99 insertions(+), 20 deletions(-) create mode 100644 meshbook/rewrite.py diff --git a/meshbook/meshbook.py b/meshbook/meshbook.py index 7f86b6b..73c8225 100644 --- a/meshbook/meshbook.py +++ b/meshbook/meshbook.py @@ -49,23 +49,7 @@ class MeshbookUtilities: return ids - @staticmethod - def load_config(conffile: str = None, segment: str = 'meshcentral-service') -> ConfigParser: - """Load and return the configuration from a file.""" - conffile = conffile or './api.conf' - if not os.path.exists(conffile): - raise ScriptEndTrigger(f'Missing config file {conffile}. Provide an alternative path.') - try: - my_config = ConfigParser() - my_config.read(conffile) - except Exception as err: - raise ScriptEndTrigger(f'Error reading config file {conffile}: {err}') - - if segment not in my_config: - raise ScriptEndTrigger(f'Segment "{segment}" not found in config file {conffile}.') - - return my_config[segment] @staticmethod def read_yaml(file_path: str) -> dict: diff --git a/meshbook/requirements.txt b/meshbook/requirements.txt index 080bbb6..1e9b527 100644 --- a/meshbook/requirements.txt +++ b/meshbook/requirements.txt @@ -1,4 +1,4 @@ -asyncio==3.4.3 -configparser==7.1.0 -pyyaml==6.0.2 -websockets==14.1 \ No newline at end of file +asyncio +configparser +pyyaml +libmeshctrl \ No newline at end of file diff --git a/meshbook/rewrite.py b/meshbook/rewrite.py new file mode 100644 index 0000000..39adb4e --- /dev/null +++ b/meshbook/rewrite.py @@ -0,0 +1,95 @@ +#!/bin/python3 + +import argparse +import asyncio +from base64 import b64encode +from configparser import ConfigParser +import json +import math +import meshctrl +import os +import yaml + +class ScriptEndTrigger(Exception): + """Custom Exception to handle script termination events.""" + pass + +def load_config(conffile: str = None, segment: str = 'meshcentral-account') -> ConfigParser: + conffile = conffile or './api.conf' + + if not os.path.exists(conffile): + raise ScriptEndTrigger(f'Missing config file {conffile}. Provide an alternative path.') + + config = ConfigParser() + try: + config.read(conffile) + except Exception as err: + raise ConfigError(f"Error reading configuration file '{conffile}': {err}") + + if segment not in config: + raise ScriptEndTrigger(f'Segment "{segment}" not found in config file {conffile}.') + + return config[segment] + +class meshbook(): + @staticmethod + def compile_book(pb_path) -> dict: + playbook = meshbook.read_yaml(pb_path) + playbook = meshbook.replace_placeholders(playbook) + return playbook + + @staticmethod + def read_yaml(file_path: str) -> dict: + with open(file_path, 'r') as file: + return yaml.safe_load(file) + + @staticmethod + def replace_placeholders(playbook: dict) -> dict: + variables = {var["name"]: var["value"] for var in playbook.get("variables", [])} + + for task in playbook.get("tasks", []): + command = task.get("command", "") + for var_name, var_value in variables.items(): + placeholder = f"{{{{ {var_name} }}}}" # Create the placeholder string like "{{ host1 }}" + command = command.replace(placeholder, var_value) + task["command"] = command + return playbook + +async def run_book(creds): + print(creds) + +async def main(): + parser = argparse.ArgumentParser(description="Process command-line arguments") + parser.add_argument("-pb", "--playbook", type=str, help="Path to the playbook file.", required=True) + + parser.add_argument("--conf", type=str, help="Path for the API configuration file (default: ./api.conf).") + parser.add_argument("--nojson", action="store_true", help="Makes the program not output the JSON response data.") + parser.add_argument("-s", "--silent", action="store_true", help="Suppress terminal output.") + parser.add_argument("-i", "--information", action="store_true", help="Add the calculations and other informational data to the output.") + + args = parser.parse_args() + + try: + credentials = load_config(args.conf) + playbook = meshbook.compile_book(args.playbook) + + session = meshctrl.Session( + credentials['websocket_url'], + user=credentials['username'], + password=credentials['password'] + ) + await session.initialized.wait() + raw_device_list = await session.list_devices(timeout=10) + device_list = raw_device_list + + print(device_list) + + await session.close() + + except ScriptEndTrigger as e: + if not args.silent or args.information: + print(e) + + +if __name__ == "__main__": + asyncio.run(main())