Merge branch 'issue-1' into 'master'

Prüfung für Speichervebrauch auf entfernten System

See merge request tools/heimdall!3
This commit is contained in:
Christian Fraß 2023-03-04 14:32:32 +00:00
commit 868fd126e1
8 changed files with 223 additions and 3 deletions

View file

@ -605,6 +605,69 @@
"kind",
"parameters"
]
},
{
"title": "check 'generic_remote'",
"type": "object",
"unevaluatedProperties": false,
"properties": {
"kind": {
"type": "string",
"enum": [
"generic_remote"
]
},
"parameters": {
"type": "object",
"additionalProperties": false,
"properties": {
"ssh_host": {
"type": "string"
},
"ssh_port": {
"type": [
"null",
"integer"
],
"default": null
},
"ssh_user": {
"type": [
"null",
"string"
],
"default": null
},
"ssh_key": {
"type": [
"null",
"string"
],
"default": null
},
"mount_point": {
"type": "string",
"default": "/"
},
"threshold": {
"type": "integer",
"default": 95,
"description": "maximaler F\u00fcllstand in Prozent"
},
"strict": {
"type": "boolean",
"default": false
}
},
"required": [
"ssh_host"
]
}
},
"required": [
"kind",
"parameters"
]
}
]
}

View file

@ -0,0 +1,14 @@
{
"checks": [
{
"name": "test",
"kind": "generic_remote",
"parameters": {
"host": "bragi.pool.greenscale.de",
"ssh_user": "fenris",
"ssh_port": 8192,
"ssh_key": "/home/fenris/.ssh/keypairs/gs-bragi"
}
}
]
}

View file

@ -15,6 +15,7 @@
},
"includes": [
"script.hmdl.json",
"file_state.hmdl.json"
"file_state.hmdl.json",
"generic_remote.hmdl.json"
]
}

View file

@ -21,5 +21,6 @@
"checks.http_request.header_value_mismatch": "Header-Wert für Schlüssel '{{key}}' '{{value_actual}}' stimmt nicht mit erwartetem Wert {{value_expected}} überein",
"checks.http_request.body_misses_part": "Rumpf enthält nicht den erwarteten Teil '{{part}}'",
"misc.state_file_path": "Pfad zur Zustands-Datei",
"misc.check_procedure_failed": "Prüfungs-Prozedur fehlgeschlagen"
"misc.check_procedure_failed": "Prüfungs-Prozedur fehlgeschlagen",
"checks.generic_remote.overflow": "Festplatte fast voll"
}

View file

@ -21,5 +21,6 @@
"checks.http_request.header_value_mismatch": "actual header value for key '{{key}}' '{{value_actual}}' and does not match the expected value {{value_expected}}",
"checks.http_request.body_misses_part": "body does not contain the expected part '{{part}}'",
"misc.state_file_path": "state file path",
"misc.check_procedure_failed": "check procedure failed"
"misc.check_procedure_failed": "check procedure failed",
"checks.generic_remote.overflow": "harddisk full"
}

View file

@ -0,0 +1,137 @@
class implementation_check_kind_generic_remote(interface_check_kind):
'''
[implementation]
'''
def parameters_schema(self):
return {
"type": "object",
"additionalProperties": False,
"properties": {
"host" : {
"type" : "string"
},
"ssh_port": {
"type": ["null", "integer"],
"default": None
},
"ssh_user" : {
"type" : ["null", "string"],
"default": None,
},
"ssh_key" : {
"type" : ["null", "string"],
"default": None,
},
"mount_point" : {
"type" : "string",
"default" : "/"
},
"threshold" : {
"type" : "integer",
"default" : 95,
"description" : "maximaler Füllstand in Prozent"
},
"strict" : {
"type" : "boolean",
"default" : False
}
},
"required": [
"host"
]
}
'''
[implementation]
'''
def normalize_conf_node(self, node):
if (not "host" in node):
raise ValueError("mandatory parameter \"host\" missing")
else:
return dict_merge(
{
"ssh_port": None,
"ssh_user": None,
"ssh_key": None,
"mount_point": "/",
"threshold": 95,
"strict": False,
},
node
)
'''
[implementation]
'''
def run(self, parameters):
inner_command = string_coin(
"df {{mount_point}} | tr -s \" \"",
{
"mount_point": parameters["mount_point"],
}
)
outer_command_parts = []
if True:
outer_command_parts.append("ssh");
if True:
outer_command_parts.append(string_coin("{{host}}", {"host": parameters["host"]}));
if (parameters["ssh_port"] is not None):
outer_command_parts.append(string_coin("-p {{port}}", {"port": ("%u" % parameters["ssh_port"])}));
if (parameters["ssh_user"] is not None):
outer_command_parts.append(string_coin("-l {{user}}", {"user": parameters["ssh_user"]}));
if (parameters["ssh_key"] is not None):
outer_command_parts.append(string_coin("-i {{key}}", {"key": parameters["ssh_key"]}));
if True:
outer_command_parts.append(string_coin("-o BatchMode=yes", {}))
if True:
outer_command_parts.append(string_coin("'{{inner_command}}'", {"inner_command": inner_command}))
outer_command = " ".join(outer_command_parts)
result = shell_command(outer_command)
if (result["return_code"] > 0):
return {
"condition": enum_condition.unknown,
"info": {
"error": result["stderr"],
}
}
else:
stuff = result["stdout"].split("\n")[-2].split(" ")
data = {
"device": stuff[0],
"used": int(stuff[2]),
"avail": int(stuff[3]),
"perc": int(stuff[4][:-1]),
}
if (data["perc"] > parameters["threshold"]):
return {
"condition": (
enum_condition.critical
if parameters["strict"] else
enum_condition.warning
),
"info": {
"data": {
"host": parameters["host"],
"device": data["device"],
"mount_point": parameters["mount_point"],
"used": format_bytes(data["used"]),
"available": format_bytes(data["avail"]),
"percentage": (str(data["perc"]) + "%"),
},
"faults": [
translation_get("checks.generic_remote.overflow")
],
}
}
else:
return {
"condition": enum_condition.ok,
"info": {}
}

View file

@ -107,6 +107,7 @@ def main():
"script": implementation_check_kind_script(),
"file_state": implementation_check_kind_file_state(),
"http_request": implementation_check_kind_http_request(),
"generic_remote" : implementation_check_kind_generic_remote(),
}
### load notification channel implementations

View file

@ -47,6 +47,7 @@ def main():
_os.path.join(dir_source, "logic", "checks", "script.py"),
_os.path.join(dir_source, "logic", "checks", "file_state.py"),
_os.path.join(dir_source, "logic", "checks", "http_request.py"),
_os.path.join(dir_source, "logic", "checks", "generic_remote.py"),
_os.path.join(dir_source, "logic", "channels", "_interface.py"),
_os.path.join(dir_source, "logic", "channels", "console.py"),
_os.path.join(dir_source, "logic", "channels", "email.py"),
@ -66,6 +67,7 @@ def main():
_os.path.join(dir_source, "logic", "checks", "script.py"),
_os.path.join(dir_source, "logic", "checks", "file_state.py"),
_os.path.join(dir_source, "logic", "checks", "http_request.py"),
_os.path.join(dir_source, "logic", "checks", "generic_remote.py"),
_os.path.join(dir_source, "logic", "channels", "_interface.py"),
_os.path.join(dir_source, "logic", "channels", "console.py"),
_os.path.join(dir_source, "logic", "channels", "email.py"),