mirror of
https://github.com/louislam/uptime-kuma.git
synced 2025-06-07 21:42:34 +02:00
feat(monitor-checks): fix validation of checks
This commit is contained in:
parent
44bddef349
commit
b8dc487468
4 changed files with 39 additions and 32 deletions
|
@ -49,13 +49,7 @@ class Monitor extends BeanModel {
|
||||||
}
|
}
|
||||||
|
|
||||||
const tags = await R.getAll("SELECT mt.*, tag.name, tag.color FROM monitor_tag mt JOIN tag ON mt.tag_id = tag.id WHERE mt.monitor_id = ?", [this.id]);
|
const tags = await R.getAll("SELECT mt.*, tag.name, tag.color FROM monitor_tag mt JOIN tag ON mt.tag_id = tag.id WHERE mt.monitor_id = ?", [this.id]);
|
||||||
const checks = await R.getAll("SELECT mc.* FROM monitor_checks mc WHERE mc.monitor_id = ?", [this.id]);
|
const checks = await this.getMonitorChecks();
|
||||||
|
|
||||||
checks.forEach(check => {
|
|
||||||
if (MONITOR_CHECK_SELECTOR_TYPES.includes(check.type) && typeof check.value === "string" && check.value.startsWith("{")) {
|
|
||||||
check.value = JSON.parse(check.value);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
id: this.id,
|
id: this.id,
|
||||||
|
@ -168,7 +162,7 @@ class Monitor extends BeanModel {
|
||||||
debug("Cert Info Query Time: " + (dayjs().valueOf() - certInfoStartTime) + "ms");
|
debug("Cert Info Query Time: " + (dayjs().valueOf() - certInfoStartTime) + "ms");
|
||||||
|
|
||||||
|
|
||||||
validateMonitorChecks(res, this.checks, bean);
|
validateMonitorChecks(res, await this.getMonitorChecks(), bean);
|
||||||
if (this.type === "http") {
|
if (this.type === "http") {
|
||||||
bean.status = UP;
|
bean.status = UP;
|
||||||
} else {
|
} else {
|
||||||
|
@ -497,11 +491,29 @@ class Monitor extends BeanModel {
|
||||||
/**
|
/**
|
||||||
* Send Uptime
|
* Send Uptime
|
||||||
* @param duration : int Hours
|
* @param duration : int Hours
|
||||||
|
* @param io
|
||||||
|
* @param monitorID
|
||||||
|
* @param userID
|
||||||
*/
|
*/
|
||||||
static async sendUptime(duration, io, monitorID, userID) {
|
static async sendUptime(duration, io, monitorID, userID) {
|
||||||
const uptime = await this.calcUptime(duration, monitorID);
|
const uptime = await this.calcUptime(duration, monitorID);
|
||||||
io.to(userID).emit("uptime", monitorID, duration, uptime);
|
io.to(userID).emit("uptime", monitorID, duration, uptime);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async getMonitorChecks() {
|
||||||
|
const checks = await R.getAll("SELECT mc.* FROM monitor_checks mc WHERE mc.monitor_id = ?", [this.id]);
|
||||||
|
|
||||||
|
checks.forEach(check => {
|
||||||
|
if (MONITOR_CHECK_SELECTOR_TYPES.includes(check.type) && typeof check.value === "string" && check.value.startsWith("{")) {
|
||||||
|
check.value = JSON.parse(check.value);
|
||||||
|
}
|
||||||
|
if (check.type === "HTTP_STATUS_CODE_SHOULD_EQUAL" && typeof check.value === "string" && check.value.startsWith("[")) {
|
||||||
|
check.value = JSON.parse(check.value);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return checks;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = Monitor;
|
module.exports = Monitor;
|
||||||
|
|
|
@ -539,17 +539,17 @@ exports.entryPage = "dashboard";
|
||||||
let trx = await R.begin();
|
let trx = await R.begin();
|
||||||
try {
|
try {
|
||||||
// delete existing checks for monitor
|
// delete existing checks for monitor
|
||||||
const existingMonitorChecks = await R.find("monitor_checks", " monitor_id = ?", [bean.id]);
|
await trx.exec("DELETE FROM `monitor_checks` WHERE monitor_id = ?", [bean.id]);
|
||||||
await trx.trashAll(existingMonitorChecks);
|
|
||||||
|
|
||||||
// Replace them with new checks
|
// Replace them with new checks
|
||||||
for (let i = 0; i < (checks || []).length; i++) {
|
for (let i = 0; i < (checks || []).length; i++) {
|
||||||
let checkBean = trx.dispense("monitor_checks");
|
let checkBean = trx.dispense("monitor_checks");
|
||||||
checks[i].monitor_id = bean.id;
|
checkBean.type = checks[i].type;
|
||||||
checks[i].value = typeof checks[i].value === "object" ? JSON.stringify(checks[i].value) : checks[i].value;
|
checkBean.value = typeof checks[i].value === "object" ? JSON.stringify(checks[i].value) : checks[i].value;
|
||||||
checkBean.import(checks[i]);
|
checkBean.monitor_id = bean.id;
|
||||||
await trx.store(checkBean);
|
await trx.store(checkBean);
|
||||||
}
|
}
|
||||||
|
await trx.commit();
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
await trx.rollback();
|
await trx.rollback();
|
||||||
throw err;
|
throw err;
|
||||||
|
|
|
@ -4,9 +4,8 @@ const get = require("lodash.get");
|
||||||
|
|
||||||
function validateMonitorChecks(res, checks, bean) {
|
function validateMonitorChecks(res, checks, bean) {
|
||||||
const responseText = typeof data === "string" ? res.data : JSON.stringify(res.data);
|
const responseText = typeof data === "string" ? res.data : JSON.stringify(res.data);
|
||||||
let checkObj;
|
|
||||||
|
|
||||||
(this.checks || []).forEach(check => {
|
(checks || []).forEach(check => {
|
||||||
switch (check.type) {
|
switch (check.type) {
|
||||||
case "HTTP_STATUS_CODE_SHOULD_EQUAL":
|
case "HTTP_STATUS_CODE_SHOULD_EQUAL":
|
||||||
if (checkStatusCode(res.status, check.value)) {
|
if (checkStatusCode(res.status, check.value)) {
|
||||||
|
@ -54,42 +53,38 @@ function validateMonitorChecks(res, checks, bean) {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "RESPONSE_SELECTOR_SHOULD_EQUAL":
|
case "RESPONSE_SELECTOR_SHOULD_EQUAL":
|
||||||
checkObj = JSON.parse(check.value);
|
if (get(res.data, check.value.selectorPath) === check.value.selectorValue) {
|
||||||
if (get(res, checkObj.selector) === checkObj.value) {
|
bean.msg += `, response selector equals '${check.value.selectorValue}'`;
|
||||||
bean.msg += `, response selector equals '${checkObj.value}'`;
|
|
||||||
bean.status = UP;
|
bean.status = UP;
|
||||||
} else {
|
} else {
|
||||||
throw new Error(`${bean.msg}, but response selector '${checkObj.selector}' does not equal '${checkObj.value}'`);
|
throw new Error(`${bean.msg}, but response selector '${check.value.selectorPath}' does not equal '${check.value.selectorValue}'`);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "RESPONSE_SELECTOR_SHOULD_NOT_EQUAL":
|
case "RESPONSE_SELECTOR_SHOULD_NOT_EQUAL":
|
||||||
checkObj = JSON.parse(check.value);
|
if (get(res.data, check.value.selectorPath) !== check.value.selectorValue) {
|
||||||
if (get(res, checkObj.selector) !== checkObj.value) {
|
bean.msg += `, response selector does not equal '${check.value.selectorValue}'`;
|
||||||
bean.msg += `, response selector does not equal '${checkObj.value}'`;
|
|
||||||
bean.status = UP;
|
bean.status = UP;
|
||||||
} else {
|
} else {
|
||||||
throw new Error(`${bean.msg}, but response selector '${checkObj.selector}' does equal '${checkObj.value}'`);
|
throw new Error(`${bean.msg}, but response selector '${check.value.selectorPath}' does equal '${check.value.selectorValue}'`);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "RESPONSE_SELECTOR_SHOULD_MATCH_REGEX":
|
case "RESPONSE_SELECTOR_SHOULD_MATCH_REGEX":
|
||||||
checkObj = JSON.parse(check.value);
|
if (get(res.data, check.value.selectorPath).test(new RegExp(check.value.selectorValue))) {
|
||||||
if (get(res, checkObj.selector).test(new RegExp(checkObj.value))) {
|
bean.msg += `, response selector matches regex '${check.value.selectorValue}'`;
|
||||||
bean.msg += `, response selector matches regex '${checkObj.value}'`;
|
|
||||||
bean.status = UP;
|
bean.status = UP;
|
||||||
} else {
|
} else {
|
||||||
throw new Error(`${bean.msg}, but response selector '${checkObj.selector}' does not match regex '${checkObj.value}'`);
|
throw new Error(`${bean.msg}, but response selector '${check.value.selectorPath}' does not match regex '${check.value.selectorValue}'`);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "RESPONSE_SELECTOR_SHOULD_NOT_MATCH_REGEX":
|
case "RESPONSE_SELECTOR_SHOULD_NOT_MATCH_REGEX":
|
||||||
checkObj = JSON.parse(check.value);
|
if (!get(res.data, check.value.selectorPath).test(new RegExp(check.value.selectorValue))) {
|
||||||
if (!get(res, checkObj.selector).test(new RegExp(checkObj.value))) {
|
bean.msg += `, response selector does not match regex '${check.value.selectorValue}'`;
|
||||||
bean.msg += `, response selector does not match regex '${checkObj.value}'`;
|
|
||||||
bean.status = UP;
|
bean.status = UP;
|
||||||
} else {
|
} else {
|
||||||
throw new Error(`${bean.msg}, but response selector '${checkObj.selector}' does match regex '${checkObj.value}'`);
|
throw new Error(`${bean.msg}, but response selector '${check.value.selectorPath}' does match regex '${check.value.selectorValue}'`);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
|
@ -43,7 +43,7 @@
|
||||||
:max-height="600"
|
:max-height="600"
|
||||||
:taggable="true"
|
:taggable="true"
|
||||||
:modelValue="monitorCheck.value"
|
:modelValue="monitorCheck.value"
|
||||||
@update:modelValue="changeValue($event.target.value)"
|
@update:model-value="changeValue"
|
||||||
></VueMultiselect>
|
></VueMultiselect>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="monitorCheck.type === 'RESPONSE_SHOULD_CONTAIN_TEXT' || monitorCheck.type === 'RESPONSE_SHOULD_NOT_CONTAIN_TEXT'">
|
<div v-if="monitorCheck.type === 'RESPONSE_SHOULD_CONTAIN_TEXT' || monitorCheck.type === 'RESPONSE_SHOULD_NOT_CONTAIN_TEXT'">
|
||||||
|
|
Loading…
Add table
Reference in a new issue