core/source/logic/conf.py
2023-02-06 16:06:18 +01:00

320 lines
7.3 KiB
Python

def conf_schema_active():
return {
"description": "whether the check shall be executed",
"type": "boolean",
"default": True,
}
def conf_schema_threshold():
return {
"description": "how often a condition has to occur in order to be reported",
"type": "integer",
"minimum": 1,
"default": 3,
}
def conf_schema_annoy():
return {
"description": "whether notifications shall be kept sending after the threshold has been surpassed",
"type": "boolean",
"default": False,
}
def conf_schema_interval(default):
return {
"anyOf": [
{
"description": "in seconds",
"type": "integer",
"exclusiveMinimum": 0,
},
{
"description": "as text",
"type": "string",
"enum": [
"minute",
"hour",
"day",
"week",
]
},
],
"default": default,
}
def conf_schema_schedule():
return {
"type": "object",
"additionalProperties": False,
"properties": {
"regular_interval": conf_schema_interval(60 * 60),
"attentive_interval": conf_schema_interval(60 * 2),
},
"required": [
],
}
def conf_schema_notifications(notification_channel_implementations):
return {
"type": "array",
"items": {
"anyOf": list(
map(
lambda pair: {
"title": ("notification channel '%s'" % pair[0]),
"type": "object",
"unevaluatedProperties": False,
"properties": {
"kind": {
"type": "string",
"enum": [pair[0]]
},
"parameters": pair[1].parameters_schema(),
},
"required": [
"kind",
"parameters"
],
},
notification_channel_implementations.items()
)
)
},
"default": [
{
"kind": "console",
"parameters": {
}
},
],
}
def conf_schema_root(check_kind_implementations, notification_channel_implementations):
return {
"type": "object",
"additionalProperties": False,
"properties": {
"defaults": {
"description": "default values for checks",
"type": "object",
"additionalProperties": False,
"properties": {
"active": conf_schema_active(),
"threshold": conf_schema_threshold(),
"annoy": conf_schema_annoy(),
"schedule": conf_schema_schedule(),
"notifications": conf_schema_notifications(notification_channel_implementations),
},
"required": [
],
},
"checks": {
"type": "array",
"items": {
"allOf": [
{
"description": "should represent a specific check",
"type": "object",
"unevaluatedProperties": False,
"properties": {
"name": {
"type": "string"
},
"title": {
"type": "string"
},
"active": conf_schema_active(),
"threshold": conf_schema_threshold(),
"annoy": conf_schema_annoy(),
"schedule": conf_schema_schedule(),
"notifications": conf_schema_notifications(notification_channel_implementations),
},
"required": [
"name",
],
},
{
"anyOf": list(
map(
lambda pair: {
"title": ("check '%s'" % pair[0]),
"type": "object",
"unevaluatedProperties": False,
"properties": {
"kind": {
"type": "string",
"enum": [pair[0]]
},
"parameters": pair[1].parameters_schema(),
},
"required": [
"kind",
"parameters",
]
},
check_kind_implementations.items()
)
),
},
]
}
}
},
"required": [
"defaults",
"checks",
]
}
def conf_normalize_interval(interval_raw):
if (type(interval_raw) == int):
return interval_raw
elif (type(interval_raw) == str):
map_ = {
"minute": (60),
"hour": (60 * 60),
"day": (60 * 60 * 24),
"week": (60 * 60 * 24 * 7),
}
if (interval_raw not in map_):
raise ValueError("invalid string interval value: %s" % interval_raw)
else:
return map_[interval_raw]
else:
raise ValueError("invalid type for interval value")
def conf_normalize_schedule(node):
node_ = dict_merge(
{
"regular_interval": (60 * 60),
"attentive_interval": (60 * 2),
},
node
)
return {
"regular_interval": conf_normalize_interval(node["regular_interval"]),
"attentive_interval": conf_normalize_interval(node["attentive_interval"]),
}
def conf_normalize_notification(notification_channel_implementations, node):
if (node["kind"] not in notification_channel_implementations):
raise ValueError("invalid notification kind: %s" % notification["kind"])
else:
return {
"kind": node["kind"],
"parameters": notification_channel_implementations[node["kind"]].normalize_conf_node(node["parameters"]),
}
def conf_normalize_defaults(notification_channel_implementations, node):
node_ = dict_merge(
{
"active": True,
"threshold": 3,
"annoy": False,
"schedule": {
"regular_interval": (60 * 60),
"attentive_interval": (60 * 2),
},
"notifications": [
],
},
node
)
return {
"active": node_["active"],
"threshold": node_["threshold"],
"annoy": node_["annoy"],
"schedule": node_["schedule"],
"notifications": list(
map(
lambda x: conf_normalize_notification(notification_channel_implementations, x),
node_["notifications"]
)
),
}
def conf_normalize_check(check_kind_implementations, notification_channel_implementations, defaults, node):
if ("name" not in node):
raise ValueError("missing mandatory field in 'check' node: 'name'")
else:
if ("kind" not in node):
raise ValueError("missing mandatory field in 'check' node: 'kind'")
else:
if (node["kind"] not in check_kind_implementations):
raise ValueError("invalid check kind: '%s'" % node["kind"])
else:
node_ = dict_merge(
{
"title": node["name"],
"active": defaults["active"],
"threshold": defaults["threshold"],
"annoy": defaults["annoy"],
"schedule": defaults["schedule"],
"notifications": defaults["notifications"],
"parameters": {},
},
node
)
return {
"name": node_["name"],
"title": node_["title"],
"active": node_["active"],
"threshold": node_["threshold"],
"annoy": node_["annoy"],
"schedule": conf_normalize_schedule(node_["schedule"]),
"notifications": list(
map(
lambda x: conf_normalize_notification(notification_channel_implementations, x),
node_["notifications"]
)
),
"kind": node_["kind"],
"parameters": check_kind_implementations[node_["kind"]].normalize_conf_node(node_["parameters"]),
}
def conf_normalize_root(check_kind_implementations, notification_channel_implementations, node):
counts = {}
for node_ in node["checks"]:
if (node_["name"] not in counts):
counts[node_["name"]] = 0
counts[node_["name"]] += 1
fails = list(filter(lambda pair: (pair[1] > 1), counts.items()))
if (len(fails) > 0):
raise ValueError(
string_coin(
"ambiguous check names: {{names}}",
{
"names": ",".join(counts.keys()),
}
)
)
else:
defaults = conf_normalize_defaults(notification_channel_implementations, node["defaults"])
return {
"defaults": defaults,
"checks": list(
map(
lambda node_: conf_normalize_check(
check_kind_implementations,
notification_channel_implementations,
defaults,
node_
),
node["checks"]
)
)
}