mirror of
https://github.com/louislam/uptime-kuma.git
synced 2025-06-07 21:42:34 +02:00
feat(monitor-checks): try to get monitor checks fetched and stored in db
This commit is contained in:
parent
5943c76dfb
commit
07a37534b1
6 changed files with 171 additions and 52 deletions
16
server/model/monitor-check.js
Normal file
16
server/model/monitor-check.js
Normal file
|
@ -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;
|
|
@ -10,7 +10,7 @@ const { debug, UP, DOWN, PENDING, flipStatus, TimeLogger } = require("../../src/
|
||||||
const { tcping, ping, dnsResolve, checkCertificate, getTotalClientInRoom } = require("../util-server");
|
const { tcping, ping, dnsResolve, checkCertificate, getTotalClientInRoom } = require("../util-server");
|
||||||
const { R } = require("redbean-node");
|
const { R } = require("redbean-node");
|
||||||
const { BeanModel } = require("redbean-node/dist/bean-model");
|
const { BeanModel } = require("redbean-node/dist/bean-model");
|
||||||
const { Notification } = require("../notification")
|
const { Notification } = require("../notification");
|
||||||
const validateMonitorChecks = require("./validate-monitor-checks");
|
const validateMonitorChecks = require("./validate-monitor-checks");
|
||||||
const version = require("../../package.json").version;
|
const version = require("../../package.json").version;
|
||||||
|
|
||||||
|
@ -69,7 +69,6 @@ class Monitor extends BeanModel {
|
||||||
dns_resolve_server: this.dns_resolve_server,
|
dns_resolve_server: this.dns_resolve_server,
|
||||||
dns_last_result: this.dns_last_result,
|
dns_last_result: this.dns_last_result,
|
||||||
notificationIDList,
|
notificationIDList,
|
||||||
checks: this.checks,
|
|
||||||
tags: tags,
|
tags: tags,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,20 +6,20 @@ 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;
|
let checkObj;
|
||||||
|
|
||||||
this.checks.forEach(check => {
|
(this.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)) {
|
||||||
bean.msg += `, status matches '${check.value}'`
|
bean.msg += `, status matches '${check.value}'`;
|
||||||
bean.status = UP;
|
bean.status = UP;
|
||||||
} else {
|
} 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;
|
break;
|
||||||
|
|
||||||
case "RESPONSE_SHOULD_CONTAIN_TEXT":
|
case "RESPONSE_SHOULD_CONTAIN_TEXT":
|
||||||
if (responseText.includes(check.value)) {
|
if (responseText.includes(check.value)) {
|
||||||
bean.msg += `, response contains '${check.value}'`
|
bean.msg += `, response contains '${check.value}'`;
|
||||||
bean.status = UP;
|
bean.status = UP;
|
||||||
} else {
|
} else {
|
||||||
throw new Error(bean.msg + ", but response does not contain '" + check.value + "'");
|
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":
|
case "RESPONSE_SHOULD_NOT_CONTAIN_TEXT":
|
||||||
if (!responseText.includes(check.value)) {
|
if (!responseText.includes(check.value)) {
|
||||||
bean.msg += `, response does not contain '${check.value}'`
|
bean.msg += `, response does not contain '${check.value}'`;
|
||||||
bean.status = UP;
|
bean.status = UP;
|
||||||
} else {
|
} else {
|
||||||
throw new Error(bean.msg + ", but response does contain '" + check.value + "'");
|
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":
|
case "RESPONSE_SHOULD_MATCH_REGEX":
|
||||||
if (responseText.test(new RegExp(check.value))) {
|
if (responseText.test(new RegExp(check.value))) {
|
||||||
bean.msg += `, regex '${check.value}' matches`
|
bean.msg += `, regex '${check.value}' matches`;
|
||||||
bean.status = UP;
|
bean.status = UP;
|
||||||
} else {
|
} else {
|
||||||
throw new Error(bean.msg + ", but response does not match regex: '" + check.value + "'");
|
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":
|
case "RESPONSE_SHOULD_NOT_MATCH_REGEX":
|
||||||
if (!responseText.test(new RegExp(check.value))) {
|
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;
|
bean.status = UP;
|
||||||
} else {
|
} else {
|
||||||
throw new Error(bean.msg + ", but response does match regex: '" + check.value + "'");
|
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":
|
case "RESPONSE_SELECTOR_SHOULD_EQUAL":
|
||||||
checkObj = JSON.parse(check.value);
|
checkObj = JSON.parse(check.value);
|
||||||
if (get(res, checkObj.selector) === checkObj.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;
|
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 '${checkObj.selector}' does not equal '${checkObj.value}'`);
|
||||||
|
@ -66,7 +66,7 @@ function validateMonitorChecks(res, checks, bean) {
|
||||||
case "RESPONSE_SELECTOR_SHOULD_NOT_EQUAL":
|
case "RESPONSE_SELECTOR_SHOULD_NOT_EQUAL":
|
||||||
checkObj = JSON.parse(check.value);
|
checkObj = JSON.parse(check.value);
|
||||||
if (get(res, checkObj.selector) !== checkObj.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;
|
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 '${checkObj.selector}' does equal '${checkObj.value}'`);
|
||||||
|
@ -76,7 +76,7 @@ function validateMonitorChecks(res, checks, bean) {
|
||||||
case "RESPONSE_SELECTOR_SHOULD_MATCH_REGEX":
|
case "RESPONSE_SELECTOR_SHOULD_MATCH_REGEX":
|
||||||
checkObj = JSON.parse(check.value);
|
checkObj = JSON.parse(check.value);
|
||||||
if (get(res, checkObj.selector).test(new RegExp(checkObj.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;
|
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 '${checkObj.selector}' does not match regex '${checkObj.value}'`);
|
||||||
|
@ -86,7 +86,7 @@ function validateMonitorChecks(res, checks, bean) {
|
||||||
case "RESPONSE_SELECTOR_SHOULD_NOT_MATCH_REGEX":
|
case "RESPONSE_SELECTOR_SHOULD_NOT_MATCH_REGEX":
|
||||||
checkObj = JSON.parse(check.value);
|
checkObj = JSON.parse(check.value);
|
||||||
if (!get(res, checkObj.selector).test(new RegExp(checkObj.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;
|
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 '${checkObj.selector}' does match regex '${checkObj.value}'`);
|
||||||
|
|
|
@ -71,7 +71,7 @@ if (demoMode) {
|
||||||
console.log("==== Demo Mode ====");
|
console.log("==== Demo Mode ====");
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log("Creating express and socket.io instance")
|
console.log("Creating express and socket.io instance");
|
||||||
const app = express();
|
const app = express();
|
||||||
|
|
||||||
let server;
|
let server;
|
||||||
|
@ -459,13 +459,23 @@ exports.entryPage = "dashboard";
|
||||||
let notificationIDList = monitor.notificationIDList;
|
let notificationIDList = monitor.notificationIDList;
|
||||||
delete monitor.notificationIDList;
|
delete monitor.notificationIDList;
|
||||||
|
|
||||||
monitor.checks_json = JSON.stringify(monitor.checks);
|
const checks = monitor.checks;
|
||||||
delete monitor.checks;
|
delete monitor.checks;
|
||||||
|
|
||||||
|
// Store monitor info
|
||||||
bean.import(monitor);
|
bean.import(monitor);
|
||||||
bean.user_id = socket.userID;
|
bean.user_id = socket.userID;
|
||||||
await R.store(bean);
|
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 updateMonitorNotification(bean.id, notificationIDList);
|
||||||
|
|
||||||
await startMonitor(socket.userID, bean.id);
|
await startMonitor(socket.userID, bean.id);
|
||||||
|
@ -509,10 +519,21 @@ exports.entryPage = "dashboard";
|
||||||
bean.maxredirects = monitor.maxredirects;
|
bean.maxredirects = monitor.maxredirects;
|
||||||
bean.dns_resolve_type = monitor.dns_resolve_type;
|
bean.dns_resolve_type = monitor.dns_resolve_type;
|
||||||
bean.dns_resolve_server = monitor.dns_resolve_server;
|
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);
|
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);
|
await updateMonitorNotification(bean.id, monitor.notificationIDList);
|
||||||
|
|
||||||
if (bean.active) {
|
if (bean.active) {
|
||||||
|
@ -1036,12 +1057,26 @@ exports.entryPage = "dashboard";
|
||||||
delete monitor.notificationIDList;
|
delete monitor.notificationIDList;
|
||||||
|
|
||||||
monitor.checks_json = JSON.stringify(monitor.checks);
|
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.import(monitor);
|
||||||
bean.user_id = socket.userID;
|
bean.user_id = socket.userID;
|
||||||
await R.store(bean);
|
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
|
// Only for backup files with the version 1.7.0 or higher, since there was the tag feature implemented
|
||||||
if (version17x) {
|
if (version17x) {
|
||||||
// Only import if the specific monitor has tags assigned
|
// Only import if the specific monitor has tags assigned
|
||||||
|
@ -1276,6 +1311,14 @@ async function getMonitorJSONList(userID) {
|
||||||
]);
|
]);
|
||||||
|
|
||||||
for (let monitor of monitorList) {
|
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();
|
result[monitor.id] = await monitor.toJSON();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="monitor-check mb-4">
|
<div class="monitor-check mb-4">
|
||||||
<div>
|
<div>
|
||||||
<select id="type" v-model="monitorCheck.type" :class="{'form-select': true, 'mb-1': !!monitorCheck.type}">
|
<select id="type" :value="monitorCheck.type" :class="{'form-select': true, 'mb-1': !!monitorCheck.type}" @input="changeType($event.target.value)">
|
||||||
<option value="HTTP_STATUS_CODE_SHOULD_EQUAL">
|
<option value="HTTP_STATUS_CODE_SHOULD_EQUAL">
|
||||||
{{ $t("HTTP status code should equal") }}
|
{{ $t("HTTP status code should equal") }}
|
||||||
</option>
|
</option>
|
||||||
|
@ -33,7 +33,6 @@
|
||||||
<div v-if="monitorCheck.type === 'HTTP_STATUS_CODE_SHOULD_EQUAL'">
|
<div v-if="monitorCheck.type === 'HTTP_STATUS_CODE_SHOULD_EQUAL'">
|
||||||
<VueMultiselect
|
<VueMultiselect
|
||||||
id="acceptedStatusCodes"
|
id="acceptedStatusCodes"
|
||||||
v-model="monitorCheck.value"
|
|
||||||
:options="acceptedStatusCodeOptions"
|
:options="acceptedStatusCodeOptions"
|
||||||
:multiple="true"
|
:multiple="true"
|
||||||
:close-on-select="false"
|
:close-on-select="false"
|
||||||
|
@ -43,27 +42,35 @@
|
||||||
:preselect-first="false"
|
:preselect-first="false"
|
||||||
:max-height="600"
|
:max-height="600"
|
||||||
:taggable="true"
|
:taggable="true"
|
||||||
|
:modelValue="monitorCheck.value"
|
||||||
|
@update:modelValue="changeValue($event.target.value)"
|
||||||
></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'">
|
||||||
<input v-model="monitorCheck.value" type="text" class="form-control" required :placeholder="$t('Value')">
|
<input :value="monitorCheck.value" type="text" class="form-control" required :placeholder="$t('Value')" @input="changeValue($event.target.value)">
|
||||||
</div>
|
</div>
|
||||||
<div v-if="monitorCheck.type === 'RESPONSE_SHOULD_MATCH_REGEX' || monitorCheck.type === 'RESPONSE_SHOULD_NOT_MATCH_REGEX'">
|
<div v-if="monitorCheck.type === 'RESPONSE_SHOULD_MATCH_REGEX' || monitorCheck.type === 'RESPONSE_SHOULD_NOT_MATCH_REGEX'">
|
||||||
<input v-model="monitorCheck.value" type="text" class="form-control" required
|
<input type="text" class="form-control" required :value="monitorCheck.value"
|
||||||
:placeholder="$t('Regexp, Example: [a-z0-9.]+@gmail\.com')">
|
:placeholder="$t('Regexp, Example: [a-z0-9.]+@gmail\.com')" @input="changeValue($event.target.value)"
|
||||||
|
>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
v-if="monitorCheck.type === 'RESPONSE_SELECTOR_SHOULD_EQUAL' || monitorCheck.type === 'RESPONSE_SELECTOR_SHOULD_NOT_EQUAL'">
|
v-if="monitorCheck.type === 'RESPONSE_SELECTOR_SHOULD_EQUAL' || monitorCheck.type === 'RESPONSE_SELECTOR_SHOULD_NOT_EQUAL'"
|
||||||
<input v-model="monitorCheck.value.selector" type="text" class="form-control mb-1" required
|
>
|
||||||
:placeholder="$t('Selector, Example: customer.address.street')">
|
<input :value="monitorCheck?.value?.selectorPath || ''" type="text" class="form-control mb-1" required :placeholder="$t('Selector, Example: customer.address.street')"
|
||||||
<input v-model="monitorCheck.value.value" type="text" class="form-control" required :placeholder="$t('Value, Example: First street')">
|
@input="changeSelectorPath($event.target.value)"
|
||||||
|
>
|
||||||
|
<input :value="monitorCheck?.value?.selectorValue || ''" type="text" class="form-control" required :placeholder="$t('Value, Example: First street')" @input="changeSelectorValue($event.target.value)">
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
v-if="monitorCheck.type === 'RESPONSE_SELECTOR_SHOULD_MATCH_REGEX' || monitorCheck.type === 'RESPONSE_SELECTOR_SHOULD_NOT_MATCH_REGEX'">
|
v-if="monitorCheck.type === 'RESPONSE_SELECTOR_SHOULD_MATCH_REGEX' || monitorCheck.type === 'RESPONSE_SELECTOR_SHOULD_NOT_MATCH_REGEX'"
|
||||||
<input v-model="monitorCheck.value.selector" type="text" class="form-control mb-1" required
|
>
|
||||||
:placeholder="$t('Selector, Example: customer.contactInfo.email')">
|
<input :value="monitorCheck?.value?.selectorPath || ''" type="text" class="form-control mb-1" required :placeholder="$t('Selector, Example: customer.contactInfo.email')"
|
||||||
<input v-model="monitorCheck.value.value" type="text" class="form-control" required
|
@input="changeSelectorPath($event.target.value)"
|
||||||
:placeholder="$t('Regexp, Example: [a-z0-9.]+@gmail\.com')">
|
>
|
||||||
|
<input :value="monitorCheck?.value?.selectorValue || ''" type="text" class="form-control" required :placeholder="$t('Regexp, Example: [a-z0-9.]+@gmail\.com')"
|
||||||
|
@input="changeSelectorValue($event.target.value)"
|
||||||
|
>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<button class="btn btn-outline-danger" type="button" @click="deleteMonitorCheck">
|
<button class="btn btn-outline-danger" type="button" @click="deleteMonitorCheck">
|
||||||
|
@ -82,12 +89,17 @@ export default {
|
||||||
props: {
|
props: {
|
||||||
monitorCheck: {
|
monitorCheck: {
|
||||||
type: Object,
|
type: Object,
|
||||||
|
default: () => ({
|
||||||
|
type: undefined,
|
||||||
|
value: undefined,
|
||||||
|
}),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
emits: ["change", "delete"],
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
acceptedStatusCodeOptions: [],
|
acceptedStatusCodeOptions: [],
|
||||||
}
|
};
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
let acceptedStatusCodeOptions = [
|
let acceptedStatusCodeOptions = [
|
||||||
|
@ -106,10 +118,51 @@ export default {
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
deleteMonitorCheck() {
|
deleteMonitorCheck() {
|
||||||
this.$emit('delete');
|
this.$emit("delete");
|
||||||
|
},
|
||||||
|
changeType(type) {
|
||||||
|
const stringValueTypes = ["HTTP_STATUS_CODE_SHOULD_EQUAL", "RESPONSE_SHOULD_CONTAIN_TEXT", "RESPONSE_SHOULD_NOT_CONTAIN_TEXT", "RESPONSE_SHOULD_MATCH_REGEX", "RESPONSE_SHOULD_NOT_MATCH_REGEX"];
|
||||||
|
if (stringValueTypes.includes(type) && stringValueTypes.includes(this.monitorCheck.type) ||
|
||||||
|
!stringValueTypes.includes(type) && !stringValueTypes.includes(this.monitorCheck.type)) {
|
||||||
|
// Check value stays same type (string => string or object => object)
|
||||||
|
this.$emit("change", {
|
||||||
|
...this.monitorCheck,
|
||||||
|
type,
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
// Check value switches (string => object or object => string)
|
||||||
|
this.$emit("change", {
|
||||||
|
type,
|
||||||
|
value: undefined
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
changeValue(value) {
|
||||||
|
this.$emit("change", {
|
||||||
|
...this.monitorCheck,
|
||||||
|
value,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
changeSelectorPath(selectorPath) {
|
||||||
|
this.$emit("change", {
|
||||||
|
...this.monitorCheck,
|
||||||
|
value: {
|
||||||
|
...(this.monitorCheck.value || {}),
|
||||||
|
selectorPath,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
},
|
||||||
|
changeSelectorValue(selectorValue) {
|
||||||
|
this.$emit("change", {
|
||||||
|
...this.monitorCheck,
|
||||||
|
value: {
|
||||||
|
...(this.monitorCheck.value || {}),
|
||||||
|
selectorValue,
|
||||||
|
},
|
||||||
|
});
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
|
|
|
@ -134,11 +134,11 @@
|
||||||
|
|
||||||
<h2 class="mt-5 mb-2">{{ $t("Checks") }}</h2>
|
<h2 class="mt-5 mb-2">{{ $t("Checks") }}</h2>
|
||||||
|
|
||||||
<div class="my-3">
|
<div class="my-3 mb-5">
|
||||||
<div v-for="(monitorCheck, index) in monitor.checks" :key="index" class="mb-3">
|
<div v-for="(monitorCheck, index) in monitor.checks" :key="index" class="mb-3">
|
||||||
<MonitorCheckEditor :monitorCheck="monitorCheck" :index="index" @delete="deleteMonitorCheck(index)"></MonitorCheckEditor>
|
<MonitorCheckEditor :monitorCheck="monitorCheck" @change="(newMonitorCheck) => updateMonitorCheck(newMonitorCheck, index)" @delete="() => deleteMonitorCheck(index)"></MonitorCheckEditor>
|
||||||
</div>
|
</div>
|
||||||
<button class="btn btn-light" type="button" @click="addMonitorCheck()">{{ $t("Add check") }}</button>
|
<button class="btn btn-outline-secondary btn-add-check" type="button" @click="addMonitorCheck()">{{ $t("Add check") }}</button>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -187,10 +187,10 @@
|
||||||
import NotificationDialog from "../components/NotificationDialog.vue";
|
import NotificationDialog from "../components/NotificationDialog.vue";
|
||||||
import TagsManager from "../components/TagsManager.vue";
|
import TagsManager from "../components/TagsManager.vue";
|
||||||
import MonitorCheckEditor from "../components/MonitorCheckEditor.vue";
|
import MonitorCheckEditor from "../components/MonitorCheckEditor.vue";
|
||||||
import { useToast } from "vue-toastification"
|
import { useToast } from "vue-toastification";
|
||||||
import VueMultiselect from "vue-multiselect"
|
import VueMultiselect from "vue-multiselect";
|
||||||
import { isDev } from "../util.ts";
|
import { isDev } from "../util.ts";
|
||||||
const toast = useToast()
|
const toast = useToast();
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
|
@ -214,7 +214,7 @@ export default {
|
||||||
ipRegexPattern: "((^\\s*((([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))\\s*$)|(^\\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:)))(%.+)?\\s*$))",
|
ipRegexPattern: "((^\\s*((([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))\\s*$)|(^\\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:)))(%.+)?\\s*$))",
|
||||||
// Source: https://stackoverflow.com/questions/106179/regular-expression-to-match-dns-hostname-or-ip-address
|
// Source: https://stackoverflow.com/questions/106179/regular-expression-to-match-dns-hostname-or-ip-address
|
||||||
hostnameRegexPattern: "^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\\-]*[a-zA-Z0-9])\\.)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\\-]*[A-Za-z0-9])$"
|
hostnameRegexPattern: "^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\\-]*[a-zA-Z0-9])\\.)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\\-]*[A-Za-z0-9])$"
|
||||||
}
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
computed: {
|
computed: {
|
||||||
|
@ -298,7 +298,7 @@ export default {
|
||||||
accepted_statuscodes: ["200-299"],
|
accepted_statuscodes: ["200-299"],
|
||||||
dns_resolve_type: "A",
|
dns_resolve_type: "A",
|
||||||
dns_resolve_server: "1.1.1.1",
|
dns_resolve_server: "1.1.1.1",
|
||||||
}
|
};
|
||||||
|
|
||||||
for (let i = 0; i < this.$root.notificationList.length; i++) {
|
for (let i = 0; i < this.$root.notificationList.length; i++) {
|
||||||
if (this.$root.notificationList[i].isDefault == true) {
|
if (this.$root.notificationList[i].isDefault == true) {
|
||||||
|
@ -315,19 +315,23 @@ export default {
|
||||||
this.monitor.retryInterval = this.monitor.interval;
|
this.monitor.retryInterval = this.monitor.interval;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
toast.error(res.msg)
|
toast.error(res.msg);
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
addMonitorCheck() {
|
addMonitorCheck() {
|
||||||
this.monitor.checks = [...(this.monitor.checks || []), {
|
this.monitor.checks = [...(this.monitor.checks || []), {
|
||||||
type: null,
|
type: null,
|
||||||
value: '',
|
value: "",
|
||||||
}];
|
}];
|
||||||
},
|
},
|
||||||
|
|
||||||
|
updateMonitorCheck(newMonitorCheck, index) {
|
||||||
|
this.monitor.checks[index] = newMonitorCheck;
|
||||||
|
},
|
||||||
|
|
||||||
deleteMonitorCheck(index) {
|
deleteMonitorCheck(index) {
|
||||||
this.monitor.checks = this.monitor.checks.splice(index, 1);
|
this.monitor.checks = this.monitor.checks.splice(index, 1);
|
||||||
},
|
},
|
||||||
|
@ -344,13 +348,13 @@ export default {
|
||||||
toast.success(res.msg);
|
toast.success(res.msg);
|
||||||
this.processing = false;
|
this.processing = false;
|
||||||
this.$root.getMonitorList();
|
this.$root.getMonitorList();
|
||||||
this.$router.push("/dashboard/" + res.monitorID)
|
this.$router.push("/dashboard/" + res.monitorID);
|
||||||
} else {
|
} else {
|
||||||
toast.error(res.msg);
|
toast.error(res.msg);
|
||||||
this.processing = false;
|
this.processing = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
})
|
});
|
||||||
} else {
|
} else {
|
||||||
await this.$refs.tagsManager.submit(this.monitor.id);
|
await this.$refs.tagsManager.submit(this.monitor.id);
|
||||||
|
|
||||||
|
@ -358,7 +362,7 @@ export default {
|
||||||
this.processing = false;
|
this.processing = false;
|
||||||
this.$root.toastRes(res);
|
this.$root.toastRes(res);
|
||||||
this.init();
|
this.init();
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -368,7 +372,7 @@ export default {
|
||||||
this.monitor.notificationIDList[id] = true;
|
this.monitor.notificationIDList[id] = true;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style src="vue-multiselect/dist/vue-multiselect.css"></style>
|
<style src="vue-multiselect/dist/vue-multiselect.css"></style>
|
||||||
|
@ -421,6 +425,10 @@ export default {
|
||||||
color: $dark-font-color2;
|
color: $dark-font-color2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.btn-add-check {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
|
|
Loading…
Add table
Reference in a new issue