[issue-1] adjustments

This commit is contained in:
Christian Fraß 2023-03-04 15:19:44 +01:00
commit a0a328958e
8 changed files with 207 additions and 54 deletions

View file

@ -1,24 +1,10 @@
{ {
"defaults": {
"threshold": 1,
"schedule": {
"regular_interval": 10,
"attentive_interval": 1
},
"notifications": [
{
"kind": "console",
"parameters": {
}
}
]
},
"checks": [ "checks": [
{ {
"name": "test", "name": "test",
"kind": "generic_remote", "kind": "generic_remote",
"parameters": { "parameters": {
"ssh_host": "bragi.pool.greenscale.de", "host": "bragi.pool.greenscale.de",
"ssh_user": "fenris", "ssh_user": "fenris",
"ssh_port": 8192, "ssh_port": 8192,
"ssh_key": "/home/fenris/.ssh/keypairs/gs-bragi" "ssh_key": "/home/fenris/.ssh/keypairs/gs-bragi"

View file

@ -4,6 +4,7 @@
"regular_interval": 10, "regular_interval": 10,
"attentive_interval": 1 "attentive_interval": 1
}, },
"threshold": 1,
"notifications": [ "notifications": [
{ {
"kind": "console", "kind": "console",

View file

@ -8,7 +8,7 @@ class implementation_check_kind_generic_remote(interface_check_kind):
"type": "object", "type": "object",
"additionalProperties": False, "additionalProperties": False,
"properties": { "properties": {
"ssh_host" : { "host" : {
"type" : "string" "type" : "string"
}, },
"ssh_port": { "ssh_port": {
@ -38,7 +38,7 @@ class implementation_check_kind_generic_remote(interface_check_kind):
} }
}, },
"required": [ "required": [
"ssh_host" "host"
] ]
} }
@ -47,8 +47,8 @@ class implementation_check_kind_generic_remote(interface_check_kind):
[implementation] [implementation]
''' '''
def normalize_conf_node(self, node): def normalize_conf_node(self, node):
if (not "ssh_host" in node): if (not "host" in node):
raise ValueError("mandatory parameter \"ssh_host\" missing") raise ValueError("mandatory parameter \"host\" missing")
else: else:
return dict_merge( return dict_merge(
{ {
@ -78,7 +78,7 @@ class implementation_check_kind_generic_remote(interface_check_kind):
if True: if True:
outer_command_parts.append("ssh"); outer_command_parts.append("ssh");
if True: if True:
outer_command_parts.append(string_coin("{{host}}", {"host": parameters["ssh_host"]})); outer_command_parts.append(string_coin("{{host}}", {"host": parameters["host"]}));
if (parameters["ssh_port"] is not None): if (parameters["ssh_port"] is not None):
outer_command_parts.append(string_coin("-p {{port}}", {"port": ("%u" % parameters["ssh_port"])})); outer_command_parts.append(string_coin("-p {{port}}", {"port": ("%u" % parameters["ssh_port"])}));
if (parameters["ssh_user"] is not None): if (parameters["ssh_user"] is not None):
@ -104,8 +104,8 @@ class implementation_check_kind_generic_remote(interface_check_kind):
stuff = result["stdout"].split("\n")[-2].split(" ") stuff = result["stdout"].split("\n")[-2].split(" ")
data = { data = {
"device": stuff[0], "device": stuff[0],
"used": stuff[2], "used": int(stuff[2]),
"avail": stuff[3], "avail": int(stuff[3]),
"perc": int(stuff[4][:-1]), "perc": int(stuff[4][:-1]),
} }
if (data["perc"] > parameters["threshold"]): if (data["perc"] > parameters["threshold"]):
@ -116,12 +116,14 @@ class implementation_check_kind_generic_remote(interface_check_kind):
enum_condition.warning enum_condition.warning
), ),
"info": { "info": {
"ssh_host": parameters["ssh_host"], "data": {
"mount_point": parameters["mount_point"], "host": parameters["host"],
"device": data["device"], "device": data["device"],
"used": data["used"], # ToDo: Humanlesbarkeit herstellen "mount_point": parameters["mount_point"],
"available": data["avail"], # ToDo: Humanlesbarkeit herstellen "used": format_bytes(data["used"]),
"percentage": (str(data["perc"]) + "%"), "available": format_bytes(data["avail"]),
"percentage": (str(data["perc"]) + "%"),
},
"faults": [ "faults": [
translation_get("checks.generic_remote.overflow") translation_get("checks.generic_remote.overflow")
], ],

View file

@ -309,8 +309,8 @@ def conf_normalize_check(
node__["annoy"] = node_["annoy"] node__["annoy"] = node_["annoy"]
if ("schedule" in node_): if ("schedule" in node_):
node__["schedule"] = conf_normalize_schedule(node_["schedule"]) node__["schedule"] = conf_normalize_schedule(node_["schedule"])
if ("notification" in node_): if ("notifications" in node_):
node__["notification"] = list( node__["notifications"] = list(
map( map(
lambda x: conf_normalize_notification(notification_channel_implementations, x), lambda x: conf_normalize_notification(notification_channel_implementations, x),
node_["notifications"] node_["notifications"]

View file

@ -60,3 +60,26 @@ def shell_command(command):
"stderr": result.stderr.decode(), "stderr": result.stderr.decode(),
} }
def format_bytes(bytes_):
units = [
{"label": "B", "digits": 0},
{"label": "KB", "digits": 1},
{"label": "MB", "digits": 1},
{"label": "GB", "digits": 1},
{"label": "TB", "digits": 1},
{"label": "PB", "digits": 1},
]
number = bytes_
index = 0
while ((number >= 1000) and (index < (len(units) - 1))):
number /= 1000
index += 1
return (
("%." + ("%u" % units[index]["digits"]) + "f %s")
% (
number,
units[index]["label"],
)
)

View file

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

102
source/test/test.py Normal file
View file

@ -0,0 +1,102 @@
definitions = [
{
"name": "lib.string_coin",
"procedure": lambda input_: string_coin(input_["template"], input_["arguments"]),
"cases": [
{
"input": {
"template": "{{sachen}} sind {{farbe}}",
"arguments": {
"farbe": "rot",
},
},
"output": "{{sachen}} sind rot"
},
{
"input": {
"template": "{{sachen}} sind {{farbe}}",
"arguments": {
},
},
"output": "{{sachen}} sind {{farbe}}"
},
{
"input": {
"template": "{{sachen}} sind {{farbe}}",
"arguments": {
"sachen": "rosen",
"farbe": "rot",
},
},
"output": "rosen sind rot"
},
{
"input": {
"template": "{{sachen}} sind {{farbe}}",
"arguments": {
"sachen": "rosen",
"farbe": "rot",
"ort": "frankreich",
},
},
"output": "rosen sind rot"
},
],
},
{
"name": "lib.format_bytes",
"procedure": lambda input_: format_bytes(input_),
"cases": [
{
"input": 999,
"output": "999 B",
},
{
"input": 1000,
"output": "1.0 KB",
},
{
"input": 1000000,
"output": "1.0 MB",
},
{
"input": 1000000000,
"output": "1.0 GB",
},
{
"input": 1000000000000,
"output": "1.0 TB",
},
{
"input": 1000000000000000,
"output": "1.0 PB",
},
{
"input": 1000000000000000000,
"output": "1000.0 PB",
},
],
},
]
for definition in definitions:
for index in range(len(definition["cases"])):
case = definition["cases"][index]
output_actual = definition["procedure"](case["input"])
output_expected = case["output"]
passed = (output_actual == output_expected)
info = {
"input": case["input"],
"output_expected": output_expected,
"output_actual": output_actual,
}
_sys.stderr.write(
"[%s] %s.%u%s\n"
% (
("+" if passed else "x"),
definition["name"],
index,
("" if passed else (": " + _json.dumps(info))),
)
)

View file

@ -4,6 +4,7 @@ import sys as _sys
import os as _os import os as _os
import json as _json import json as _json
import stat as _stat import stat as _stat
import argparse as _argparse
def file_read(path): def file_read(path):
@ -34,24 +35,62 @@ def main():
## consts ## consts
dir_source = "source" dir_source = "source"
dir_build = "build" dir_build = "build"
sources_logic = [ targets = {
_os.path.join(dir_source, "logic", "packages.py"), "app": {
_os.path.join(dir_source, "logic", "lib.py"), "sources": [
_os.path.join(dir_source, "logic", "localization.py"), _os.path.join(dir_source, "logic", "packages.py"),
_os.path.join(dir_source, "logic", "condition.py"), _os.path.join(dir_source, "logic", "lib.py"),
_os.path.join(dir_source, "logic", "conf.py"), _os.path.join(dir_source, "logic", "localization.py"),
_os.path.join(dir_source, "logic", "checks", "_interface.py"), _os.path.join(dir_source, "logic", "condition.py"),
_os.path.join(dir_source, "logic", "checks", "script.py"), _os.path.join(dir_source, "logic", "conf.py"),
_os.path.join(dir_source, "logic", "checks", "file_state.py"), _os.path.join(dir_source, "logic", "checks", "_interface.py"),
_os.path.join(dir_source, "logic", "checks", "http_request.py"), _os.path.join(dir_source, "logic", "checks", "script.py"),
_os.path.join(dir_source, "logic", "checks", "generic_remote.py"), _os.path.join(dir_source, "logic", "checks", "file_state.py"),
_os.path.join(dir_source, "logic", "channels", "_interface.py"), _os.path.join(dir_source, "logic", "checks", "http_request.py"),
_os.path.join(dir_source, "logic", "channels", "console.py"), _os.path.join(dir_source, "logic", "checks", "generic_remote.py"),
_os.path.join(dir_source, "logic", "channels", "email.py"), _os.path.join(dir_source, "logic", "channels", "_interface.py"),
_os.path.join(dir_source, "logic", "channels", "libnotify.py"), _os.path.join(dir_source, "logic", "channels", "console.py"),
_os.path.join(dir_source, "logic", "main.py"), _os.path.join(dir_source, "logic", "channels", "email.py"),
] _os.path.join(dir_source, "logic", "channels", "libnotify.py"),
path_compilation = _os.path.join(dir_build, "heimdall") _os.path.join(dir_source, "logic", "main.py"),
],
"build": _os.path.join(dir_build, "heimdall"),
},
"test": {
"sources": [
_os.path.join(dir_source, "logic", "packages.py"),
_os.path.join(dir_source, "logic", "lib.py"),
_os.path.join(dir_source, "logic", "localization.py"),
_os.path.join(dir_source, "logic", "condition.py"),
_os.path.join(dir_source, "logic", "conf.py"),
_os.path.join(dir_source, "logic", "checks", "_interface.py"),
_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"),
_os.path.join(dir_source, "logic", "channels", "libnotify.py"),
_os.path.join(dir_source, "test", "test.py"),
],
"build": _os.path.join(dir_build, "heimdall-test"),
},
}
## args
argument_parser = _argparse.ArgumentParser(
)
argument_parser.add_argument(
"-t",
"--target",
type = str,
choices = ["app", "test"],
default = "app",
dest = "target_name",
help = "which target to build",
)
args = argument_parser.parse_args()
## exec ## exec
if (not _os.path.exists(dir_build)): if (not _os.path.exists(dir_build)):
@ -82,17 +121,17 @@ def main():
) )
### logic ### logic
for path in sources_logic: for path in targets[args.target_name]["sources"]:
compilation += (file_read(path) + "\n") compilation += (file_read(path) + "\n")
### write to file ### write to file
if _os.path.exists(path_compilation): if _os.path.exists(targets[args.target_name]["build"]):
_os.remove(path_compilation) _os.remove(targets[args.target_name]["build"])
file_write(path_compilation, compilation) file_write(targets[args.target_name]["build"], compilation)
### postproess ### postproess
_os.chmod( _os.chmod(
path_compilation, targets[args.target_name]["build"],
(_stat.S_IRWXU | _stat.S_IXGRP | _stat.S_IXOTH) (_stat.S_IRWXU | _stat.S_IXGRP | _stat.S_IXOTH)
) )