worked on hostgroup implementation

This commit is contained in:
Linus Vogel 2026-02-12 22:55:00 +01:00
parent 6fc2ac7969
commit bfb568b456
4 changed files with 154 additions and 7 deletions

View File

@ -1,4 +1,6 @@
from pillar_tool.schemas import HealthCheckError
from sqlalchemy import text
from pillar_tool.schemas import HealthCheckError, HealthCheckSuccess
from pillar_tool.util import load_config, config
load_config()
@ -22,6 +24,7 @@ from pillar_tool.db.database import run_db_migrations
# import all the routers
from pillar_tool.routers.host import router as host_router
from pillar_tool.routers.hostgroup import router as hostgroup_router
# run any pending migrations
run_db_migrations()
@ -66,6 +69,7 @@ app.exception_handler(Exception)(on_general_error)
# Setup the api router
app.include_router(host_router)
app.include_router(hostgroup_router)
@app.get("/")
async def root():
@ -77,7 +81,7 @@ async def health():
# Check database connection
try:
db = get_connection()
db.execute("SELECT 1")
db.execute(text("SELECT 1"))
db.close()
except Exception as e:
return HealthCheckError(500, f"Database connection error:\n{e}").response()

View File

@ -67,7 +67,8 @@ def host_list():
response = requests.get(f"{base_url}/host", headers=auth_header)
response.raise_for_status()
print(response.json())
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}")
@ -108,7 +109,15 @@ def host_delete(fqdn: str):
@hostgroup.command("list")
def hostgroup_list():
click.echo("Listing known hostgroups...")
click.echo("TODO: implement")
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("create")

View File

@ -172,6 +172,22 @@ async def host_add(request: Request, fqdn: str, params: HostCreateParams):
@router.delete("/{fqdn}")
async def host_delete(request: Request, fqdn: str):
"""
Delete a specific host from the system by its FQDN.
Removes the host entry and associated data from the database.
TODO: Implement actual deletion logic - currently just a stub.
Args:
request: FastAPI request object containing database session
fqdn: Fully qualified domain name of the host to delete
Returns:
JSONResponse indicating success or failure of the operation
Raises:
HTTPException: If FQDN format is invalid or host is not found
"""
pass

View File

@ -1,7 +1,15 @@
from http.client import HTTPResponse
from sqlalchemy import select, insert, bindparam
from sqlalchemy.orm import Session
from starlette.exceptions import HTTPException
from starlette.requests import Request
from fastapi import APIRouter
from starlette.responses import JSONResponse
from pillar_tool.db import Host
from pillar_tool.schemas import HostgroupCreateParams
from pillar_tool.util.validation import split_and_validate_path
router = APIRouter(
prefix="/hostgroup",
@ -11,24 +19,134 @@ router = APIRouter(
@router.get("")
def hostgroups_get(req: Request):
pass
"""
Retrieve all host groups.
Fetches and returns a list of host group names from the database.
A host group is defined as a `Host` record where `is_hostgroup == True`.
Returns:
JSONResponse: A JSON response with status code 200 containing a list of host group names (strings).
"""
db: Session = req.state.db
result = db.execute(select(Host).where(Host.is_hostgroup == True)).fetchall()
hosts: list[Host] = list(map(lambda x: x[0], result))
return JSONResponse(status_code=200, content=list(map(lambda x: x.name, hosts)))
@router.get("/{name}")
def hostgroup_get(req: Request, name: str):
pass
def hostgroup_get(req: Request, name: str, path_input: str | None = None):
"""
Retrieve a specific host group by name.
Fetches and returns details of the specified host group.
Returns 404 if no such host group exists.
Args:
req (Request): The incoming request object.
name (str): The name of the host group to retrieve.
path_input (str): the path of the group if desired
Returns:
JSONResponse: A JSON response with status code 200 and the host group details on success,
or 404 if not found.
"""
db: Session = req.state.db
# decode the path
last = None
ancestors = []
if path_input is not None:
path = split_and_validate_path(path_input)
# get the path from the db
path_stmt = select(Host).where(Host.name == bindparam('name') and Host.parent_id == bindparam('parent_id'))
for label in path:
result = db.execute(path_stmt, {'name': label, 'parent_id': last}).fetchall()
# error 404 if there is no matching item
if len(result) != 1:
raise HTTPException(status_code=404, detail="No such hostgroup path exists")
tmp: Host = result[0][0]
ancestors.append(tmp)
last = tmp.id
# get the host in question
stmt = select(Host).where(Host.name == name and Host.is_hostgroup == True and Host.parent_id == last)
result = db.execute(stmt).fetchall()
if len(result) == 0:
raise HTTPException(status_code=404, detail="No such hostgroup exists")
# Note: this should be enforced by the database
assert len(result) == 1
print("check 1")
hg: Host = result[0][0]
return JSONResponse(status_code=200, content={
'hostgroup': hg.name,
'path': '/'.join(x.name for x in ancestors)
})
@router.post("/{name}")
def hostgroup_create(req: Request, name: str, params: HostgroupCreateParams):
"""
Create a new host group.
Creates a new host group record in the database with the provided parameters.
Args:
req (Request): The incoming request object.
name (str): The name of the host group (used as identifier).
params (HostgroupCreateParams): The creation parameters (e.g., description, associated hosts).
Returns:
JSONResponse: A JSON response with status code 201 on success,
or appropriate error codes (e.g., 409 if already exists).
"""
pass
@router.patch("/{name}")
def hostgroup_update(req: Request, name: str, params: HostgroupCreateParams):
"""
Update an existing host group by name.
Updates the specified host group with new parameters.
Returns 404 if no such host group exists.
Args:
req (Request): The incoming request object.
name (str): The current name of the host group to update.
params (HostgroupCreateParams): The updated parameters.
Returns:
JSONResponse: A JSON response with status code 200 on success,
or 404 if not found.
"""
pass
@router.delete("/{name}")
def hostgroup_delete(req: Request, name: str, params: HostgroupCreateParams):
"""
Delete a host group by name.
Deletes the specified host group from the database.
Returns 404 if no such host group exists.
Args:
req (Request): The incoming request object.
name (str): The name of the host group to delete.
params (HostgroupCreateParams): Included for consistency but typically unused in deletions.
Returns:
JSONResponse: A JSON response with status code 204 on successful deletion,
or 404 if not found.
"""
pass