argos/argos_monitoring/server/routes/api.py
Luc Didry 4880c65681
💥 — Rename argos to argos-monitoring to fit the package name (fix #53)
Uninstall argos with `pip uninstall argos-monitoring` before installing this release!
2024-07-04 09:44:07 +02:00

127 lines
4.1 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""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)
# Dont 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)