[int]
This commit is contained in:
parent
0f6116ddcd
commit
525e59f7cf
|
|
@ -1,13 +0,0 @@
|
|||
class interface_notification_channel(object):
|
||||
|
||||
def parameters_schema(self):
|
||||
raise NotImplementedError
|
||||
|
||||
|
||||
def normalize_order_node(self, node):
|
||||
raise NotImplementedError
|
||||
|
||||
|
||||
def notify(self, parameters, name, data, state, info):
|
||||
raise NotImplementedError
|
||||
|
||||
|
|
@ -1,41 +0,0 @@
|
|||
class implementation_notification_channel_console(interface_notification_channel):
|
||||
|
||||
'''
|
||||
[implementation]
|
||||
'''
|
||||
def parameters_schema(self):
|
||||
return {
|
||||
"type": "object",
|
||||
"additionalProperties": False,
|
||||
"properties": {
|
||||
},
|
||||
"required": [
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
'''
|
||||
[implementation]
|
||||
'''
|
||||
def normalize_order_node(self, node):
|
||||
return dict_merge(
|
||||
{
|
||||
},
|
||||
node
|
||||
)
|
||||
|
||||
|
||||
'''
|
||||
[implementation]
|
||||
'''
|
||||
def notify(self, parameters, name, data, state, info):
|
||||
_sys.stdout.write(
|
||||
string_coin(
|
||||
"[{{title}}] <{{condition}}> {{info}}\n",
|
||||
{
|
||||
"title": data["title"],
|
||||
"condition": condition_show(state["condition"]),
|
||||
"info": _json.dumps(info, indent = "\t", ensure_ascii = False),
|
||||
}
|
||||
)
|
||||
)
|
||||
|
|
@ -1,16 +0,0 @@
|
|||
class interface_check_kind(object):
|
||||
|
||||
def parameters_schema(self):
|
||||
raise NotImplementedError
|
||||
|
||||
|
||||
def normalize_order_node(self, node):
|
||||
raise NotImplementedError
|
||||
|
||||
|
||||
'''
|
||||
return record<condition:enum_condition,info:any>
|
||||
'''
|
||||
def run(self, parameters):
|
||||
raise NotImplementedError
|
||||
|
||||
|
|
@ -1,270 +0,0 @@
|
|||
class implementation_check_kind_http_request(interface_check_kind):
|
||||
|
||||
'''
|
||||
[implementation]
|
||||
'''
|
||||
def parameters_schema(self):
|
||||
return {
|
||||
"type": "object",
|
||||
"additionalProperties": False,
|
||||
"properties": {
|
||||
"request": {
|
||||
"type": "object",
|
||||
"additionalProperties": False,
|
||||
"properties": {
|
||||
"target": {
|
||||
"description": "URL",
|
||||
"type": "string"
|
||||
},
|
||||
"method": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"GET",
|
||||
"POST"
|
||||
],
|
||||
"default": "GET"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"target"
|
||||
]
|
||||
},
|
||||
"timeout": {
|
||||
"description": "maximum allowed execution time in seconds",
|
||||
"type": "float",
|
||||
"default": 5.0
|
||||
},
|
||||
"follow_redirects": {
|
||||
"description": "whether redirect instructions in responses shall be followend instead of being exposed as result",
|
||||
"type": "boolean",
|
||||
"default": False
|
||||
},
|
||||
"response": {
|
||||
"type": "object",
|
||||
"additionalProperties": False,
|
||||
"properties": {
|
||||
"status_code": {
|
||||
"description": "checks whether the response status code is this",
|
||||
"type": ["null", "integer"],
|
||||
"default": 200
|
||||
},
|
||||
"headers": {
|
||||
"description": "conjunctively checks header key-value pairs",
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"description": "header value",
|
||||
"type": "string"
|
||||
},
|
||||
"properties": {
|
||||
},
|
||||
"required": [
|
||||
],
|
||||
"default": {}
|
||||
},
|
||||
"body_part": {
|
||||
"description": "checks whether the response body contains this string",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
]
|
||||
},
|
||||
"critical": {
|
||||
"description": "whether a violation of this check shall be leveled as critical instead of concerning",
|
||||
"type": "boolean",
|
||||
"default": True
|
||||
},
|
||||
"strict": {
|
||||
"deprecated": True,
|
||||
"description": "alias for 'critical'",
|
||||
"type": "boolean",
|
||||
"default": True
|
||||
},
|
||||
},
|
||||
"required": [
|
||||
"request",
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
'''
|
||||
[implementation]
|
||||
'''
|
||||
def normalize_order_node(self, node):
|
||||
version = (
|
||||
"v1"
|
||||
if (not ("critical" in node)) else
|
||||
"v2"
|
||||
)
|
||||
|
||||
if (version == "v1"):
|
||||
node_ = dict_merge(
|
||||
{
|
||||
"request": {
|
||||
"method": "GET"
|
||||
},
|
||||
"timeout": 5.0,
|
||||
"follow_redirects": False,
|
||||
"response": {
|
||||
"status_code": 200
|
||||
},
|
||||
"strict": True,
|
||||
},
|
||||
node,
|
||||
True
|
||||
)
|
||||
allowed_methods = set(["GET", "POST"])
|
||||
if (node_["request"]["method"] not in allowed_methods):
|
||||
raise ValueError("invalid HTTP request method: %s" % node_["request"]["method"])
|
||||
else:
|
||||
return {
|
||||
"request": node_["request"],
|
||||
"timeout": node_["timeout"],
|
||||
"follow_redirects": node_["follow_redirects"],
|
||||
"response": node_["response"],
|
||||
"critical": node_["strict"],
|
||||
}
|
||||
elif (version == "v2"):
|
||||
node_ = dict_merge(
|
||||
{
|
||||
"request": {
|
||||
"method": "GET"
|
||||
},
|
||||
"timeout": 5.0,
|
||||
"follow_redirects": False,
|
||||
"response": {
|
||||
"status_code": 200
|
||||
},
|
||||
"critical": True,
|
||||
},
|
||||
node,
|
||||
True
|
||||
)
|
||||
allowed_methods = set(["GET", "POST"])
|
||||
if (node_["request"]["method"] not in allowed_methods):
|
||||
raise ValueError("invalid HTTP request method: %s" % node_["request"]["method"])
|
||||
else:
|
||||
return node_
|
||||
else:
|
||||
raise ValueError("unhandled")
|
||||
|
||||
|
||||
'''
|
||||
[implementation]
|
||||
'''
|
||||
def run(self, parameters):
|
||||
if (parameters["request"]["method"] == "GET"):
|
||||
try:
|
||||
response = _requests.get(
|
||||
parameters["request"]["target"],
|
||||
timeout = parameters["timeout"],
|
||||
allow_redirects = parameters["follow_redirects"]
|
||||
)
|
||||
error = None
|
||||
except Exception as error_:
|
||||
error = error_
|
||||
response = None
|
||||
elif (parameters["request"]["method"] == "POST"):
|
||||
try:
|
||||
response = _requests.post(
|
||||
parameters["request"]["target"],
|
||||
timeout = parameters["timeout"],
|
||||
allow_redirects = parameters["follow_redirects"]
|
||||
)
|
||||
error = None
|
||||
except Exception as error_:
|
||||
error = error_
|
||||
response = None
|
||||
else:
|
||||
raise ValueError("impossible")
|
||||
if (response is None):
|
||||
return {
|
||||
"condition": (
|
||||
enum_condition.critical
|
||||
if parameters["strict"] else
|
||||
enum_condition.concerning
|
||||
),
|
||||
"info": {
|
||||
"request": parameters["request"],
|
||||
"faults": [
|
||||
translation_get("checks.http_request.request_failed"),
|
||||
],
|
||||
}
|
||||
}
|
||||
else:
|
||||
faults = []
|
||||
for (key, value, ) in parameters["response"].items():
|
||||
if (key == "status_code"):
|
||||
if ((value is None) or (response.status_code == value)):
|
||||
pass
|
||||
else:
|
||||
faults.append(
|
||||
translation_get(
|
||||
"checks.http_request.status_code_mismatch",
|
||||
{
|
||||
"status_code_actual": ("%u" % response.status_code),
|
||||
"status_code_expected": ("%u" % value),
|
||||
}
|
||||
)
|
||||
)
|
||||
elif (key == "headers"):
|
||||
for (header_key, header_value, ) in value.items():
|
||||
if (not (header_key in response.headers)):
|
||||
faults.append(
|
||||
translation_get(
|
||||
"checks.http_request.header_missing",
|
||||
{
|
||||
"key": header_key,
|
||||
"value_expected": header_value,
|
||||
}
|
||||
)
|
||||
)
|
||||
else:
|
||||
if (not (response.headers[header_key] == header_value)):
|
||||
faults.append(
|
||||
translation_get(
|
||||
"checks.http_request.header_value_mismatch",
|
||||
{
|
||||
"key": header_key,
|
||||
"value_actual": response.headers[header_key],
|
||||
"value_expected": header_value,
|
||||
}
|
||||
)
|
||||
)
|
||||
else:
|
||||
pass
|
||||
elif (key == "body_part"):
|
||||
if (response.text.find(value) >= 0):
|
||||
pass
|
||||
else:
|
||||
faults.append(
|
||||
translation_get(
|
||||
"checks.http_request.body_misses_part",
|
||||
{
|
||||
"part": value,
|
||||
}
|
||||
)
|
||||
)
|
||||
else:
|
||||
raise ValueError("unhandled")
|
||||
return {
|
||||
"condition": (
|
||||
enum_condition.ok
|
||||
if (len(faults) <= 0) else
|
||||
(
|
||||
enum_condition.critical
|
||||
if parameters["strict"] else
|
||||
enum_condition.concerning
|
||||
)
|
||||
),
|
||||
"info": {
|
||||
"request": parameters["request"],
|
||||
"response": {
|
||||
"status_code": response.status_code,
|
||||
"headers": dict(map(lambda pair: pair, response.headers.items())),
|
||||
# "body": response.text,
|
||||
},
|
||||
"faults": faults,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1,39 +0,0 @@
|
|||
class enum_condition(_enum.Enum):
|
||||
unknown = 0
|
||||
ok = 1
|
||||
concerning = 2
|
||||
critical = 3
|
||||
|
||||
|
||||
'''
|
||||
converts a condition to a human readable string
|
||||
'''
|
||||
def condition_show(condition):
|
||||
return translation_get(
|
||||
{
|
||||
enum_condition.unknown: "conditions.unknown",
|
||||
enum_condition.ok: "conditions.ok",
|
||||
enum_condition.concerning: "conditions.concerning",
|
||||
enum_condition.critical: "conditions.critical",
|
||||
}[condition]
|
||||
)
|
||||
|
||||
|
||||
def condition_encode(condition):
|
||||
return {
|
||||
enum_condition.unknown: "unknown",
|
||||
enum_condition.ok: "ok",
|
||||
enum_condition.concerning: "concerning",
|
||||
enum_condition.critical: "critical",
|
||||
}[condition]
|
||||
|
||||
|
||||
def condition_decode(condition_encoded):
|
||||
return {
|
||||
"unknown": enum_condition.unknown,
|
||||
"ok": enum_condition.ok,
|
||||
"warning": enum_condition.concerning, # deprecated
|
||||
"concerning": enum_condition.concerning,
|
||||
"critical": enum_condition.critical,
|
||||
}[condition_encoded]
|
||||
|
||||
|
|
@ -1,52 +0,0 @@
|
|||
translation_language_fallback = None
|
||||
|
||||
translation_language_shall = None
|
||||
|
||||
def translation_initialize(language_fallback, language_shall):
|
||||
global translation_language_fallback
|
||||
global translation_language_shall
|
||||
translation_language_fallback = language_fallback
|
||||
translation_language_shall = language_shall
|
||||
|
||||
|
||||
def translation_get(key, arguments = None):
|
||||
global translation_language_fallback
|
||||
global translation_language_shall
|
||||
global localization_data
|
||||
if (arguments is None):
|
||||
arguments = {}
|
||||
languages = list(
|
||||
filter(
|
||||
lambda language: (language is not None),
|
||||
[translation_language_shall, translation_language_fallback]
|
||||
)
|
||||
)
|
||||
for language in languages:
|
||||
if (language not in localization_data):
|
||||
_sys.stderr.write(
|
||||
string_coin(
|
||||
"[notice] missing localization data for language '{{language}}'\n",
|
||||
{
|
||||
"language": language,
|
||||
}
|
||||
)
|
||||
)
|
||||
else:
|
||||
if (key not in localization_data[language]):
|
||||
_sys.stderr.write(
|
||||
string_coin(
|
||||
"[notice] missing translation in language '{{language}}' for key '{{key}}'\n",
|
||||
{
|
||||
"language": language,
|
||||
"key": key,
|
||||
}
|
||||
)
|
||||
)
|
||||
else:
|
||||
return string_coin(
|
||||
localization_data[language][key],
|
||||
arguments
|
||||
)
|
||||
return ("{{%s}}" % key)
|
||||
|
||||
|
||||
|
|
@ -1,476 +0,0 @@
|
|||
def order_schema_active(
|
||||
):
|
||||
return {
|
||||
"description": "whether the check shall be executed",
|
||||
"type": "boolean",
|
||||
"default": True,
|
||||
}
|
||||
|
||||
|
||||
def order_schema_threshold(
|
||||
):
|
||||
return {
|
||||
"description": "how often a condition has to occur in order to be reported",
|
||||
"type": "integer",
|
||||
"minimum": 1,
|
||||
"default": 3,
|
||||
}
|
||||
|
||||
|
||||
def order_schema_annoy(
|
||||
):
|
||||
return {
|
||||
"description": "whether notifications about non-ok states shall be kept sending after the threshold has been surpassed",
|
||||
"type": "boolean",
|
||||
"default": False,
|
||||
}
|
||||
|
||||
|
||||
def order_schema_interval(
|
||||
allow_null,
|
||||
default
|
||||
):
|
||||
return {
|
||||
"anyOf": [
|
||||
{
|
||||
"description": "in seconds",
|
||||
"type": ("integer" if allow_null else ["null", "integer"]),
|
||||
"exclusiveMinimum": 0,
|
||||
},
|
||||
{
|
||||
"description": "as text",
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"minute",
|
||||
"hour",
|
||||
"day",
|
||||
"week",
|
||||
]
|
||||
},
|
||||
],
|
||||
"default": default,
|
||||
}
|
||||
|
||||
|
||||
def order_schema_schedule(
|
||||
):
|
||||
return {
|
||||
"type": "object",
|
||||
"additionalProperties": False,
|
||||
"properties": {
|
||||
"regular_interval": order_schema_interval(False, (60 * 60)),
|
||||
"attentive_interval": order_schema_interval(False, (60 * 2)),
|
||||
"reminding_interval": order_schema_interval(True, (60 * 60 * 24)),
|
||||
},
|
||||
"required": [
|
||||
],
|
||||
}
|
||||
|
||||
|
||||
def order_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 order_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": order_schema_active(),
|
||||
"threshold": order_schema_threshold(),
|
||||
"annoy": order_schema_annoy(),
|
||||
"schedule": order_schema_schedule(),
|
||||
"notifications": order_schema_notifications(notification_channel_implementations),
|
||||
},
|
||||
"required": [
|
||||
],
|
||||
},
|
||||
"includes": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"default": [],
|
||||
"description": "list of relative or absolute paths to other hmdl files on the local machine, which shall be subsumed in the overall monitoring task"
|
||||
},
|
||||
"checks": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"allOf": [
|
||||
{
|
||||
"description": "should represent a specific check",
|
||||
"type": "object",
|
||||
"unevaluatedProperties": False,
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"title": {
|
||||
"type": "string"
|
||||
},
|
||||
"active": order_schema_active(),
|
||||
"threshold": order_schema_threshold(),
|
||||
"annoy": order_schema_annoy(),
|
||||
"schedule": order_schema_schedule(),
|
||||
"notifications": order_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(),
|
||||
"custom": {
|
||||
"description": "custom data, which shall be attached to notifications",
|
||||
"default": None,
|
||||
},
|
||||
},
|
||||
"required": [
|
||||
"kind",
|
||||
"parameters",
|
||||
]
|
||||
},
|
||||
check_kind_implementations.items()
|
||||
)
|
||||
),
|
||||
},
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
def order_normalize_interval(
|
||||
interval_raw
|
||||
):
|
||||
if (interval_raw is None):
|
||||
return None
|
||||
else:
|
||||
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 order_normalize_schedule(
|
||||
node
|
||||
):
|
||||
node_ = dict_merge(
|
||||
{
|
||||
"regular_interval": (60 * 60),
|
||||
"attentive_interval": (60 * 2),
|
||||
"reminding_interval": (60 * 60 * 24),
|
||||
},
|
||||
node
|
||||
)
|
||||
return {
|
||||
"regular_interval": order_normalize_interval(node_["regular_interval"]),
|
||||
"attentive_interval": order_normalize_interval(node_["attentive_interval"]),
|
||||
"reminding_interval": order_normalize_interval(node_["reminding_interval"]),
|
||||
}
|
||||
|
||||
|
||||
def order_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_order_node(node["parameters"]),
|
||||
}
|
||||
|
||||
|
||||
def order_normalize_defaults(
|
||||
notification_channel_implementations,
|
||||
node
|
||||
):
|
||||
node_ = dict_merge(
|
||||
{
|
||||
"active": True,
|
||||
"threshold": 3,
|
||||
"annoy": False,
|
||||
"schedule": {
|
||||
"regular_interval": (60 * 60),
|
||||
"attentive_interval": (60 * 2),
|
||||
"reminding_interval": (60 * 60 * 24),
|
||||
},
|
||||
"notifications": [
|
||||
],
|
||||
},
|
||||
node
|
||||
)
|
||||
return {
|
||||
"active": node_["active"],
|
||||
"threshold": node_["threshold"],
|
||||
"annoy": node_["annoy"],
|
||||
"schedule": node_["schedule"],
|
||||
"notifications": list(
|
||||
map(
|
||||
lambda x: order_normalize_notification(notification_channel_implementations, x),
|
||||
node_["notifications"]
|
||||
)
|
||||
),
|
||||
}
|
||||
|
||||
|
||||
def order_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(
|
||||
dict_merge(
|
||||
defaults,
|
||||
{
|
||||
"title": node["name"],
|
||||
"parameters": {},
|
||||
"custom": None,
|
||||
},
|
||||
),
|
||||
node
|
||||
)
|
||||
node__ = {}
|
||||
if True:
|
||||
node__["name"] = node_["name"]
|
||||
if True:
|
||||
node__["title"] = node_["title"]
|
||||
if ("active" in node_):
|
||||
node__["active"] = node_["active"]
|
||||
if ("threshold" in node_):
|
||||
node__["threshold"] = node_["threshold"]
|
||||
if ("annoy" in node_):
|
||||
node__["annoy"] = node_["annoy"]
|
||||
if ("schedule" in node_):
|
||||
node__["schedule"] = order_normalize_schedule(node_["schedule"])
|
||||
if ("notifications" in node_):
|
||||
node__["notifications"] = list(
|
||||
map(
|
||||
lambda x: order_normalize_notification(notification_channel_implementations, x),
|
||||
node_["notifications"]
|
||||
)
|
||||
)
|
||||
if ("kind" in node_):
|
||||
node__["kind"] = node_["kind"]
|
||||
if True:
|
||||
node__["parameters"] = check_kind_implementations[node_["kind"]].normalize_order_node(node_["parameters"])
|
||||
if ("custom" in node_):
|
||||
node__["custom"] = node_["custom"]
|
||||
return node__
|
||||
|
||||
|
||||
def order_normalize_root(
|
||||
check_kind_implementations,
|
||||
notification_channel_implementations,
|
||||
node,
|
||||
options = None
|
||||
):
|
||||
options = dict_merge(
|
||||
{
|
||||
"use_implicit_default_values": True,
|
||||
},
|
||||
({} if (options is None) else options)
|
||||
)
|
||||
counts = {}
|
||||
checks_raw = (
|
||||
node["checks"]
|
||||
if ("checks" in node) else
|
||||
[]
|
||||
)
|
||||
for node_ in checks_raw:
|
||||
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(map(lambda pair: pair[0], fails)),
|
||||
}
|
||||
)
|
||||
)
|
||||
else:
|
||||
defaults_raw = (
|
||||
node["defaults"]
|
||||
if ("defaults" in node) else
|
||||
{}
|
||||
)
|
||||
defaults = (
|
||||
order_normalize_defaults(
|
||||
notification_channel_implementations,
|
||||
defaults_raw
|
||||
)
|
||||
if options["use_implicit_default_values"] else
|
||||
defaults_raw
|
||||
)
|
||||
includes = (
|
||||
node["includes"]
|
||||
if ("includes" in node) else
|
||||
[]
|
||||
)
|
||||
return {
|
||||
"defaults": defaults,
|
||||
"includes": includes,
|
||||
"checks": list(
|
||||
map(
|
||||
lambda node_: order_normalize_check(
|
||||
check_kind_implementations,
|
||||
notification_channel_implementations,
|
||||
defaults,
|
||||
node_
|
||||
),
|
||||
checks_raw
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
def order_load(
|
||||
check_kind_implementations,
|
||||
notification_channel_implementations,
|
||||
path,
|
||||
options = None
|
||||
):
|
||||
options = dict_merge(
|
||||
{
|
||||
"root": True,
|
||||
"already_included": set([]),
|
||||
},
|
||||
({} if (options is None) else options)
|
||||
)
|
||||
if (path in options["already_included"]):
|
||||
raise ValueError("circular dependency detected")
|
||||
else:
|
||||
order_raw = _json.loads(file_read(path))
|
||||
includes = (
|
||||
order_raw["includes"]
|
||||
if ("includes" in order_raw) else
|
||||
[]
|
||||
)
|
||||
for index in range(len(includes)):
|
||||
path_ = includes[index]
|
||||
sub_order = order_load(
|
||||
check_kind_implementations,
|
||||
notification_channel_implementations,
|
||||
(
|
||||
path_
|
||||
if _os.path.isabs(path_) else
|
||||
_os.path.join(_os.path.dirname(path), path_)
|
||||
),
|
||||
{
|
||||
"root": False,
|
||||
"already_included": (options["already_included"] | {path})
|
||||
}
|
||||
)
|
||||
if (not "checks" in order_raw):
|
||||
order_raw["checks"] = []
|
||||
order_raw["checks"].extend(
|
||||
list(
|
||||
map(
|
||||
lambda check: dict_merge(
|
||||
check,
|
||||
{
|
||||
"name": string_coin(
|
||||
"{{prefix}}.{{original_name}}",
|
||||
{
|
||||
"prefix": _os.path.basename(path_).split(".")[0],
|
||||
"original_name": check["name"],
|
||||
}
|
||||
),
|
||||
}
|
||||
),
|
||||
sub_order["checks"]
|
||||
)
|
||||
)
|
||||
)
|
||||
order_raw["includes"] = []
|
||||
return order_normalize_root(
|
||||
check_kind_implementations,
|
||||
notification_channel_implementations,
|
||||
order_raw,
|
||||
{
|
||||
"use_implicit_default_values": options["root"],
|
||||
}
|
||||
)
|
||||
|
||||
|
|
@ -1,17 +0,0 @@
|
|||
import sys as _sys
|
||||
import os as _os
|
||||
import subprocess as _subprocess
|
||||
import math as _math
|
||||
import hashlib as _hashlib
|
||||
import tempfile as _tempfile
|
||||
import argparse as _argparse
|
||||
import json as _json
|
||||
import requests as _requests
|
||||
import enum as _enum
|
||||
import time as _time
|
||||
import datetime as _datetime
|
||||
import smtplib as _smtplib
|
||||
from email.mime.text import MIMEText
|
||||
import ssl as _ssl
|
||||
import socket as _socket
|
||||
import sqlite3 as _sqlite3
|
||||
|
|
@ -4,7 +4,8 @@ async function main(
|
|||
// consts
|
||||
const version : string = "0.8";
|
||||
|
||||
// init
|
||||
// init translations
|
||||
// TODO: use env language
|
||||
await lib_plankton.translate.initialize_promise(
|
||||
{
|
||||
"verbosity": 1,
|
||||
|
|
|
|||
Loading…
Reference in a new issue