diff --git a/README.md b/README.md index 058d22d..8d444da 100644 --- a/README.md +++ b/README.md @@ -125,6 +125,7 @@ positional arguments: bulk Add nodes in bulk run Run scripts or commands on nodes config Manage app config + api Start and stop connpy api ``` ### Manage profiles: @@ -154,3 +155,62 @@ options: conn pc@office conn server ``` +## http API +With the Connpy API you can run commands on devices using http requests + +### 1. List Nodes + +**Endpoint**: `/list_nodes` + +**Method**: `POST` + +**Description**: This route returns a list of nodes. It can also filter the list based on a given keyword. + +#### Request Body: + +```json +{ + "filter": "" +} +``` + +* `filter` (optional): A keyword to filter the list of nodes. It returns only the nodes that contain the keyword. If not provided, the route will return the entire list of nodes. + +#### Response: + +- A JSON array containing the filtered list of nodes. + +--- + +### 2. Run Commands + +**Endpoint**: `/run_commands` + +**Method**: `POST` + +**Description**: This route runs commands on selected nodes based on the provided action, nodes, and commands. It also supports executing tests by providing expected results. + +#### Request Body: + +```json +{ + "action": "", + "nodes": "", + "commands": "", + "expected": "", + "options": "" +} +``` + +* `action` (required): The action to be performed. Possible values: `run` or `test`. +* `nodes` (required): A list of nodes or a single node on which the commands will be executed. The nodes can be specified as individual node names or a node group with the `@` prefix. Node groups can also be specified as arrays with a list of nodes inside the group. +* `commands` (required): A list of commands to be executed on the specified nodes. +* `expected` (optional, only used when the action is `test`): A single expected result for the test. +* `options` (optional): Array to pass options to the run command, options are: `prompt`, `parallel`, `timeout` + +#### Response: + +- A JSON object with the results of the executed commands on the nodes. +## Automation module +the automation module + diff --git a/connpy/_version.py b/connpy/_version.py index ebe9105..9e2f1ac 100644 --- a/connpy/_version.py +++ b/connpy/_version.py @@ -1,2 +1,2 @@ -__version__ = "3.0.5" +__version__ = "3.0.6" diff --git a/connpy/api.py b/connpy/api.py index b1fd089..431dd8d 100644 --- a/connpy/api.py +++ b/connpy/api.py @@ -102,12 +102,14 @@ def stop_api(): # Read the process ID (pid) from the file try: with open(PID_FILE1, "r") as f: - pid = int(f.read().strip()) + pid = int(f.readline().strip()) + port = int(f.readline().strip()) PID_FILE=PID_FILE1 except: try: with open(PID_FILE2, "r") as f: - pid = int(f.read().strip()) + pid = int(f.readline().strip()) + port = int(f.readline().strip()) PID_FILE=PID_FILE2 except: print("Connpy api server is not running.") @@ -116,30 +118,34 @@ def stop_api(): os.kill(pid, signal.SIGTERM) # Delete the PID file os.remove(PID_FILE) - print(f"Server with process ID {pid} stopped.") + return port -def start_server(): +def debug_api(port=8048): app.custom_config = configfile() - serve(app, host='0.0.0.0', port=8048) + app.run(debug=True, port=port) -def start_api(): +def start_server(port=8048): + app.custom_config = configfile() + serve(app, host='0.0.0.0', port=port) + +def start_api(port=8048): if os.path.exists(PID_FILE1) or os.path.exists(PID_FILE2): print("Connpy server is already running.") return pid = os.fork() if pid == 0: - start_server() + start_server(port) else: try: with open(PID_FILE1, "w") as f: - f.write(str(pid)) + f.write(str(pid) + "\n" + str(port)) except: try: with open(PID_FILE2, "w") as f: - f.write(str(pid)) + f.write(str(pid) + "\n" + str(port)) except: print("Cound't create PID file") return - print(f'Server is running with process ID {pid}.') + print(f'Server is running with process ID {pid} in port {port}') diff --git a/connpy/completion.py b/connpy/completion.py index dc4117e..9614a6c 100644 --- a/connpy/completion.py +++ b/connpy/completion.py @@ -50,7 +50,7 @@ def main(): if words[0] == "config": strings=["--allow-uppercase", "--keepalive", "--completion", "--fzf", "--configfolder", "--help"] if words[0] == "api": - strings=["--start", "--stop", "--restart", "--help"] + strings=["--start", "--stop", "--restart", "--debug", "--help"] if words[0] in ["--mod", "--edit", "-e", "--show", "-s", "--add", "-a", "--rm", "--del", "-r"]: strings=["profile"] if words[0] in ["list", "ls"]: diff --git a/connpy/connapp.py b/connpy/connapp.py index fe1ec2f..caf9be7 100755 --- a/connpy/connapp.py +++ b/connpy/connapp.py @@ -106,9 +106,10 @@ class connapp: #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=0, action=self._store_type, help="Start conppy api") - apicrud.add_argument("--restart", dest="restart", nargs=0, action=self._store_type, help="Restart conppy api") - apicrud.add_argument("--stop", dest="stop", nargs=0, action=self._store_type, help="Stop conppy api") + apicrud.add_argument("-s","--start", dest="start", nargs="?", action=self._store_type, help="Start conppy api", type=int, default=8048, metavar="PORT") + apicrud.add_argument("-r","--restart", dest="restart", nargs=0, action=self._store_type, help="Restart conppy api") + apicrud.add_argument("-x","--stop", dest="stop", nargs=0, action=self._store_type, help="Stop conppy api") + apicrud.add_argument("-d", "--debug", dest="debug", nargs="?", action=self._store_type, help="Run connpy server on debug mode", type=int, default=8048, metavar="PORT") apiparser.set_defaults(func=self._func_api) #CONFIGPARSER configparser = subparsers.add_parser("config", help="Manage app config") @@ -500,9 +501,17 @@ class connapp: def _func_api(self, args): if args.command == "stop" or args.command == "restart": - stop_api() + args.data = stop_api() if args.command == "start" or args.command == "restart": - start_api() + if args.data: + start_api(args.data) + else: + start_api() + if args.command == "debug": + if args.data: + debug_api(args.data) + else: + debug_api() return def _node_run(self, args): diff --git a/docs/connpy/index.html b/docs/connpy/index.html index dba6af6..dc6ac86 100644 --- a/docs/connpy/index.html +++ b/docs/connpy/index.html @@ -919,9 +919,10 @@ __pdoc__ = { #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=0, action=self._store_type, help="Start conppy api") - apicrud.add_argument("--restart", dest="restart", nargs=0, action=self._store_type, help="Restart conppy api") - apicrud.add_argument("--stop", dest="stop", nargs=0, action=self._store_type, help="Stop conppy api") + apicrud.add_argument("-s","--start", dest="start", nargs="?", action=self._store_type, help="Start conppy api", type=int, default=8048, metavar="PORT") + apicrud.add_argument("-r","--restart", dest="restart", nargs=0, action=self._store_type, help="Restart conppy api") + apicrud.add_argument("-x","--stop", dest="stop", nargs=0, action=self._store_type, help="Stop conppy api") + apicrud.add_argument("-d", "--debug", dest="debug", nargs="?", action=self._store_type, help="Run connpy server on debug mode", type=int, default=8048, metavar="PORT") apiparser.set_defaults(func=self._func_api) #CONFIGPARSER configparser = subparsers.add_parser("config", help="Manage app config") @@ -1313,9 +1314,17 @@ __pdoc__ = { def _func_api(self, args): if args.command == "stop" or args.command == "restart": - stop_api() + args.data = stop_api() if args.command == "start" or args.command == "restart": - start_api() + if args.data: + start_api(args.data) + else: + start_api() + if args.command == "debug": + if args.data: + debug_api(args.data) + else: + debug_api() return def _node_run(self, args): @@ -1953,9 +1962,10 @@ tasks: #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=0, action=self._store_type, help="Start conppy api") - apicrud.add_argument("--restart", dest="restart", nargs=0, action=self._store_type, help="Restart conppy api") - apicrud.add_argument("--stop", dest="stop", nargs=0, action=self._store_type, help="Stop conppy api") + apicrud.add_argument("-s","--start", dest="start", nargs="?", action=self._store_type, help="Start conppy api", type=int, default=8048, metavar="PORT") + apicrud.add_argument("-r","--restart", dest="restart", nargs=0, action=self._store_type, help="Restart conppy api") + apicrud.add_argument("-x","--stop", dest="stop", nargs=0, action=self._store_type, help="Stop conppy api") + apicrud.add_argument("-d", "--debug", dest="debug", nargs="?", action=self._store_type, help="Run connpy server on debug mode", type=int, default=8048, metavar="PORT") apiparser.set_defaults(func=self._func_api) #CONFIGPARSER configparser = subparsers.add_parser("config", help="Manage app config")