Skip to content

Commit 85f45f8

Browse files
Add endpoints to get, post and delete silences (#798)
- GET returns gets all Active microscope for specified instrument - POST creates a new silence until given end time (turns off alerts) for specified instrument - DELETE removes ALL existing silences for specified instrument. Requires alertmanager_url to be set in config.
1 parent 82b4177 commit 85f45f8

3 files changed

Lines changed: 112 additions & 1 deletion

File tree

src/murfey/server/api/session_info.py

Lines changed: 90 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,9 @@
33
from pathlib import Path
44
from typing import Dict, List, Optional
55

6+
import requests
67
from fastapi import APIRouter, Depends, Request
7-
from fastapi.responses import FileResponse
8+
from fastapi.responses import FileResponse, JSONResponse
89
from pydantic import BaseModel
910
from sqlmodel import select
1011

@@ -276,6 +277,94 @@ def update_current_gain_ref(
276277
db.commit()
277278

278279

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+
279368
spa_router = APIRouter(
280369
prefix="/session_info/spa",
281370
dependencies=[Depends(validate_token)],

src/murfey/util/config.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@ class MachineConfig(BaseModel): # type: ignore
109109
frontend_url: str = "http://localhost:3000"
110110
instrument_server_url: str = "http://localhost:8001"
111111
smartem_api_url: str = ""
112+
alertmanager_url: str = ""
112113

113114
# Messaging queues
114115
failure_queue: str = ""

src/murfey/util/route_manifest.yaml

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1153,6 +1153,27 @@ murfey.server.api.session_info.router:
11531153
type: int
11541154
methods:
11551155
- PUT
1156+
- path: /session_info/silences/{instrument_name}
1157+
function: get_silences
1158+
path_params:
1159+
- name: instrument_name
1160+
type: str
1161+
methods:
1162+
- GET
1163+
- path: /session_info/silences/{instrument_name}
1164+
function: create_silence
1165+
path_params:
1166+
- name: instrument_name
1167+
type: str
1168+
methods:
1169+
- POST
1170+
- path: /session_info/silences/{instrument_name}
1171+
function: delete_silences
1172+
path_params:
1173+
- name: instrument_name
1174+
type: str
1175+
methods:
1176+
- DELETE
11561177
murfey.server.api.session_info.spa_router:
11571178
- path: /session_info/spa/sessions/{session_id}/spa_processing_parameters
11581179
function: get_spa_proc_param_details

0 commit comments

Comments
 (0)