96 lines
3.4 KiB
Python

import uuid
from sqlalchemy import select, insert, delete, and_, 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, Environment, EnvironmentAssignment
from pillar_tool.db.models.top_data import State, StateAssignment
from pillar_tool.util.validation import validate_state_name
router = APIRouter(
prefix="/top",
tags=["top"],
)
@router.get("/query/{host}")
def top_get(req: Request, host: str):
db: Session = req.state.db
# build the hierarchy
host_stmt = select(Host).where(Host.name == host)
result = db.execute(host_stmt).fetchall()
if len(result) == 0:
return JSONResponse(status_code=404, content={"message": "Host '{}' not found".format(host)})
elif len(result) > 1:
return JSONResponse(status_code=500, content={"message": "More than one host found"})
else:
target_host = result[0][0]
parent_stmt = select(Host).where(Host.id == bindparam("parent_id"))
parents = []
current = target_host
while current is not None:
result = db.execute(parent_stmt, {'parend_id': current.id}).fetchall()
if len(result) == 0:
current = None
elif len(result) > 1:
return JSONResponse(status_code=500, content={"message": "More than one parent host found"})
else:
parents.append(result[0][0])
current = result[0][0]
# TODO: states should be hierarchical, same as pillars are
select_stmt = (select(Host, EnvironmentAssignment, Environment)
.where(and_(Host.name == host, Host.is_hostgroup == False))
.join(EnvironmentAssignment, EnvironmentAssignment.host_id == Host.id)
.join(Environment, EnvironmentAssignment.environment_id == Environment.id)
)
result = db.execute(select_stmt).fetchall()
print(result[0])
return JSONResponse(status_code=200, content={})
@router.post("/setenv/{host}/{environment}")
def top_setenv(req: Request, host: str, environment: str):
db: Session = req.state.db
# get the target host id
host_stmt = select(Host).where(and_(Host.name == host, Host.is_hostgroup == False))
host_res = db.execute(host_stmt).fetchall()
if len(host_res) == 0:
return JSONResponse(status_code=404, content={"error": "No host found"})
elif len(host_res) == 1:
host_res = host_res[0][0]
else:
# Note that this should be prevented by the database
return JSONResponse(status_code=404, content={"error": "Too many hosts found??? This should not happen"})
# get the environment id
env_stmt = select(Environment).where(Environment.name == environment)
env_res = db.execute(env_stmt).fetchall()
if len(env_res) == 0:
return JSONResponse(status_code=404, content={"error": "No environment found"})
elif len(env_res) == 1:
env_res = env_res[0][0]
else:
# Note that this should be prevented by the database
return JSONResponse(status_code=404, content={"error": "Too many environments found??? This should not happen"})
insert_stmt = insert(EnvironmentAssignment).values(environment_id=env_res.id, host_id=host_res.id)
result = db.execute(insert_stmt)
return JSONResponse(status_code=200, content={})
def top_state_assign(req: Request):
pass