From 83f7cb390fb4eb3822144382bcdaa4b79b716cee Mon Sep 17 00:00:00 2001 From: Linus Vogel Date: Sun, 1 Feb 2026 21:00:13 +0100 Subject: [PATCH] added cli tool basics --- pillar_tool/db/queries/host_queries.py | 0 pillar_tool/ptcli.py | 78 ++++++++++++++++++++++++++ pillar_tool/schemas.py | 0 pyproject.toml | 6 ++ 4 files changed, 84 insertions(+) create mode 100644 pillar_tool/db/queries/host_queries.py create mode 100644 pillar_tool/ptcli.py create mode 100644 pillar_tool/schemas.py diff --git a/pillar_tool/db/queries/host_queries.py b/pillar_tool/db/queries/host_queries.py new file mode 100644 index 0000000..e69de29 diff --git a/pillar_tool/ptcli.py b/pillar_tool/ptcli.py new file mode 100644 index 0000000..9000ab3 --- /dev/null +++ b/pillar_tool/ptcli.py @@ -0,0 +1,78 @@ +import base64 + +import click + +import requests +from click import Context + +from pillar_tool.util import config, load_config, Config + +cfg: Config | None = None +base_url: str | None = None +auth_header: dict[str, str] | None = None + + +@click.group("command") +def main(): + global cfg, base_url, auth_header + + # load the configuration and store it + load_config() + cfg = config() + base_url = f"{cfg.ptcli.scheme}://{cfg.ptcli.host}:{cfg.ptcli.port}" + auth_header = { 'Authorization': f"Basic {base64.b64encode(f"{cfg.ptcli.user}:{cfg.ptcli.password}".encode('utf-8')).decode('ascii')}" } + + # health check of the api + try: + response = requests.get(f"{base_url}/health") + response.raise_for_status() + except requests.exceptions.HTTPError as e: + raise click.ClickException(f"API seems to be unhealthy:\n{e}") + except requests.exceptions.ConnectionError as e: + raise click.ClickException("Unable to connect to PillarTool API") + +@main.group("pillar") +def pillar(): + pass + +@main.group("host") +def host(): + pass + +@main.group("query") +def query(): + pass + +@pillar.command("get") +def pillar_get(): + print("pillar_get") + +@pillar.command("list") +def pillar_list(): + print("pillar_list") + +@host.command("list") +def host_list(): + click.echo("Listing known hosts...") + try: + response = requests.get(f"{base_url}/hosts", headers=auth_header) + response.raise_for_status() + + print(response.json()) + except requests.exceptions.HTTPError as e: + raise click.ClickException(f"Failed to list hosts:\n{e}") + +@host.command("create") +@click.argument("fqdn") +@click.argument("parent", default=None) +def host_create(fqdn: str, parent: str | None): + click.echo("Creating host...") + try: + response = requests.post(f"{base_url}/host/{fqdn}", json={'parent': parent}, headers=auth_header) + response.raise_for_status() + except requests.exceptions.HTTPError as e: + raise click.ClickException(f"Failed to create host:\n{e}") + + + click.echo(f"Host '{fqdn}' created!") + diff --git a/pillar_tool/schemas.py b/pillar_tool/schemas.py new file mode 100644 index 0000000..e69de29 diff --git a/pyproject.toml b/pyproject.toml index 003afeb..8c9a117 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -5,11 +5,17 @@ description = "Add your description here" requires-python = ">=3.13" dependencies = [ "alembic>=1.17.2", + "click>=8.3.1", "fastapi>=0.126.0", "hypercorn>=0.18.0", "jinja2>=3.1.6", "psycopg2>=2.9.11", "pycryptodome>=3.23.0", "pydantic>=2.12.5", + "requests>=2.32.5", "sqlalchemy>=2.0.45", ] + + +[project.scripts] +ptcli = "pillar_tool.ptcli:main"