Make it possible to specify the frequency with '1d'

This commit is contained in:
Alexis Métaireau 2023-10-11 11:11:57 +02:00
parent ca6584c803
commit daa22708c4
5 changed files with 134 additions and 14 deletions

View file

@ -16,7 +16,8 @@ Features :
- [x] Change the naming and use service/agent.
- [x] Packaging (and `argos agent` / `argos service` commands)
- [x] Endpoints are protected by an authentication token
- [ ] Find a way to define when the task should be checked again (via config ? stored on the tasks themselves ?)
- [ ] Task frequency can be defined in the configuration
- [ ] Add a command to generate new authentication tokens
- [ ] Local task for database cleanup (to run periodically)
- [ ] Handles multiple alerting backends (email, sms, gotify) ;
- [ ] Exposes a simple read-only website.

View file

@ -7,6 +7,8 @@ import yaml
from pydantic import BaseModel, Field, HttpUrl, validator
from yamlinclude import YamlIncludeConstructor
from argos.schemas.utils import string_to_duration
# XXX Find a way to check without having cirular imports
# This file contains the pydantic schemas. For the database models, check in argos.model.
@ -21,17 +23,9 @@ class SSL(BaseModel):
@validator("thresholds", each_item=True, pre=True)
def parse_threshold(cls, value):
for duration_str, severity in value.items():
num = int("".join(filter(str.isdigit, duration_str)))
if "d" in duration_str:
num = num
elif "w" in duration_str:
num = num * 7
elif "m" in duration_str:
num = num * 30
else:
raise ValueError("Invalid duration value")
days = string_to_duration(duration_str, "days")
# Return here because it's one-item dicts.
return (num, severity)
return (days, severity)
class WebsiteCheck(BaseModel):
@ -63,8 +57,7 @@ class WebsitePath(BaseModel):
@validator("checks", each_item=True, pre=True)
def parse_checks(cls, value):
from argos.checks import \
get_registered_checks # To avoid circular imports
from argos.checks import get_registered_checks # To avoid circular imports
available_names = get_registered_checks().keys()
@ -95,6 +88,10 @@ class General(BaseModel):
frequency: str
alerts: Alert
@validator("frequency", pre=True)
def parse_frequency(cls, value):
return string_to_duration(value, "hours")
class Config(BaseModel):
general: General

30
argos/schemas/utils.py Normal file
View file

@ -0,0 +1,30 @@
from typing import Literal
def string_to_duration(value: str, target: Literal["days", "hours"]):
"""Convert a string to a number of hours, or days"""
num = int("".join(filter(str.isdigit, value)))
if target == "hours":
reconvert = True
if "h" in value:
if target == "days":
raise ValueError("Invalid duration value", value)
num = num
reconvert = False
elif "d" in value:
num = num
elif "w" in value:
num = num * 7
elif "m" in value:
num = num * 30
elif "y" in value:
num = num * 365
else:
raise ValueError("Invalid duration value", value)
if target == "hours" and reconvert:
num = num * 24
return num

View file

@ -19,4 +19,75 @@ ssl:
- "1d": critical
"5d": warning
websites: !include websites.yaml
# It's also possible to define the checks in another file
# with the include syntax:
#
# websites: !include websites.yaml
#
websites:
- domain: "https://mypads.framapad.org"
paths:
- path: "/mypads/"
checks:
- status-is: 200
- body-contains: '<div id= "mypads"></div>'
- ssl-certificate-expiration: "on-check"
- path: "/admin/"
checks:
- status-is: 401
- domain: "https://munin.framasoft.org"
paths:
- path: "/"
checks:
- status-is: 301
- path: "/munin/"
checks:
- status-is: 401
- domain: "https://framagenda.org"
paths:
- path: "/status.php"
checks:
- status-is: 200
# Là, idéalement, il faudrait un json-contains,
# qui serait une table de hachage
- body-contains: '"maintenance":false'
- ssl-certificate-expiration: "on-check"
- path: "/"
checks:
- status-is: 302
- path: "/login"
checks:
- status-is: 200
- domain: "https://framadrive.org"
paths:
- path: "/status.php"
checks:
- status-is: 200
- body-contains: '"maintenance":false'
- ssl-certificate-expiration: "on-check"
- path: "/"
checks:
- status-is: 302
- path: "/login"
checks:
- status-is: 200
- domain: "https://cloud.framabook.org"
paths:
- path: "/status.php"
checks:
- status-is: 200
- body-contains: '"maintenance":false'
- ssl-certificate-expiration: "on-check"
- path: "/"
checks:
- status-is: 302
- path: "/login"
checks:
- status-is: 200
- domain: "https://framasoft.org"
paths:
- path: "/"
checks:
- status-is: 200
- ssl-certificate-expiration: "on-check"

View file

@ -0,0 +1,21 @@
import pytest
from argos.schemas.utils import string_to_duration
def test_string_to_duration_days():
assert string_to_duration("1d", target="days") == 1
assert string_to_duration("1w", target="days") == 7
assert string_to_duration("3w", target="days") == 21
assert string_to_duration("3m", target="days") == 90
assert string_to_duration("1y", target="days") == 365
with pytest.raises(ValueError):
string_to_duration("3h", target="days")
def test_string_to_duration_hours():
assert string_to_duration("1h", target="hours") == 1
assert string_to_duration("1d", target="hours") == 24
assert string_to_duration("1w", target="hours") == 7 * 24
assert string_to_duration("3w", target="hours") == 21 * 24
assert string_to_duration("3m", target="hours") == 3 * 30 * 24