diff --git a/pillar_tool/db/queries/host_queries.py b/pillar_tool/db/queries/host_queries.py index aa684fe..fa62024 100644 --- a/pillar_tool/db/queries/host_queries.py +++ b/pillar_tool/db/queries/host_queries.py @@ -45,5 +45,6 @@ def create_host(db: Session, fqdn: str, parent: str | None) -> Host: raise HTTPException(status_code=500, detail="Invalid state of database") -def delete_host(db: Session, fqdn: str): +def delete_host(db: Session, path: list[str]) -> str | None: + pass \ No newline at end of file diff --git a/pillar_tool/main.py b/pillar_tool/main.py index be27258..c79a6f0 100644 --- a/pillar_tool/main.py +++ b/pillar_tool/main.py @@ -108,6 +108,23 @@ async def hostgroup_list(request: Request): @app.post("/host/{fqdn}") async def host_add(request: Request, fqdn: str, params: HostCreateParams): + """ + Creates a hierarchical host structure based on the provided FQDN path. + + Args: + request: The HTTP request containing database connection and other metadata. + fqdn: Fully Qualified Domain Name in dot-separated format (e.g., "a/b/c"). + params: Host creation parameters including optional parent reference. + + Returns: + JSON response with: + - message: Confirmation of host creation + - host: The final created host object + - path: Full hierarchical path if applicable + + Raises: + HTTPException(400): If the provided FQDN is invalid or malformed. + """ # Validate and split FQDN into hierarchical labels (e.g., "a/b/c" -> ["a", "b", "c"]) labels = validate_and_split_path_and_domain_name(fqdn) if labels is None: @@ -144,8 +161,22 @@ async def host_add(request: Request, fqdn: str, params: HostCreateParams): @app.delete("/host/{fqdn}") async def host_delete(request: Request, fqdn: str): - delete_host(request.state.db, fqdn) - return JSONResponse({}) + # Validate and split FQDN into hierarchical labels (e.g., "a/b/c" -> ["a", "b", "c"]) + labels = validate_and_split_path_and_domain_name(fqdn) + if labels is None: + raise HTTPException(status_code=400, detail="Invalid Path provided") + + error_msg: str | None = delete_host(request.state.db, labels) + if error_msg is not None: + return JSONResponse({ + 'message': "Failed to delete host", + 'details': error_msg + }, status_code=400) + else: + return JSONResponse({ + 'message': "Host deleted", + 'path': fqdn + }) @app.get("/top/{fqdn}") async def host_top(request: Request, fqdn: str): diff --git a/pillar_tool/ptcli.py b/pillar_tool/ptcli.py index 9000ab3..f5daea8 100644 --- a/pillar_tool/ptcli.py +++ b/pillar_tool/ptcli.py @@ -76,3 +76,8 @@ def host_create(fqdn: str, parent: str | None): click.echo(f"Host '{fqdn}' created!") + +@host.command("delete") +@click.argument("full_path") +def host_delete(full_path: str): + click.confirm(f"Are you sure you want to delete") \ No newline at end of file diff --git a/pillar_tool/util/validation.py b/pillar_tool/util/validation.py index 4164b7e..57e891e 100644 --- a/pillar_tool/util/validation.py +++ b/pillar_tool/util/validation.py @@ -2,6 +2,7 @@ import re DOMAIN_NAME_REGEX = r'^[a-zA-Z0-9._-]+$' # could be a FQDN, but also just a name +FQDN_REGEX = r'^([a-zA-Z0-9.-]+\.)+[a-zA-Z]{2,}$' def validate_and_split_path_and_domain_name(path_or_dn: str) -> list[str] | None: @@ -31,3 +32,5 @@ def validate_and_split_path_and_domain_name(path_or_dn: str) -> list[str] | None # Return the list of validated fragments or None if any failed validation # NOTE: validated_fragments could be falsy if input was empty or only slashes return validated_fragments if validated_fragments else None + +