Compare commits

...

2 Commits

2 changed files with 65 additions and 9 deletions

View File

@ -5,6 +5,7 @@ import click
import requests
from .cli_main import main, auth_header, base_url
from ...schemas import PillarParams
@main.group("pillar")
@ -52,11 +53,27 @@ def pillar_set(name: str, host: str | None, hostgroup: str | None, parameter_typ
except ValueError as e:
print(f"Failed to validate value: {e}")
else:
data = {
'host': host,
'hostgroup': hostgroup,
'type': parameter_type,
'value': json.dumps(value)
}
data = PillarParams(
host=host,
hostgroup=hostgroup,
type=parameter_type,
value=json.dumps(value)
)
requests.post(f"{base_url()}/pillar/{name}", headers=auth_header(), json=data)
requests.post(f"{base_url()}/pillar/{name}", headers=auth_header(), json=data.model_dump())
@pillar.command("delete")
@click.argument("name")
@click.option("--host")
@click.option("--hostgroup")
def pillar_delete(name: str, host: str | None, hostgroup: str | None):
try:
data = PillarParams(
host=host,
hostgroup=hostgroup,
type=None,
value=None,
)
requests.delete(f"{base_url()}/pillar/{name}", headers=auth_header(), json=data.model_dump())
except Exception as e:
print(f"ERROR: {e}")

View File

@ -4,7 +4,7 @@ from uuid import uuid4
from sqlalchemy.dialects import postgresql
from sqlalchemy.dialects.postgresql import insert
from sqlalchemy import select, delete, bindparam, and_
from sqlalchemy import select, delete, bindparam, and_, or_
from sqlalchemy.orm import Session
from starlette.exceptions import HTTPException
from starlette.requests import Request
@ -147,5 +147,44 @@ def pillar_create(req: Request, name: str, params: PillarParams):
@router.delete("/{name}")
def pillar_delete(req: Request, name: str, params: PillarParams):
# TODO: implement
db = req.state.db
if params.host is not None:
# delete a pillar at the host level
target_stmt = select(Host).where(and_(Host.name == params.host, Host.is_hostgroup == False))
result = db.execute(target_stmt).fetchall()
if len(result) == 0:
return JSONResponse(status_code=404, content={})
# this should be enforced by the database
assert len(result) == 1
target: Host = result[0][0]
elif params.hostgroup is not None:
# delete a pillar at the hostgroup level
path = split_and_validate_path(params.hostgroup)
if not path:
return JSONResponse(status_code=400, content={'message': "No target specified"})
last = None
current = None
# Note: both statements need to be present, since '==' will not work for None and 'is' will not work for a UUID
group_stmt = select(Host).where(and_(Host.is_hostgroup == True, Host.parent_id == bindparam('parent'), Host.name == bindparam('name')))
group_stmt_none = select(Host).where(and_(Host.is_hostgroup == True, Host.parent_id.is_(None), Host.name == bindparam('name')))
for label in path:
result = db.execute(group_stmt if last is not None else group_stmt_none, {'name': label, 'parent': last}).fetchall()
if len(result) == 0:
return JSONResponse(status_code=404, content={'message': f"No hostgroup named: {params.hostgroup}"})
# Note: this should be enforced by the database
assert len(result) == 1, f"Result: {[x[0].name for x in result]}"
current: Host = result[0][0]
last = current.id
target: Host = current
else:
return JSONResponse(status_code=400, content={
'message': "Either Host or Hostgroup needs to be set!"
})
delete_stmt = delete(Pillar).where(and_(Pillar.host_id == target.id, or_(Pillar.pillar_name == name, Pillar.pillar_name.like(f"{name}:%"))))
result = db.execute(delete_stmt)
return JSONResponse(status_code=200, content={'message': 'ok'})