diff --git a/argos/schemas/config.py b/argos/schemas/config.py index c0014ab..160b5ae 100644 --- a/argos/schemas/config.py +++ b/argos/schemas/config.py @@ -127,12 +127,18 @@ class Alert(BaseModel): unknown: List[str] +class GotifyUrl(BaseModel): + url: HttpUrl + tokens: List[str] + + class General(BaseModel): """Frequency for the checks and alerts""" frequency: int alerts: Alert mail: Optional[Mail] = None + gotify: Optional[List[GotifyUrl]] = None @field_validator("frequency", mode="before") def parse_frequency(cls, value): diff --git a/argos/server/alerting.py b/argos/server/alerting.py index 3c5c9c2..cb9ef62 100644 --- a/argos/server/alerting.py +++ b/argos/server/alerting.py @@ -1,10 +1,14 @@ import ssl import smtplib +from typing import List from urllib.parse import urlparse +import httpx + +from argos.checks.base import Severity from argos.logging import logger -from argos.schemas.config import Config, Mail +from argos.schemas.config import Config, Mail, GotifyUrl # XXX Implement mail alerts https://framagit.org/framasoft/framaspace/argos/-/issues/15 # XXX Implement gotify alerts https://framagit.org/framasoft/framaspace/argos/-/issues/16 @@ -14,22 +18,25 @@ def handle_alert(config: Config, result, task, severity): msg = f"task={task.id}, status={result.status}, {severity=}" logger.error("Alerting stub: %s", msg) - if config.general.mail is not None: - logger.debug('Will send mail notification') - - subject = f"[Argos] {urlparse(task.url).netloc}: status {severity}" + if config.general.mail is not None or config.general.gotify is not None: + subject = f"{urlparse(task.url).netloc}: status {severity}" msg = f"""\ URL: {task.url} Check: {task.check} Status: {severity} Time: {result.submitted_at} """ - notify_by_mail(subject, msg, config.general.mail) + + if config.general.mail is not None: + notify_by_mail(subject, msg, config.general.mail) + if config.general.gotify is not None: + notify_with_gotify(subject, msg, severity, config.general.gotify) def notify_by_mail(subject: str, msg: str, config: Mail) -> None: + logger.debug('Will send mail notification') mail = f"""\ -Subject: {subject} +Subject: [Argos] {subject} {msg}""" @@ -56,3 +63,33 @@ Subject: {subject} logger.debug('Sending mail to %s', address) logger.debug(msg) smtp.sendmail(config.mailfrom, address, mail) + + +def notify_with_gotify(subject: str, msg: str, severity: str, config: List[GotifyUrl]) -> None: + logger.debug('Will send gotify notification') + headers = {'accept': 'application/json', + 'content-type': 'application/json'} + + priority = 9 + if severity == Severity.OK: + priority = 1 + elif severity == Severity.WARNING: + priority = 5 + + payload = {'title': subject, + 'message': msg, + 'priority': priority} + + for url in config: + logger.debug('Sending gotify message(s) to %s', url) + for token in url.tokens: + try: + res = httpx.post(f"{url.url}message", + params={'token': token}, + headers=headers, + json=payload) + res.raise_for_status() + except httpx.RequestError as exc: + logger.error('An error occurred while sending a message to %s with token %s', + exc.request.url, + token) diff --git a/config-example.yaml b/config-example.yaml index 4899989..8bbf908 100644 --- a/config-example.yaml +++ b/config-example.yaml @@ -22,6 +22,11 @@ general: # addresses: # - foo@admin.example.org # - bar@admin.example.org +# gotify: +# - url: https://example.org +# tokens: +# - foo +# - bar service: secrets: