refactoring on the pillar router

This commit is contained in:
Linus Vogel 2026-05-14 19:45:42 +02:00
parent 67ed4f686d
commit 5ad0cff79b

View File

@ -28,13 +28,6 @@ router = APIRouter(
@router.get("/{target}") @router.get("/{target}")
def pillar_get(req: Request, target: str) -> JSONResponse: def pillar_get(req: Request, target: str) -> JSONResponse:
# TODO: implement
# this function should:
# - get the affected host hierarchy
# - get all the relevant pillar dictionaries
# - merge the pillar directories
# - return the merged pillar directory
# if any error happens, return non-200 status and an empty dictionary so that salt does not shit itself
db: Session = req.state.db db: Session = req.state.db
print("[DEBUG] pillar_get: retrieving pillar data for target '{}'".format(target)) print("[DEBUG] pillar_get: retrieving pillar data for target '{}'".format(target))
@ -92,7 +85,7 @@ def pillar_get(req: Request, target: str) -> JSONResponse:
print("[DEBUG] pillar_get: resolved host hierarchy with {} hosts: {}".format(len(path), [h.name for h in path])) print("[DEBUG] pillar_get: resolved host hierarchy with {} hosts: {}".format(len(path), [h.name for h in path]))
out = merge([get_pillar_for_target(db, host.id) for host in path]) out = merge([get_pillar_for_target(db, host.id) for host in path]) # type: ignore
print("[DEBUG] pillar_get: merged pillar data contains {} top-level key(s)".format(len(out))) print("[DEBUG] pillar_get: merged pillar data contains {} top-level key(s)".format(len(out)))
return JSONResponse(status_code=200, content=out) return JSONResponse(status_code=200, content=out)
@ -133,7 +126,7 @@ def pillar_create(req: Request, name: str, params: PillarParams):
print("[DEBUG] pillar_create: ERROR - Hostgroup path '{}' could not be parsed or validated.".format(params.hostgroup)) print("[DEBUG] pillar_create: ERROR - Hostgroup path '{}' could not be parsed or validated.".format(params.hostgroup))
return JSONResponse(status_code=400, content={'message': "No target specified"}) return JSONResponse(status_code=400, content={'message': "No target specified"})
last = None last = None
current = None current: Host | None = None
# Note: both statements need to be present, since '==' will not work for None and 'is' will not work for a UUID # 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 = 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'))) group_stmt_none = select(Host).where(and_(Host.is_hostgroup == True, Host.parent_id.is_(None), Host.name == bindparam('name')))
@ -144,8 +137,8 @@ def pillar_create(req: Request, name: str, params: PillarParams):
return JSONResponse(status_code=404, content={'message': f"No hostgroup named: {params.hostgroup}"}) return JSONResponse(status_code=404, content={'message': f"No hostgroup named: {params.hostgroup}"})
# Note: this should be enforced by the database # Note: this should be enforced by the database
assert len(result) == 1, f"Result: {[x[0].name for x in result]}" assert len(result) == 1, f"Result: {[x[0].name for x in result]}"
current: Host = result[0][0] current: Host | None = result[0][0]
last = current.id last = current.id # type: ignore
target: Host = current target: Host = current
else: else:
print("[DEBUG] pillar_create: ERROR - Neither host nor hostgroup specified in request parameters.") print("[DEBUG] pillar_create: ERROR - Neither host nor hostgroup specified in request parameters.")
@ -176,14 +169,14 @@ def pillar_create(req: Request, name: str, params: PillarParams):
{ 'name': name, 'value': params.value, 'type': params.type } { 'name': name, 'value': params.value, 'type': params.type }
] ]
print("[DEBUG] pillar_create: storing {} pillar entry/entries for target '{}' (id={})".format(len(pillars_to_store), target.name, target.id)) print("[DEBUG] pillar_create: storing {} pillar entry/entries for target '{}' (id={})".format(len(pillars_to_store), target.name, target.id)) # type: ignore
# store pillar data # store pillar data
insert_stmt = insert(Pillar).values(id=bindparam('new_id'), host_id=target.id, pillar_name=bindparam('name'), parameter_type=bindparam('type'), value=bindparam('value')) insert_stmt = insert(Pillar).values(id=bindparam('new_id'), host_id=target.id, pillar_name=bindparam('name'), parameter_type=bindparam('type'), value=bindparam('value'))
upsert_stmt = insert_stmt.on_conflict_do_update(constraint='pillar_unique_pillar_name', set_={'parameter_type': bindparam('type'), 'value': bindparam('value')} ) upsert_stmt = insert_stmt.on_conflict_do_update(constraint='pillar_unique_pillar_name', set_={'parameter_type': bindparam('type'), 'value': bindparam('value')} )
for instance in pillars_to_store: for instance in pillars_to_store:
instance['new_id'] = uuid4() instance['new_id'] = uuid4() # type: ignore
result = db.execute(upsert_stmt, instance) result = db.execute(upsert_stmt, instance)
print("[DEBUG] pillar_create: successfully stored pillar '{}'".format(name)) print("[DEBUG] pillar_create: successfully stored pillar '{}'".format(name))
@ -220,7 +213,7 @@ def pillar_delete(req: Request, name: str, params: PillarParams):
print("[DEBUG] pillar_delete: ERROR - Hostgroup path '{}' could not be parsed or validated.".format(params.hostgroup)) print("[DEBUG] pillar_delete: ERROR - Hostgroup path '{}' could not be parsed or validated.".format(params.hostgroup))
return JSONResponse(status_code=400, content={'message': "No target specified"}) return JSONResponse(status_code=400, content={'message': "No target specified"})
last = None last = None
current = None current: Host | None = None
# Note: both statements need to be present, since '==' will not work for None and 'is' will not work for a UUID # 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 = 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'))) group_stmt_none = select(Host).where(and_(Host.is_hostgroup == True, Host.parent_id.is_(None), Host.name == bindparam('name')))
@ -231,8 +224,8 @@ def pillar_delete(req: Request, name: str, params: PillarParams):
return JSONResponse(status_code=404, content={'message': f"No hostgroup named: {params.hostgroup}"}) return JSONResponse(status_code=404, content={'message': f"No hostgroup named: {params.hostgroup}"})
# Note: this should be enforced by the database # Note: this should be enforced by the database
assert len(result) == 1, f"Result: {[x[0].name for x in result]}" assert len(result) == 1, f"Result: {[x[0].name for x in result]}"
current: Host = result[0][0] current: Host | None = result[0][0]
last = current.id last = current.id # type: ignore
target: Host = current target: Host = current
else: else:
print("[DEBUG] pillar_delete: ERROR - Neither host nor hostgroup specified in request parameters.") print("[DEBUG] pillar_delete: ERROR - Neither host nor hostgroup specified in request parameters.")
@ -240,10 +233,10 @@ def pillar_delete(req: Request, name: str, params: PillarParams):
'message': "Either Host or Hostgroup needs to be set!" 'message': "Either Host or Hostgroup needs to be set!"
}) })
print("[DEBUG] pillar_delete: deleting pillar '{}' (and sub-pillars '{}.*') from target '{}' (id={})".format(name, name, target.name, target.id)) print("[DEBUG] pillar_delete: deleting pillar '{}' (and sub-pillars '{}.*') from target '{}' (id={})".format(name, name, target.name, target.id)) # type: ignore
delete_stmt = delete(Pillar).where(and_(Pillar.host_id == target.id, or_(Pillar.pillar_name == name, Pillar.pillar_name.like(f"{name}:%")))) delete_stmt = delete(Pillar).where(and_(Pillar.host_id == target.id, or_(Pillar.pillar_name == name, Pillar.pillar_name.like(f"{name}:%")))) # type: ignore
result = db.execute(delete_stmt) result = db.execute(delete_stmt)
print("[DEBUG] pillar_delete: successfully deleted pillar '{}' from target '{}'".format(name, target.name)) print("[DEBUG] pillar_delete: successfully deleted pillar '{}' from target '{}'".format(name, target.name)) # type: ignore
return JSONResponse(status_code=200, content={'message': 'ok'}) return JSONResponse(status_code=200, content={'message': 'ok'})