icinga2-checks/checker/result.py

119 lines
3.8 KiB
Python

import sys
def create_description_list(data: list):
"""
Create a Description List HTML element based on the input list.
Args:
data (list): A list containing lists, where each inner list has two elements:
the description term and the description details.
Returns:
str: A string containing the HTML representation of the description list.
Example:
data = [
["Description Term 1", "Description Details 1"],
["Description Term 2", "Description Details 2"],
["Description Term 3", "Description Details 3"],
]
html = create_description_list(data)
print(html)
"""
html = "<dl>"
for item in data:
html += f"<dt>{item[0]}</dt><dd>{item[1]}</dd>"
html += "</dl>"
return html
def dict_to_perfdata(data: dict, replace_dashes=True):
"""
Transforms a dictionary into Icinga2 perfdata format.
The input dictionary should have the following structure:
{
"item1": {
"value": any_type (required),
"warn": any_type (optional),
"crit": any_type (optional),
"min": any_type (optional),
"max": any_type (optional),
"unit": string (optional),
},
...
}
:param data: A dictionary containing the perfdata items and their values.
:type data: dict
:param replace_dashes: If True, replace dashes in perfdata names/keys with underscores. Default is True.
:type replace_dashes: bool
:return: A string in Icinga2 perfdata format.
:rtype: str
"""
perfdata = []
for key, values in data.copy().items():
# Remove values that are None
for k, v in values.copy().items():
if v is None:
del values[k]
if replace_dashes:
key = key.replace('-', '_')
item = f"{key.strip()}={values['value']}{values.get('unit', '')}"
for k in ['warn', 'crit', 'min', 'max']:
if k in values:
item += f";{values[k]}"
else:
item += ";"
perfdata.append(item)
return " ".join(perfdata)
def print_icinga2_check_status(text_result: str, return_code: int, perfdata=None):
"""
Prints the status of an Icinga2 check with the given text result, return code, and perfdata.
Example:
sample_text_result = "check is good, time 120s"
sample_return_code = 0
sample_perfdata = {
"time": {
"value": 120,
"warn": 3,
"crit": 100,
"min": 0,
"max": 200,
"unit": "s",
},
}
print_icinga2_check_status(sample_text_result, sample_return_code, sample_perfdata)
:param text_result: The text result of the check command.
:type text_result: str
:param return_code: The return code of the check (UNKNOWN=-1, OK=0, WARNING=1, CRITICAL=2).
:type return_code: int
:param perfdata: A dictionary containing the perfdata items and their values, defaults to an empty dictionary.
:type perfdata: dict, optional
:raises ValueError: If an invalid return code is passed.
"""
if perfdata is None:
perfdata = {}
status_codes = {
-1: "UNKNOWN",
0: "OK",
1: "WARNING",
2: "CRITICAL",
}
if return_code not in status_codes:
raise ValueError(f"Invalid return code: {return_code}")
status = status_codes[return_code]
perfdata_str = f' | {dict_to_perfdata(perfdata)}' if perfdata else ''
print(f"{status} - {text_result.strip()}{perfdata_str}")
def quit_check(text_result: str, exit_code: int, perfdata=None):
print_icinga2_check_status(text_result, exit_code, perfdata=perfdata)
sys.exit(exit_code)