2022-11-29 23:53:14 +01:00
|
|
|
class implementation_check_kind_http_request(interface_check_kind):
|
|
|
|
|
|
2022-11-30 23:03:24 +01:00
|
|
|
'''
|
|
|
|
|
[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"
|
|
|
|
|
]
|
|
|
|
|
},
|
2022-12-15 15:51:07 +01:00
|
|
|
"timeout": {
|
|
|
|
|
"description": "maximum allowed execution time in seconds",
|
|
|
|
|
"type": "float",
|
|
|
|
|
"default": 5.0
|
|
|
|
|
},
|
2022-11-30 23:03:24 +01:00
|
|
|
"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": [
|
|
|
|
|
]
|
|
|
|
|
},
|
2022-12-03 16:36:44 +01:00
|
|
|
"strict": {
|
|
|
|
|
"description": "whether a violation of this check shall be leveled as critical instead of concerning",
|
2022-11-30 23:03:24 +01:00
|
|
|
"type": "boolean",
|
2022-12-03 16:36:44 +01:00
|
|
|
"default": True
|
|
|
|
|
},
|
2022-11-30 23:03:24 +01:00
|
|
|
},
|
|
|
|
|
"required": [
|
|
|
|
|
"request"
|
|
|
|
|
]
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2022-11-29 23:53:14 +01:00
|
|
|
'''
|
|
|
|
|
[implementation]
|
|
|
|
|
'''
|
|
|
|
|
def normalize_conf_node(self, node):
|
2022-12-03 16:36:44 +01:00
|
|
|
node_ = dict_merge(
|
2022-11-29 23:53:14 +01:00
|
|
|
{
|
|
|
|
|
"request": {
|
|
|
|
|
"method": "GET"
|
|
|
|
|
},
|
2022-12-15 15:51:07 +01:00
|
|
|
"timeout": 5.0,
|
2022-11-29 23:53:14 +01:00
|
|
|
"response": {
|
|
|
|
|
"status_code": 200
|
|
|
|
|
},
|
2022-12-03 16:36:44 +01:00
|
|
|
"strict": True,
|
2022-11-29 23:53:14 +01:00
|
|
|
},
|
|
|
|
|
node,
|
|
|
|
|
True
|
|
|
|
|
)
|
2022-12-03 16:36:44 +01:00
|
|
|
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_
|
2022-11-29 23:53:14 +01:00
|
|
|
|
|
|
|
|
|
|
|
|
|
'''
|
|
|
|
|
[implementation]
|
|
|
|
|
'''
|
2022-11-30 08:15:35 +01:00
|
|
|
def run(self, parameters):
|
|
|
|
|
if (parameters["request"]["method"] == "GET"):
|
2022-11-29 23:53:14 +01:00
|
|
|
try:
|
|
|
|
|
response = _requests.get(
|
2022-12-15 15:51:07 +01:00
|
|
|
parameters["request"]["target"],
|
|
|
|
|
timeout = parameters["timeout"]
|
2022-11-29 23:53:14 +01:00
|
|
|
)
|
|
|
|
|
error = None
|
|
|
|
|
except Exception as error_:
|
|
|
|
|
error = error_
|
|
|
|
|
response = None
|
2022-11-30 08:15:35 +01:00
|
|
|
elif (parameters["request"]["method"] == "POST"):
|
2022-11-29 23:53:14 +01:00
|
|
|
try:
|
|
|
|
|
response = _requests.post(
|
2022-12-15 15:51:07 +01:00
|
|
|
parameters["request"]["target"],
|
|
|
|
|
timeout = parameters["timeout"]
|
2022-11-29 23:53:14 +01:00
|
|
|
)
|
|
|
|
|
error = None
|
|
|
|
|
except Exception as error_:
|
|
|
|
|
error = error_
|
|
|
|
|
response = None
|
|
|
|
|
else:
|
2022-12-03 16:36:44 +01:00
|
|
|
raise ValueError("impossible")
|
|
|
|
|
if (response is None):
|
2022-11-29 23:53:14 +01:00
|
|
|
return {
|
2022-12-03 16:36:44 +01:00
|
|
|
"condition": (
|
|
|
|
|
enum_condition.critical
|
|
|
|
|
if parameters["strict"] else
|
|
|
|
|
enum_condition.warning
|
|
|
|
|
),
|
|
|
|
|
"info": {
|
|
|
|
|
"request": parameters["request"],
|
|
|
|
|
"faults": [
|
2022-12-18 23:16:39 +01:00
|
|
|
translation_get("checks.http_request.request_failed"),
|
2022-12-03 16:36:44 +01:00
|
|
|
],
|
|
|
|
|
}
|
2022-11-29 23:53:14 +01:00
|
|
|
}
|
|
|
|
|
else:
|
2023-01-19 08:11:50 +01:00
|
|
|
faults = []
|
2022-12-03 16:36:44 +01:00
|
|
|
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),
|
|
|
|
|
}
|
2022-11-29 23:53:14 +01:00
|
|
|
)
|
2022-12-03 16:36:44 +01:00
|
|
|
)
|
|
|
|
|
elif (key == "headers"):
|
|
|
|
|
for (header_key, header_value, ) in value.items():
|
|
|
|
|
if (response.headers[header_key] == header_value):
|
2022-11-29 23:53:14 +01:00
|
|
|
pass
|
|
|
|
|
else:
|
2022-12-03 16:36:44 +01:00
|
|
|
faults.append(
|
|
|
|
|
translation_get(
|
|
|
|
|
"checks.http_request.header_value_mismatch",
|
2022-11-29 23:53:14 +01:00
|
|
|
{
|
2022-12-03 16:36:44 +01:00
|
|
|
"key": header_key,
|
|
|
|
|
"value_actual": response.headers[header_key],
|
|
|
|
|
"value_expected": header_value,
|
2022-11-29 23:53:14 +01:00
|
|
|
}
|
|
|
|
|
)
|
|
|
|
|
)
|
2022-12-03 16:36:44 +01:00
|
|
|
elif (key == "body_part"):
|
|
|
|
|
if (response.text.find(value) >= 0):
|
|
|
|
|
pass
|
2022-11-29 23:53:14 +01:00
|
|
|
else:
|
2022-12-03 16:36:44 +01:00
|
|
|
faults.append(
|
|
|
|
|
translation_get(
|
|
|
|
|
"checks.http_request.body_misses_part",
|
|
|
|
|
{
|
|
|
|
|
"part": value,
|
|
|
|
|
}
|
|
|
|
|
)
|
2022-11-29 23:53:14 +01:00
|
|
|
)
|
2022-12-03 16:36:44 +01:00
|
|
|
else:
|
|
|
|
|
raise ValueError("unhandled")
|
|
|
|
|
return {
|
|
|
|
|
"condition": (
|
|
|
|
|
enum_condition.ok
|
|
|
|
|
if (len(faults) <= 0) else
|
|
|
|
|
(
|
|
|
|
|
enum_condition.critical
|
|
|
|
|
if parameters["strict"] else
|
|
|
|
|
enum_condition.warning
|
|
|
|
|
)
|
|
|
|
|
),
|
|
|
|
|
"info": {
|
|
|
|
|
"request": parameters["request"],
|
|
|
|
|
"response": {
|
|
|
|
|
"status_code": response.status_code,
|
|
|
|
|
# "headers": dict(map(lambda pair: pair, response.headers.items())),
|
|
|
|
|
# "body": response.text,
|
|
|
|
|
},
|
|
|
|
|
"faults": faults,
|
2022-11-29 23:53:14 +01:00
|
|
|
}
|
2022-12-03 16:36:44 +01:00
|
|
|
}
|
2022-11-30 23:03:24 +01:00
|
|
|
|