|
3 | 3 | from pathlib import Path |
4 | 4 | from typing import Dict, List, Optional |
5 | 5 |
|
| 6 | +import requests |
6 | 7 | from fastapi import APIRouter, Depends, Request |
7 | | -from fastapi.responses import FileResponse |
| 8 | +from fastapi.responses import FileResponse, JSONResponse |
8 | 9 | from pydantic import BaseModel |
9 | 10 | from sqlmodel import select |
10 | 11 |
|
@@ -276,6 +277,94 @@ def update_current_gain_ref( |
276 | 277 | db.commit() |
277 | 278 |
|
278 | 279 |
|
| 280 | +# Endpoints for turning alerts on and off |
| 281 | + |
| 282 | + |
| 283 | +@router.get("/silences/{instrument_name}") |
| 284 | +def get_silences(instrument_name: MurfeyInstrumentName): |
| 285 | + all_configs = get_machine_config() |
| 286 | + valid_instrument_names = list(all_configs.keys()) |
| 287 | + if instrument_name in valid_instrument_names: |
| 288 | + index = valid_instrument_names.index(instrument_name) |
| 289 | + query_params = f"filter=microscope={sanitise(valid_instrument_names[index])}" |
| 290 | + else: |
| 291 | + logger.warning( |
| 292 | + f"invalid query parameters for get alerts on {sanitise(instrument_name)}" |
| 293 | + ) |
| 294 | + return [] |
| 295 | + machine_config = all_configs[instrument_name] |
| 296 | + alertmanager_url = machine_config.alertmanager_url |
| 297 | + if not alertmanager_url: |
| 298 | + logger.warning(f"alertmanager_url not set for {sanitise(instrument_name)}") |
| 299 | + return [] |
| 300 | + response = requests.get(f"{alertmanager_url}/api/v2/silences?{query_params}") |
| 301 | + if response.status_code != 200: |
| 302 | + logger.warning( |
| 303 | + f"Tried to get silences for {sanitise(instrument_name)}, but received status {response.status_code} from alertmanager API" |
| 304 | + ) |
| 305 | + active_silences = [] |
| 306 | + for silence in response.json(): |
| 307 | + if silence["status"]["state"] == "active": |
| 308 | + active_silences.append(silence) |
| 309 | + return active_silences |
| 310 | + |
| 311 | + |
| 312 | +@router.post("/silences/{instrument_name}") |
| 313 | +def create_silence( |
| 314 | + instrument_name: MurfeyInstrumentName, end_time: datetime |
| 315 | +) -> JSONResponse: |
| 316 | + machine_config = machine_info_by_instrument(instrument_name) |
| 317 | + alertmanager_url = machine_config.alertmanager_url |
| 318 | + if not alertmanager_url: |
| 319 | + logger.warning(f"alertmanager_url not set for {sanitise(instrument_name)}") |
| 320 | + return JSONResponse( |
| 321 | + status_code=500, content="URL not set. Could not turn off alerts" |
| 322 | + ) |
| 323 | + start_time = datetime.now().astimezone().isoformat() |
| 324 | + end_time_str = end_time.astimezone().isoformat() |
| 325 | + silence_json = { |
| 326 | + "matchers": [ |
| 327 | + {"name": "microscope", "value": instrument_name, "isRegex": False} |
| 328 | + ], |
| 329 | + "createdBy": "murfey", |
| 330 | + "annotations": {"description": f"Silence for alerts on {instrument_name}"}, |
| 331 | + "comment": "silence created from murfey", |
| 332 | + "status": {"state": "active"}, |
| 333 | + "startsAt": str(start_time), |
| 334 | + "endsAt": str(end_time_str), |
| 335 | + } |
| 336 | + response = requests.post(f"{alertmanager_url}/api/v2/silences", json=silence_json) |
| 337 | + if response.status_code != 200: |
| 338 | + logger.warning( |
| 339 | + f"Create silence for {sanitise(instrument_name)} received status {response.status_code} from alertmanager API" |
| 340 | + ) |
| 341 | + return JSONResponse( |
| 342 | + status_code=response.status_code, content=response.json() |
| 343 | + ) # return a response with same data and code as from alertmanager |
| 344 | + |
| 345 | + |
| 346 | +@router.delete( |
| 347 | + "/silences/{instrument_name}" |
| 348 | +) # delete all silences for given microscope |
| 349 | +def delete_silences(instrument_name: MurfeyInstrumentName): |
| 350 | + machine_config = machine_info_by_instrument(instrument_name) |
| 351 | + alertmanager_url = machine_config.alertmanager_url |
| 352 | + if not alertmanager_url: |
| 353 | + logger.warning(f"alertmanager_url not set for {sanitise(instrument_name)}") |
| 354 | + return JSONResponse(status_code=500, content="URL not set") |
| 355 | + silences = get_silences(instrument_name) |
| 356 | + if not silences: |
| 357 | + return {"success": False} |
| 358 | + for silence in silences: |
| 359 | + id = silence["id"] |
| 360 | + response = requests.delete(f"{alertmanager_url}/api/v2/silence/{id}") |
| 361 | + if response.status_code != 200: |
| 362 | + logger.warning( |
| 363 | + f"Delete silence {id} for {sanitise(instrument_name)} received status {response.status_code} from alertmanager API" |
| 364 | + ) |
| 365 | + return response # returns final response in loop |
| 366 | + |
| 367 | + |
279 | 368 | spa_router = APIRouter( |
280 | 369 | prefix="/session_info/spa", |
281 | 370 | dependencies=[Depends(validate_token)], |
|
0 commit comments