From 68b63baeac14d590b4a67f43b69633d6e2c4c531 Mon Sep 17 00:00:00 2001 From: fluzzi Date: Thu, 6 Apr 2023 18:47:29 -0300 Subject: [PATCH] starting api --- connpy/api.py | 83 +++++++++++++++++++++++++++++++++++++++++++++++ connpy/connapp.py | 24 +++++++++++++- 2 files changed, 106 insertions(+), 1 deletion(-) create mode 100644 connpy/api.py diff --git a/connpy/api.py b/connpy/api.py new file mode 100644 index 0000000..8bb8650 --- /dev/null +++ b/connpy/api.py @@ -0,0 +1,83 @@ +from flask import Flask, request, jsonify +from connpy import configfile, node, nodes +from waitress import serve +import os +import signal + +app = Flask(__name__) +conf = configfile() + +PID_FILE = ".connpy_server.pid" + + +@app.route("/") +def hello(): + return "Welcome to the Connpy API!" + +@app.route("/add_node", methods=["POST"]) +def add_node(): + node_data = request.get_json() + unique = node_data["unique"] + host = node_data["host"] + user = node_data["user"] + password = node_data["password"] + + conf.add(unique, host=host, user=user, password=password) + + return jsonify({"message": f"Node {unique} added successfully"}) + +@app.route("/run_commands", methods=["POST"]) +def run_commands(): + conf = app.custom_config + data = request.get_json() + unique = data["unique"] + commands = data["commands"] + node_data = conf.getitem(unique) + conn_node = node(unique,**node_data, config=conf) + + output = conn_node.run(commands) + + return output + +@app.route("/run_commands_on_nodes", methods=["POST"]) +def run_commands_on_nodes(): + data = request.get_json() + unique_list = data["unique_list"] + commands = data["commands"] + + nodes_data = {unique: conf.getitem(unique) for unique in unique_list} + conn_nodes = nodes(nodes_data) + + output = conn_nodes.run(commands) + + return jsonify({"output": output}) + +def stop_api(): + # Read the process ID (pid) from the file + with open(PID_FILE, "r") as f: + pid = int(f.read().strip()) + + # Send a SIGTERM signal to the process + os.kill(pid, signal.SIGTERM) + + # Delete the PID file + os.remove(PID_FILE) + + print(f"Server with process ID {pid} stopped.") + +def start_server(folder): + folder = folder.rstrip('/') + file = folder + '/config.json' + key = folder + '/.osk' + app.custom_config = configfile(file, key) + serve(app, host='0.0.0.0', port=8048) + +def start_api(folder): + pid = os.fork() + if pid == 0: + start_server(folder) + else: + with open(PID_FILE, "w") as f: + f.write(str(pid)) + print(f'Server is running') + diff --git a/connpy/connapp.py b/connpy/connapp.py index d7e26a8..f948337 100755 --- a/connpy/connapp.py +++ b/connpy/connapp.py @@ -10,11 +10,15 @@ import sys import inquirer from .core import node,nodes from ._version import __version__ +from .api import * import yaml try: from pyfzf.pyfzf import FzfPrompt except: FzfPrompt = None +home = os.path.expanduser("~") +defaultdir = home + '/.config/conn' + #functions and classes @@ -99,6 +103,12 @@ class connapp: runparser.add_argument("run", nargs='+', action=self._store_type, help=self._help("run"), default="run") runparser.add_argument("-g","--generate", dest="action", action="store_const", help="Generate yaml file template", const="generate", default="run") runparser.set_defaults(func=self._func_run) + #APIPARSER + apiparser = subparsers.add_parser("api", help="Start and stop connpy api") + apicrud = apiparser.add_mutually_exclusive_group(required=True) + apicrud.add_argument("--start", dest="start", nargs="?", action=self._store_type, help="Start connpy api", default="desfaultdir") + apicrud.add_argument("--stop", dest="stop", nargs=0, action=self._store_type, help="Stop conppy api") + apiparser.set_defaults(func=self._func_api) #CONFIGPARSER configparser = subparsers.add_parser("config", help="Manage app config") configcrud = configparser.add_mutually_exclusive_group(required=True) @@ -108,7 +118,7 @@ class connapp: configcrud.add_argument("--completion", dest="completion", nargs=1, choices=["bash","zsh"], action=self._store_type, help="Get terminal completion configuration for conn") configparser.set_defaults(func=self._func_others) #Manage sys arguments - commands = ["node", "profile", "mv", "move","copy", "cp", "bulk", "ls", "list", "run", "config"] + commands = ["node", "profile", "mv", "move","copy", "cp", "bulk", "ls", "list", "run", "config", "api"] profilecmds = ["--add", "-a", "--del", "--rm", "-r", "--mod", "--edit", "-e", "--show", "-s"] if len(argv) >= 2 and argv[1] == "profile" and argv[0] in profilecmds: argv[1] = argv[0] @@ -476,6 +486,18 @@ class connapp: actions = {"noderun": self._node_run, "generate": self._yaml_generate, "run": self._yaml_run} return actions.get(args.action)(args) + def _func_api(self, args): + if args.command == "start": + if args.data == None: + args.data = defaultdir + else: + if not os.path.isdir(args.data): + raise argparse.ArgumentTypeError(f"readable_dir:{args.data} is not a valid path") + start_api(args.data) + if args.command == "stop": + stop_api() + return + def _node_run(self, args): command = " ".join(args.data[1:]) command = command.split("-")