mirror of
https://framagit.org/framasoft/framaspace/argos.git
synced 2025-04-28 09:52:38 +02:00
127 lines
4.1 KiB
Python
127 lines
4.1 KiB
Python
"""Web interface for machines"""
|
||
from typing import List, Union
|
||
|
||
from fastapi import APIRouter, BackgroundTasks, Depends, Request
|
||
from sqlalchemy.orm import Session
|
||
|
||
from argos_monitoring.logging import logger
|
||
from argos_monitoring.schemas import AgentResult, Config, Task
|
||
from argos_monitoring.server import queries
|
||
from argos_monitoring.server.alerting import handle_alert
|
||
from argos_monitoring.server.routes.dependencies import get_config, get_db, verify_token
|
||
|
||
route = APIRouter()
|
||
|
||
|
||
@route.get("/tasks", response_model=list[Task], dependencies=[Depends(verify_token)])
|
||
async def read_tasks(
|
||
request: Request,
|
||
db: Session = Depends(get_db),
|
||
limit: int = 10,
|
||
agent_id: Union[None, str] = None,
|
||
):
|
||
"""Return a list of tasks to execute"""
|
||
agent_id = agent_id or request.client.host
|
||
tasks = await queries.list_tasks(db, agent_id=agent_id, limit=limit)
|
||
return tasks
|
||
|
||
|
||
@route.post("/results", status_code=201, dependencies=[Depends(verify_token)])
|
||
async def create_results(
|
||
request: Request,
|
||
results: List[AgentResult],
|
||
background_tasks: BackgroundTasks,
|
||
db: Session = Depends(get_db),
|
||
config: Config = Depends(get_config),
|
||
agent_id: Union[None, str] = None,
|
||
):
|
||
"""Get the results from the agents and store them locally.
|
||
|
||
- Finalize the checks (some checks need the server to do some part of the validation,
|
||
for instance because they need access to the configuration)
|
||
- If it's an error, determine its severity ;
|
||
- Trigger the reporting calls
|
||
"""
|
||
agent_id = agent_id or request.client.host
|
||
db_results = []
|
||
for agent_result in results:
|
||
# XXX Maybe offload this to a queue.
|
||
# XXX Get all the tasks at once, to limit the queries on the db
|
||
task = await queries.get_task(db, agent_result.task_id)
|
||
if not task:
|
||
logger.error("Unable to find task %i", agent_result.task_id)
|
||
else:
|
||
last_severity = task.severity
|
||
result = await queries.create_result(db, agent_result, agent_id)
|
||
check = task.get_check()
|
||
status, severity = await check.finalize(config, result, **result.context)
|
||
result.set_status(status, severity)
|
||
task.set_times_severity_and_deselect(severity, result.submitted_at)
|
||
|
||
# Don’t create an alert if the severity has not changed
|
||
if last_severity != severity:
|
||
background_tasks.add_task(
|
||
handle_alert, config, result, task, severity, last_severity, request
|
||
)
|
||
|
||
db_results.append(result)
|
||
db.commit()
|
||
return {"result_ids": [r.id for r in db_results]}
|
||
|
||
|
||
@route.post(
|
||
"/reschedule/all",
|
||
responses={
|
||
200: {
|
||
"content": {
|
||
"application/json": {"example": {"msg": "Non OK tasks reschuled"}}
|
||
}
|
||
}
|
||
},
|
||
)
|
||
async def reschedule_all(request: Request, db: Session = Depends(get_db)):
|
||
"""Reschedule checks of all non OK tasks ASAP"""
|
||
await queries.reschedule_all(db)
|
||
return {"msg": "Non OK tasks reschuled"}
|
||
|
||
|
||
@route.get(
|
||
"/stats",
|
||
responses={
|
||
200: {
|
||
"content": {
|
||
"application/json": {
|
||
"example": {
|
||
"upcoming_tasks_count": 0,
|
||
"results_count": 1993085,
|
||
"selected_tasks_count": 1845,
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
)
|
||
async def get_stats(db: Session = Depends(get_db)):
|
||
"""Get tasks statistics"""
|
||
return {
|
||
"upcoming_tasks_count": await queries.count_tasks(db, selected=False),
|
||
"results_count": await queries.count_results(db),
|
||
"selected_tasks_count": await queries.count_tasks(db, selected=True),
|
||
}
|
||
|
||
|
||
@route.get(
|
||
"/severities",
|
||
responses={
|
||
200: {
|
||
"content": {
|
||
"application/json": {
|
||
"example": {"ok": 1541, "warning": 0, "critical": 0, "unknown": 0}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
)
|
||
async def get_severity_counts(db: Session = Depends(get_db)):
|
||
"""Returns the number of results per severity"""
|
||
return await queries.get_severity_counts(db)
|