86 lines
2.7 KiB
Python
86 lines
2.7 KiB
Python
import uuid
|
|
|
|
from sqlalchemy import select, insert, delete, bindparam
|
|
from sqlalchemy.orm import Session
|
|
from starlette.exceptions import HTTPException
|
|
from starlette.requests import Request
|
|
from fastapi import APIRouter, Depends
|
|
from starlette.responses import JSONResponse
|
|
|
|
from pillar_tool.db import Host
|
|
from pillar_tool.db.models.top_data import State, StateAssignment
|
|
from pillar_tool.db.queries.pillar_queries import get_pillar_for_target
|
|
from pillar_tool.schemas import PillarParams, get_model_from_query
|
|
from pillar_tool.util.pillar_utilities import merge
|
|
from pillar_tool.util.validation import validate_state_name, validate_fqdn
|
|
|
|
router = APIRouter(
|
|
prefix="/pillar",
|
|
tags=["pillar"],
|
|
)
|
|
|
|
# Note: there is no list of all pillars, as this would not be helpful
|
|
|
|
@router.get("/{fqdn}")
|
|
def pillar_get(req: Request, fqdn: str):
|
|
# 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
|
|
|
|
# get the host hierarchy
|
|
host_stmt = select(Host).where(Host.name == fqdn and Host.is_hostgroup == False)
|
|
result = db.execute(host_stmt).fetchall()
|
|
if len(result) == 0:
|
|
return JSONResponse(status=404, content={})
|
|
# NOTE: should be enforced by the database
|
|
assert len(result) == 1
|
|
|
|
host: Host = result[0][0]
|
|
path: list[Host] = [host]
|
|
parent_stmt = select(Host).where(Host.id == bindparam('parent'))
|
|
while path[-1].parent_id is not None:
|
|
result = db.execute(parent_stmt, {'parent': path[-1].parent_id}).fetchall()
|
|
# NOTE: should be enforced by the database
|
|
assert len(result) == 1
|
|
tmp: Host = result[0][0]
|
|
path.append(tmp)
|
|
|
|
path.reverse()
|
|
out = merge(get_pillar_for_target(db, host.id) for host in path)
|
|
|
|
return JSONResponse(status_code=200, content={})
|
|
|
|
|
|
|
|
@router.post("/{name}")
|
|
def pillar_create(req: Request, name: str, params: PillarParams):
|
|
db = req.state.db
|
|
|
|
# ensure that value and type have been set in the request parameters
|
|
if params.type is None or params.value is None:
|
|
|
|
|
|
target_stmt = select(Host).where(Host.name == name)
|
|
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]
|
|
|
|
|
|
|
|
|
|
|
|
@router.delete("/{name}")
|
|
def pillar_delete(req: Request, name: str):
|
|
# TODO: implement
|
|
db = req.state.db
|