restructured the commandline interface
This commit is contained in:
parent
9216c95f10
commit
855302de1f
@ -1 +0,0 @@
|
|||||||
from .main import main
|
|
||||||
7
pillar_tool/ptcli/__main__.py
Normal file
7
pillar_tool/ptcli/__main__.py
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
from pillar_tool.ptcli.cli.cli_main import main
|
||||||
|
|
||||||
|
def tool_main():
|
||||||
|
main()
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
6
pillar_tool/ptcli/cli/__init__.py
Normal file
6
pillar_tool/ptcli/cli/__init__.py
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
from .host import host
|
||||||
|
from .hostgroup import hostgroup
|
||||||
|
from .query import query
|
||||||
|
from .state import state
|
||||||
|
from .pillar import pillar
|
||||||
|
from .environment import environment
|
||||||
41
pillar_tool/ptcli/cli/cli_main.py
Normal file
41
pillar_tool/ptcli/cli/cli_main.py
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
import base64
|
||||||
|
|
||||||
|
import click
|
||||||
|
|
||||||
|
import requests
|
||||||
|
from urllib.parse import quote
|
||||||
|
|
||||||
|
from pillar_tool.schemas import HostCreateParams, HostgroupParams
|
||||||
|
from pillar_tool.util import config, load_config, Config
|
||||||
|
from pillar_tool.util.validation import split_and_validate_path, validate_fqdn
|
||||||
|
|
||||||
|
cfg: Config | None = None
|
||||||
|
_base_url: str | None = None
|
||||||
|
_auth_header: dict[str, str] | None = None
|
||||||
|
|
||||||
|
def auth_header():
|
||||||
|
global _auth_header
|
||||||
|
return _auth_header
|
||||||
|
|
||||||
|
def base_url():
|
||||||
|
global _base_url
|
||||||
|
return _base_url
|
||||||
|
|
||||||
|
@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")
|
||||||
9
pillar_tool/ptcli/cli/environment.py
Normal file
9
pillar_tool/ptcli/cli/environment.py
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
import click
|
||||||
|
import requests
|
||||||
|
|
||||||
|
from .cli_main import main, auth_header, base_url
|
||||||
|
|
||||||
|
|
||||||
|
@main.group("environment")
|
||||||
|
def environment():
|
||||||
|
pass
|
||||||
57
pillar_tool/ptcli/cli/host.py
Normal file
57
pillar_tool/ptcli/cli/host.py
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
import click
|
||||||
|
import requests
|
||||||
|
|
||||||
|
from .cli_main import main, auth_header, base_url
|
||||||
|
from ...schemas import HostCreateParams
|
||||||
|
from ...util.validation import validate_fqdn
|
||||||
|
|
||||||
|
|
||||||
|
@main.group("host")
|
||||||
|
def host():
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
@host.command("list")
|
||||||
|
def host_list():
|
||||||
|
click.echo("Listing known hosts...")
|
||||||
|
try:
|
||||||
|
response = requests.get(f"{base_url()}/host", headers=auth_header())
|
||||||
|
response.raise_for_status()
|
||||||
|
|
||||||
|
for h in response.json():
|
||||||
|
click.echo(f" - {h}")
|
||||||
|
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:
|
||||||
|
params = HostCreateParams(
|
||||||
|
parent=parent
|
||||||
|
)
|
||||||
|
response = requests.post(f"{base_url()}/host/{fqdn}", json=params.model_dump(), 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!")
|
||||||
|
|
||||||
|
|
||||||
|
@host.command("delete")
|
||||||
|
@click.argument("fqdn")
|
||||||
|
def host_delete(fqdn: str):
|
||||||
|
if not validate_fqdn(fqdn):
|
||||||
|
click.echo("Invalid FQDN")
|
||||||
|
return
|
||||||
|
|
||||||
|
if click.confirm(f"Are you sure you want to delete '{fqdn}'?"):
|
||||||
|
click.echo("Deleting host...")
|
||||||
|
|
||||||
|
try:
|
||||||
|
response = requests.delete(f'{base_url}/host/{fqdn}', headers=auth_header())
|
||||||
|
response.raise_for_status()
|
||||||
|
except requests.exceptions.HTTPError as e:
|
||||||
|
raise click.ClickException(f"Failed to delete host:\n{e}")
|
||||||
74
pillar_tool/ptcli/cli/hostgroup.py
Normal file
74
pillar_tool/ptcli/cli/hostgroup.py
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
import click
|
||||||
|
import requests
|
||||||
|
|
||||||
|
from .cli_main import main, auth_header, base_url
|
||||||
|
from ...schemas import HostgroupParams
|
||||||
|
from ...util.validation import split_and_validate_path
|
||||||
|
|
||||||
|
|
||||||
|
@main.group("hostgroup")
|
||||||
|
def hostgroup():
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
@hostgroup.command("list")
|
||||||
|
def hostgroup_list():
|
||||||
|
click.echo("Listing known hostgroups...")
|
||||||
|
try:
|
||||||
|
response = requests.get(f'{base_url}/hostgroup', headers=auth_header())
|
||||||
|
response.raise_for_status()
|
||||||
|
|
||||||
|
click.echo("Hostgroups:")
|
||||||
|
for hg in response.json():
|
||||||
|
click.echo(f" - {hg}")
|
||||||
|
except requests.exceptions.HTTPError as e:
|
||||||
|
raise click.ClickException(f"Failed to list hostgroups:\n{e}")
|
||||||
|
|
||||||
|
|
||||||
|
@hostgroup.command("show")
|
||||||
|
@click.argument("path")
|
||||||
|
def hostgroup_show(path: str):
|
||||||
|
click.echo(f"Showing hostgroup '{path}'...")
|
||||||
|
try:
|
||||||
|
labels = split_and_validate_path(path)
|
||||||
|
name = labels[-1]
|
||||||
|
path = '/'.join(labels[:-1]) if len(labels) > 1 else None
|
||||||
|
data = HostgroupParams(
|
||||||
|
path=path
|
||||||
|
)
|
||||||
|
response = requests.get(f'{base_url}/hostgroup/{name}', headers=auth_header(), params=data.model_dump())
|
||||||
|
response.raise_for_status()
|
||||||
|
except requests.exceptions.HTTPError as e:
|
||||||
|
raise click.ClickException(f"Failed to show hostgroup:\n{e}")
|
||||||
|
|
||||||
|
|
||||||
|
@hostgroup.command("create")
|
||||||
|
@click.argument("path")
|
||||||
|
def hostgroup_create(path: str):
|
||||||
|
click.echo(f"Creating hostgroup '{path}'...")
|
||||||
|
try:
|
||||||
|
labels = split_and_validate_path(path)
|
||||||
|
path = "/".join(labels[:-1]) if len(labels) > 1 else ''
|
||||||
|
name = labels[-1]
|
||||||
|
data = HostgroupParams(
|
||||||
|
path=path
|
||||||
|
)
|
||||||
|
response = requests.post(f'{base_url}/hostgroup/{name}', headers=auth_header(), json=data.model_dump())
|
||||||
|
response.raise_for_status()
|
||||||
|
except requests.exceptions.HTTPError as e:
|
||||||
|
raise click.ClickException(f"Failed to create hostgroup:\n{e}")
|
||||||
|
|
||||||
|
|
||||||
|
@hostgroup.command("delete")
|
||||||
|
@click.argument("path")
|
||||||
|
def hostgroup_delete(path: str):
|
||||||
|
click.echo(f"Deleting hostgroup {path}...")
|
||||||
|
try:
|
||||||
|
labels = split_and_validate_path(path)
|
||||||
|
name = labels[-1]
|
||||||
|
prefix = "/".join(labels[:-1]) if len(labels) > 1 else None
|
||||||
|
query_params = f"?path={prefix}" if prefix is not None else ''
|
||||||
|
response = requests.delete(f'{base_url}/hostgroup/{name}{query_params}', headers=auth_header())
|
||||||
|
response.raise_for_status()
|
||||||
|
except requests.exceptions.HTTPError as e:
|
||||||
|
raise click.ClickException(f"Failed to delete hostgroup:\n{e}")
|
||||||
9
pillar_tool/ptcli/cli/pillar.py
Normal file
9
pillar_tool/ptcli/cli/pillar.py
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
import click
|
||||||
|
import requests
|
||||||
|
|
||||||
|
from .cli_main import main, auth_header, base_url
|
||||||
|
|
||||||
|
|
||||||
|
@main.group("pillar")
|
||||||
|
def pillar():
|
||||||
|
pass
|
||||||
9
pillar_tool/ptcli/cli/query.py
Normal file
9
pillar_tool/ptcli/cli/query.py
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
import click
|
||||||
|
import requests
|
||||||
|
|
||||||
|
from .cli_main import main, auth_header, base_url
|
||||||
|
|
||||||
|
|
||||||
|
@main.group("query")
|
||||||
|
def query():
|
||||||
|
pass
|
||||||
9
pillar_tool/ptcli/cli/state.py
Normal file
9
pillar_tool/ptcli/cli/state.py
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
import click
|
||||||
|
import requests
|
||||||
|
|
||||||
|
from .cli_main import main, auth_header, base_url
|
||||||
|
|
||||||
|
|
||||||
|
@main.group("state")
|
||||||
|
def state():
|
||||||
|
pass
|
||||||
@ -1,171 +0,0 @@
|
|||||||
import base64
|
|
||||||
|
|
||||||
import click
|
|
||||||
|
|
||||||
import requests
|
|
||||||
from urllib.parse import quote
|
|
||||||
|
|
||||||
from pillar_tool.schemas import HostCreateParams, HostgroupParams
|
|
||||||
from pillar_tool.util import config, load_config, Config
|
|
||||||
from pillar_tool.util.validation import split_and_validate_path, validate_fqdn
|
|
||||||
|
|
||||||
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("hostgroup")
|
|
||||||
def hostgroup():
|
|
||||||
pass
|
|
||||||
|
|
||||||
@main.group("environment")
|
|
||||||
def environment():
|
|
||||||
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}/host", headers=auth_header)
|
|
||||||
response.raise_for_status()
|
|
||||||
|
|
||||||
for h in response.json():
|
|
||||||
click.echo(f" - {h}")
|
|
||||||
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:
|
|
||||||
params = HostCreateParams(
|
|
||||||
parent=parent
|
|
||||||
)
|
|
||||||
response = requests.post(f"{base_url}/host/{fqdn}", json=params.model_dump(), 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!")
|
|
||||||
|
|
||||||
|
|
||||||
@host.command("delete")
|
|
||||||
@click.argument("fqdn")
|
|
||||||
def host_delete(fqdn: str):
|
|
||||||
if not validate_fqdn(fqdn):
|
|
||||||
click.echo("Invalid FQDN")
|
|
||||||
return
|
|
||||||
|
|
||||||
if click.confirm(f"Are you sure you want to delete '{fqdn}'?"):
|
|
||||||
click.echo("Deleting host...")
|
|
||||||
|
|
||||||
try:
|
|
||||||
response = requests.delete(f'{base_url}/host/{fqdn}', headers=auth_header)
|
|
||||||
response.raise_for_status()
|
|
||||||
except requests.exceptions.HTTPError as e:
|
|
||||||
raise click.ClickException(f"Failed to delete host:\n{e}")
|
|
||||||
|
|
||||||
|
|
||||||
@hostgroup.command("list")
|
|
||||||
def hostgroup_list():
|
|
||||||
click.echo("Listing known hostgroups...")
|
|
||||||
try:
|
|
||||||
response = requests.get(f'{base_url}/hostgroup', headers=auth_header)
|
|
||||||
response.raise_for_status()
|
|
||||||
|
|
||||||
click.echo("Hostgroups:")
|
|
||||||
for hg in response.json():
|
|
||||||
click.echo(f" - {hg}")
|
|
||||||
except requests.exceptions.HTTPError as e:
|
|
||||||
raise click.ClickException(f"Failed to list hostgroups:\n{e}")
|
|
||||||
|
|
||||||
|
|
||||||
@hostgroup.command("show")
|
|
||||||
@click.argument("path")
|
|
||||||
def hostgroup_show(path: str):
|
|
||||||
click.echo(f"Showing hostgroup '{path}'...")
|
|
||||||
try:
|
|
||||||
labels = split_and_validate_path(path)
|
|
||||||
name = labels[-1]
|
|
||||||
path = '/'.join(labels[:-1]) if len(labels) > 1 else None
|
|
||||||
data = HostgroupParams(
|
|
||||||
path=path
|
|
||||||
)
|
|
||||||
response = requests.get(f'{base_url}/hostgroup/{name}', headers=auth_header, params=data.model_dump())
|
|
||||||
response.raise_for_status()
|
|
||||||
except requests.exceptions.HTTPError as e:
|
|
||||||
raise click.ClickException(f"Failed to show hostgroup:\n{e}")
|
|
||||||
|
|
||||||
|
|
||||||
@hostgroup.command("create")
|
|
||||||
@click.argument("path")
|
|
||||||
def hostgroup_create(path: str):
|
|
||||||
click.echo(f"Creating hostgroup '{path}'...")
|
|
||||||
try:
|
|
||||||
labels = split_and_validate_path(path)
|
|
||||||
path = "/".join(labels[:-1]) if len(labels) > 1 else ''
|
|
||||||
name = labels[-1]
|
|
||||||
data = HostgroupParams(
|
|
||||||
path=path
|
|
||||||
)
|
|
||||||
response = requests.post(f'{base_url}/hostgroup/{name}', headers=auth_header, json=data.model_dump())
|
|
||||||
response.raise_for_status()
|
|
||||||
except requests.exceptions.HTTPError as e:
|
|
||||||
raise click.ClickException(f"Failed to create hostgroup:\n{e}")
|
|
||||||
|
|
||||||
|
|
||||||
@hostgroup.command("delete")
|
|
||||||
@click.argument("path")
|
|
||||||
def hostgroup_delete(path: str):
|
|
||||||
click.echo(f"Deleting hostgroup {path}...")
|
|
||||||
try:
|
|
||||||
labels = split_and_validate_path(path)
|
|
||||||
name = labels[-1]
|
|
||||||
prefix = "/".join(labels[:-1]) if len(labels) > 1 else None
|
|
||||||
query_params = f"?path={prefix}" if prefix is not None else ''
|
|
||||||
response = requests.delete(f'{base_url}/hostgroup/{name}{query_params}', headers=auth_header)
|
|
||||||
response.raise_for_status()
|
|
||||||
except requests.exceptions.HTTPError as e:
|
|
||||||
raise click.ClickException(f"Failed to delete hostgroup:\n{e}")
|
|
||||||
|
|
||||||
@ -26,14 +26,20 @@ pillar_tool/db/queries/__init__.py
|
|||||||
pillar_tool/db/queries/auth_queries.py
|
pillar_tool/db/queries/auth_queries.py
|
||||||
pillar_tool/db/queries/host_queries.py
|
pillar_tool/db/queries/host_queries.py
|
||||||
pillar_tool/db/queries/pillar_queries.py
|
pillar_tool/db/queries/pillar_queries.py
|
||||||
pillar_tool/frontend/__init__.py
|
|
||||||
pillar_tool/frontend/pillar_view.py
|
|
||||||
pillar_tool/middleware/__init__.py
|
pillar_tool/middleware/__init__.py
|
||||||
pillar_tool/middleware/basicauth_backend.py
|
pillar_tool/middleware/basicauth_backend.py
|
||||||
pillar_tool/middleware/db_connection.py
|
pillar_tool/middleware/db_connection.py
|
||||||
pillar_tool/middleware/logging.py
|
pillar_tool/middleware/logging.py
|
||||||
pillar_tool/ptcli/__init__.py
|
pillar_tool/ptcli/__init__.py
|
||||||
pillar_tool/ptcli/main.py
|
pillar_tool/ptcli/__main__.py
|
||||||
|
pillar_tool/ptcli/cli/__init__.py
|
||||||
|
pillar_tool/ptcli/cli/cli_main.py
|
||||||
|
pillar_tool/ptcli/cli/environment.py
|
||||||
|
pillar_tool/ptcli/cli/host.py
|
||||||
|
pillar_tool/ptcli/cli/hostgroup.py
|
||||||
|
pillar_tool/ptcli/cli/pillar.py
|
||||||
|
pillar_tool/ptcli/cli/query.py
|
||||||
|
pillar_tool/ptcli/cli/state.py
|
||||||
pillar_tool/routers/__init__.py
|
pillar_tool/routers/__init__.py
|
||||||
pillar_tool/routers/environment.py
|
pillar_tool/routers/environment.py
|
||||||
pillar_tool/routers/host.py
|
pillar_tool/routers/host.py
|
||||||
|
|||||||
@ -1,2 +1,2 @@
|
|||||||
[console_scripts]
|
[console_scripts]
|
||||||
ptcli = pillar_tool.ptcli:main
|
ptcli = pillar_tool.ptcli.__main__:tool_main
|
||||||
|
|||||||
@ -18,4 +18,4 @@ dependencies = [
|
|||||||
|
|
||||||
|
|
||||||
[project.scripts]
|
[project.scripts]
|
||||||
ptcli = "pillar_tool.ptcli:main"
|
ptcli = "pillar_tool.ptcli.__main__:tool_main"
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user