From 07a37534b13a55ea0f67e3c5121568ef0f4b1741 Mon Sep 17 00:00:00 2001 From: Bert Verhelst Date: Mon, 27 Sep 2021 17:17:34 +0200 Subject: [PATCH] feat(monitor-checks): try to get monitor checks fetched and stored in db --- server/model/monitor-check.js | 16 +++++ server/model/monitor.js | 3 +- server/model/validate-monitor-checks.js | 22 +++--- server/server.js | 53 +++++++++++++-- src/components/MonitorCheckEditor.vue | 89 ++++++++++++++++++++----- src/pages/EditMonitor.vue | 40 ++++++----- 6 files changed, 171 insertions(+), 52 deletions(-) create mode 100644 server/model/monitor-check.js diff --git a/server/model/monitor-check.js b/server/model/monitor-check.js new file mode 100644 index 0000000..0bcf887 --- /dev/null +++ b/server/model/monitor-check.js @@ -0,0 +1,16 @@ +const { BeanModel } = require("redbean-node/dist/bean-model"); + +class MonitorCheck extends BeanModel { + /** + * Return a object that ready to parse to JSON + */ + async toJSON() { + return { + id: this.id, + type: this.type, + value: this.value, + }; + } +} + +module.exports = MonitorCheck; diff --git a/server/model/monitor.js b/server/model/monitor.js index 6e2dfaf..9374996 100644 --- a/server/model/monitor.js +++ b/server/model/monitor.js @@ -10,7 +10,7 @@ const { debug, UP, DOWN, PENDING, flipStatus, TimeLogger } = require("../../src/ const { tcping, ping, dnsResolve, checkCertificate, getTotalClientInRoom } = require("../util-server"); const { R } = require("redbean-node"); const { BeanModel } = require("redbean-node/dist/bean-model"); -const { Notification } = require("../notification") +const { Notification } = require("../notification"); const validateMonitorChecks = require("./validate-monitor-checks"); const version = require("../../package.json").version; @@ -69,7 +69,6 @@ class Monitor extends BeanModel { dns_resolve_server: this.dns_resolve_server, dns_last_result: this.dns_last_result, notificationIDList, - checks: this.checks, tags: tags, }; } diff --git a/server/model/validate-monitor-checks.js b/server/model/validate-monitor-checks.js index b43098c..f0057c1 100644 --- a/server/model/validate-monitor-checks.js +++ b/server/model/validate-monitor-checks.js @@ -6,20 +6,20 @@ function validateMonitorChecks(res, checks, bean) { const responseText = typeof data === "string" ? res.data : JSON.stringify(res.data); let checkObj; - this.checks.forEach(check => { + (this.checks || []).forEach(check => { switch (check.type) { case "HTTP_STATUS_CODE_SHOULD_EQUAL": if (checkStatusCode(res.status, check.value)) { - bean.msg += `, status matches '${check.value}'` + bean.msg += `, status matches '${check.value}'`; bean.status = UP; } else { - throw new Error(bean.msg + ", but status code dit not match " + check.value) + throw new Error(bean.msg + ", but status code dit not match " + check.value); } break; case "RESPONSE_SHOULD_CONTAIN_TEXT": if (responseText.includes(check.value)) { - bean.msg += `, response contains '${check.value}'` + bean.msg += `, response contains '${check.value}'`; bean.status = UP; } else { throw new Error(bean.msg + ", but response does not contain '" + check.value + "'"); @@ -28,7 +28,7 @@ function validateMonitorChecks(res, checks, bean) { case "RESPONSE_SHOULD_NOT_CONTAIN_TEXT": if (!responseText.includes(check.value)) { - bean.msg += `, response does not contain '${check.value}'` + bean.msg += `, response does not contain '${check.value}'`; bean.status = UP; } else { throw new Error(bean.msg + ", but response does contain '" + check.value + "'"); @@ -37,7 +37,7 @@ function validateMonitorChecks(res, checks, bean) { case "RESPONSE_SHOULD_MATCH_REGEX": if (responseText.test(new RegExp(check.value))) { - bean.msg += `, regex '${check.value}' matches` + bean.msg += `, regex '${check.value}' matches`; bean.status = UP; } else { throw new Error(bean.msg + ", but response does not match regex: '" + check.value + "'"); @@ -46,7 +46,7 @@ function validateMonitorChecks(res, checks, bean) { case "RESPONSE_SHOULD_NOT_MATCH_REGEX": if (!responseText.test(new RegExp(check.value))) { - bean.msg += `, regex '${check.value}' does not matches` + bean.msg += `, regex '${check.value}' does not matches`; bean.status = UP; } else { throw new Error(bean.msg + ", but response does match regex: '" + check.value + "'"); @@ -56,7 +56,7 @@ function validateMonitorChecks(res, checks, bean) { case "RESPONSE_SELECTOR_SHOULD_EQUAL": checkObj = JSON.parse(check.value); if (get(res, checkObj.selector) === checkObj.value) { - bean.msg += `, response selector equals '${checkObj.value}'` + bean.msg += `, response selector equals '${checkObj.value}'`; bean.status = UP; } else { throw new Error(`${bean.msg}, but response selector '${checkObj.selector}' does not equal '${checkObj.value}'`); @@ -66,7 +66,7 @@ function validateMonitorChecks(res, checks, bean) { case "RESPONSE_SELECTOR_SHOULD_NOT_EQUAL": checkObj = JSON.parse(check.value); if (get(res, checkObj.selector) !== checkObj.value) { - bean.msg += `, response selector does not equal '${checkObj.value}'` + bean.msg += `, response selector does not equal '${checkObj.value}'`; bean.status = UP; } else { throw new Error(`${bean.msg}, but response selector '${checkObj.selector}' does equal '${checkObj.value}'`); @@ -76,7 +76,7 @@ function validateMonitorChecks(res, checks, bean) { case "RESPONSE_SELECTOR_SHOULD_MATCH_REGEX": checkObj = JSON.parse(check.value); if (get(res, checkObj.selector).test(new RegExp(checkObj.value))) { - bean.msg += `, response selector matches regex '${checkObj.value}'` + bean.msg += `, response selector matches regex '${checkObj.value}'`; bean.status = UP; } else { throw new Error(`${bean.msg}, but response selector '${checkObj.selector}' does not match regex '${checkObj.value}'`); @@ -86,7 +86,7 @@ function validateMonitorChecks(res, checks, bean) { case "RESPONSE_SELECTOR_SHOULD_NOT_MATCH_REGEX": checkObj = JSON.parse(check.value); if (!get(res, checkObj.selector).test(new RegExp(checkObj.value))) { - bean.msg += `, response selector does not match regex '${checkObj.value}'` + bean.msg += `, response selector does not match regex '${checkObj.value}'`; bean.status = UP; } else { throw new Error(`${bean.msg}, but response selector '${checkObj.selector}' does match regex '${checkObj.value}'`); diff --git a/server/server.js b/server/server.js index c8101b6..4bc426a 100644 --- a/server/server.js +++ b/server/server.js @@ -71,7 +71,7 @@ if (demoMode) { console.log("==== Demo Mode ===="); } -console.log("Creating express and socket.io instance") +console.log("Creating express and socket.io instance"); const app = express(); let server; @@ -459,13 +459,23 @@ exports.entryPage = "dashboard"; let notificationIDList = monitor.notificationIDList; delete monitor.notificationIDList; - monitor.checks_json = JSON.stringify(monitor.checks); + const checks = monitor.checks; delete monitor.checks; + // Store monitor info bean.import(monitor); bean.user_id = socket.userID; await R.store(bean); + // Store checks info + for (let i = 0; i < (checks || []).length; i++) { + let checkBean = R.dispense("monitor_checks"); + checks[i].monitor_id = bean.id; + checks[i].value = typeof checks[i].value === "object" ? JSON.stringify(checks[i].value) : checks[i].value; + checkBean.import(checks[i]); + await R.store(checkBean); + } + await updateMonitorNotification(bean.id, notificationIDList); await startMonitor(socket.userID, bean.id); @@ -509,10 +519,21 @@ exports.entryPage = "dashboard"; bean.maxredirects = monitor.maxredirects; bean.dns_resolve_type = monitor.dns_resolve_type; bean.dns_resolve_server = monitor.dns_resolve_server; - bean.checks_json = JSON.stringify(monitor.checks); + + const checks = monitor.checks; + delete monitor.checks; await R.store(bean); + // Store checks info + for (let i = 0; i < (checks || []).length; i++) { + let checkBean = R.dispense("monitor_checks"); + checks[i].monitor_id = bean.id; + checks[i].value = typeof checks[i].value === "object" ? JSON.stringify(checks[i].value) : checks[i].value; + checkBean.import(checks[i]); + await R.store(checkBean); + } + await updateMonitorNotification(bean.id, monitor.notificationIDList); if (bean.active) { @@ -1034,14 +1055,28 @@ exports.entryPage = "dashboard"; let notificationIDList = monitor.notificationIDList; delete monitor.notificationIDList; - + monitor.checks_json = JSON.stringify(monitor.checks); - delete monitor.accepted_statuscodes; + + delete monitor.accepted_statuscodes; // TODO convert to check + delete monitor.keyword; // TODO convert to check + + const checks = monitor.checks; + delete monitor.checks; bean.import(monitor); bean.user_id = socket.userID; await R.store(bean); + // Store monitor checks + for (let i = 0; i < (checks || []).length; i++) { + let checkBean = R.dispense("monitor_checks"); + checks[i].monitor_id = bean.id; + checks[i].value = typeof checks[i].value === "object" ? JSON.stringify(checks[i].value) : checks[i].value; + checkBean.import(checks[i]); + await R.store(checkBean); + } + // Only for backup files with the version 1.7.0 or higher, since there was the tag feature implemented if (version17x) { // Only import if the specific monitor has tags assigned @@ -1276,6 +1311,14 @@ async function getMonitorJSONList(userID) { ]); for (let monitor of monitorList) { + const monitorChecks = await R.find("monitor_checks", " monitor_id = ? ORDER BY id", [ + monitor.id, + ]); + const monitorCheckObj = []; + for (let monitorCheck of monitorChecks) { + monitorCheckObj.push(await monitorCheck.toJSON()); + } + monitor.checks = monitorCheckObj; result[monitor.id] = await monitor.toJSON(); } diff --git a/src/components/MonitorCheckEditor.vue b/src/components/MonitorCheckEditor.vue index 72b38de..f2a992d 100644 --- a/src/components/MonitorCheckEditor.vue +++ b/src/components/MonitorCheckEditor.vue @@ -1,7 +1,7 @@