Added DNS Monitor Type
This commit is contained in:
parent
2912ca1248
commit
c79be19ec3
|
@ -0,0 +1,80 @@
|
|||
-- You should not modify if this have pushed to Github, unless it does serious wrong with the db.
|
||||
PRAGMA foreign_keys = off;
|
||||
|
||||
BEGIN TRANSACTION;
|
||||
|
||||
create table monitor_dg_tmp (
|
||||
id INTEGER not null primary key autoincrement,
|
||||
name VARCHAR(150),
|
||||
active BOOLEAN default 1 not null,
|
||||
user_id INTEGER references user on update cascade on delete
|
||||
set
|
||||
null,
|
||||
interval INTEGER default 20 not null,
|
||||
url TEXT,
|
||||
type VARCHAR(20),
|
||||
weight INTEGER default 2000,
|
||||
hostname VARCHAR(255),
|
||||
port INTEGER,
|
||||
created_date DATETIME default (DATETIME('now')) not null,
|
||||
keyword VARCHAR(255),
|
||||
maxretries INTEGER NOT NULL DEFAULT 0,
|
||||
ignore_tls BOOLEAN default 0 not null,
|
||||
upside_down BOOLEAN default 0 not null,
|
||||
maxredirects INTEGER default 10 not null,
|
||||
accepted_statuscodes_json TEXT default '["200-299"]' not null,
|
||||
dns_resolve_type VARCHAR(5),
|
||||
dns_resolve_server VARCHAR(255)
|
||||
);
|
||||
|
||||
insert into
|
||||
monitor_dg_tmp(
|
||||
id,
|
||||
name,
|
||||
active,
|
||||
user_id,
|
||||
interval,
|
||||
url,
|
||||
type,
|
||||
weight,
|
||||
hostname,
|
||||
port,
|
||||
created_date,
|
||||
keyword,
|
||||
maxretries,
|
||||
ignore_tls,
|
||||
upside_down,
|
||||
maxredirects,
|
||||
accepted_statuscodes_json
|
||||
)
|
||||
select
|
||||
id,
|
||||
name,
|
||||
active,
|
||||
user_id,
|
||||
interval,
|
||||
url,
|
||||
type,
|
||||
weight,
|
||||
hostname,
|
||||
port,
|
||||
created_date,
|
||||
keyword,
|
||||
maxretries,
|
||||
ignore_tls,
|
||||
upside_down,
|
||||
maxredirects,
|
||||
accepted_statuscodes_json
|
||||
from
|
||||
monitor;
|
||||
|
||||
drop table monitor;
|
||||
|
||||
alter table
|
||||
monitor_dg_tmp rename to monitor;
|
||||
|
||||
create index user_id on monitor (user_id);
|
||||
|
||||
COMMIT;
|
||||
|
||||
PRAGMA foreign_keys = on;
|
|
@ -9,7 +9,7 @@ class Database {
|
|||
|
||||
static templatePath = "./db/kuma.db"
|
||||
static path = "./data/kuma.db";
|
||||
static latestVersion = 6;
|
||||
static latestVersion = 7;
|
||||
static noReject = true;
|
||||
static sqliteInstance = null;
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@ dayjs.extend(timezone)
|
|||
const axios = require("axios");
|
||||
const { Prometheus } = require("../prometheus");
|
||||
const { debug, UP, DOWN, PENDING, flipStatus, TimeLogger } = require("../../src/util");
|
||||
const { tcping, ping, checkCertificate, checkStatusCode } = require("../util-server");
|
||||
const { tcping, ping, dnsResolve, checkCertificate, checkStatusCode } = require("../util-server");
|
||||
const { R } = require("redbean-node");
|
||||
const { BeanModel } = require("redbean-node/dist/bean-model");
|
||||
const { Notification } = require("../notification")
|
||||
|
@ -48,6 +48,8 @@ class Monitor extends BeanModel {
|
|||
upsideDown: this.isUpsideDown(),
|
||||
maxredirects: this.maxredirects,
|
||||
accepted_statuscodes: this.getAcceptedStatuscodes(),
|
||||
dns_resolve_type: this.dns_resolve_type,
|
||||
dns_resolve_server: this.dns_resolve_server,
|
||||
notificationIDList,
|
||||
};
|
||||
}
|
||||
|
@ -175,6 +177,44 @@ class Monitor extends BeanModel {
|
|||
bean.ping = await ping(this.hostname);
|
||||
bean.msg = ""
|
||||
bean.status = UP;
|
||||
} else if (this.type === "dns") {
|
||||
let startTime = dayjs().valueOf();
|
||||
|
||||
var dnsRes = await dnsResolve(this.hostname, this.dns_resolve_server, this.dns_resolve_type);
|
||||
|
||||
var dnsMessage = "";
|
||||
|
||||
if (this.dns_resolve_type == 'A' || this.dns_resolve_type == 'AAAA' || this.dns_resolve_type == 'CNAME' || this.dns_resolve_type == 'PTR') {
|
||||
var dnsMessage = dnsRes[0];
|
||||
} else if (this.dns_resolve_type == 'CAA') {
|
||||
var dnsMessage = dnsRes[0].issue;
|
||||
} else if (this.dns_resolve_type == 'MX') {
|
||||
dnsRes.forEach(record => {
|
||||
dnsMessage += `Server: ${record.exchange} - Priority: ${record.priority} | `;
|
||||
});
|
||||
var dnsMessage = dnsMessage.slice(0, -2)
|
||||
} else if (this.dns_resolve_type == 'NS') {
|
||||
dnsRes.forEach(record => {
|
||||
dnsMessage += `Server: ${record} | `;
|
||||
});
|
||||
var dnsMessage = dnsMessage.slice(0, -2)
|
||||
} else if (this.dns_resolve_type == 'SOA') {
|
||||
dnsMessage += `NS-Name: ${dnsRes.nsname} | Hostmaster: ${dnsRes.hostmaster} | Serial: ${dnsRes.serial} | Refresh: ${dnsRes.refresh} | Retry: ${dnsRes.retry} | Expire: ${dnsRes.expire} | MinTTL: ${dnsRes.minttl}`;
|
||||
} else if (this.dns_resolve_type == 'SRV') {
|
||||
dnsRes.forEach(record => {
|
||||
dnsMessage += `Name: ${record.name} | Port: ${record.port} | Priority: ${record.priority} | Weight: ${record.weight} | `;
|
||||
});
|
||||
var dnsMessage = dnsMessage.slice(0, -2)
|
||||
} else if (this.dns_resolve_type == 'TXT') {
|
||||
dnsRes.forEach(record => {
|
||||
dnsMessage += `Record: ${record} | `;
|
||||
});
|
||||
var dnsMessage = dnsMessage.slice(0, -2)
|
||||
}
|
||||
|
||||
bean.msg = dnsMessage;
|
||||
bean.ping = dayjs().valueOf() - startTime;
|
||||
bean.status = UP;
|
||||
}
|
||||
|
||||
if (this.isUpsideDown()) {
|
||||
|
|
|
@ -293,6 +293,8 @@ let indexHTML = fs.readFileSync("./dist/index.html").toString();
|
|||
bean.upsideDown = monitor.upsideDown;
|
||||
bean.maxredirects = monitor.maxredirects;
|
||||
bean.accepted_statuscodes_json = JSON.stringify(monitor.accepted_statuscodes);
|
||||
bean.dns_resolve_type = monitor.dns_resolve_type;
|
||||
bean.dns_resolve_server = monitor.dns_resolve_server;
|
||||
|
||||
await R.store(bean)
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@ const { R } = require("redbean-node");
|
|||
const { debug } = require("../src/util");
|
||||
const passwordHash = require("./password-hash");
|
||||
const dayjs = require("dayjs");
|
||||
const { Resolver } = require('dns');
|
||||
|
||||
/**
|
||||
* Init or reset JWT secret
|
||||
|
@ -76,6 +77,30 @@ exports.pingAsync = function (hostname, ipv6 = false) {
|
|||
});
|
||||
}
|
||||
|
||||
exports.dnsResolve = function (hostname, resolver_server, rrtype) {
|
||||
const resolver = new Resolver();
|
||||
resolver.setServers([resolver_server]);
|
||||
return new Promise((resolve, reject) => {
|
||||
if (rrtype == 'PTR') {
|
||||
resolver.reverse(hostname, (err, records) => {
|
||||
if (err) {
|
||||
reject(err);
|
||||
} else {
|
||||
resolve(records);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
resolver.resolve(hostname, rrtype, (err, records) => {
|
||||
if (err) {
|
||||
reject(err);
|
||||
} else {
|
||||
resolve(records);
|
||||
}
|
||||
});
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
exports.setting = async function (key) {
|
||||
let value = await R.getCell("SELECT `value` FROM setting WHERE `key` = ? ", [
|
||||
key,
|
||||
|
|
|
@ -23,6 +23,9 @@
|
|||
<option value="keyword">
|
||||
HTTP(s) - Keyword
|
||||
</option>
|
||||
<option value="dns">
|
||||
DNS
|
||||
</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
|
@ -54,6 +57,41 @@
|
|||
<input id="port" v-model="monitor.port" type="number" class="form-control" required min="0" max="65535" step="1">
|
||||
</div>
|
||||
|
||||
<div v-if="monitor.type === 'dns'" class="my-3">
|
||||
<label for="hostname" class="form-label">Hostname</label>
|
||||
<input id="hostname" v-model="monitor.hostname" type="text" class="form-control" required>
|
||||
</div>
|
||||
|
||||
<div v-if="monitor.type === 'dns'" class="my-3">
|
||||
<label for="dns_resolve_server" class="form-label">Resolver Server</label>
|
||||
<input id="dns_resolve_server" v-model="monitor.dns_resolve_server" type="text" class="form-control" :pattern="this.ipRegex" required>
|
||||
<div class="form-text">
|
||||
Cloudflare is the default server, you can change the resolver server anytime.
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-if="monitor.type === 'dns'" class="my-3">
|
||||
<label for="dns_resolve_type" class="form-label">Resource Record Type</label>
|
||||
|
||||
<VueMultiselect
|
||||
id="dns_resolve_type"
|
||||
v-model="monitor.dns_resolve_type"
|
||||
:options="dnsresolvetypeOptions"
|
||||
:multiple="false"
|
||||
:close-on-select="true"
|
||||
:clear-on-select="false"
|
||||
:preserve-search="false"
|
||||
placeholder="Pick a RR-Type..."
|
||||
:preselect-first="false"
|
||||
:max-height="500"
|
||||
:taggable="false"
|
||||
></VueMultiselect>
|
||||
|
||||
<div class="form-text">
|
||||
Select the RR-Type you want to monitor
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="my-3">
|
||||
<label for="interval" class="form-label">Heartbeat Interval (Every {{ monitor.interval }} seconds)</label>
|
||||
<input id="interval" v-model="monitor.interval" type="number" class="form-control" required min="20" step="1">
|
||||
|
@ -170,6 +208,8 @@ export default {
|
|||
notificationIDList: {},
|
||||
},
|
||||
acceptedStatusCodeOptions: [],
|
||||
dnsresolvetypeOptions: [],
|
||||
ipRegex: "((^\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*$))",
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -200,11 +240,25 @@ export default {
|
|||
"500-599",
|
||||
];
|
||||
|
||||
let dnsresolvetypeOptions = [
|
||||
"A",
|
||||
"AAAA",
|
||||
"CAA",
|
||||
"CNAME",
|
||||
"MX",
|
||||
"NS",
|
||||
"PTR",
|
||||
"SOA",
|
||||
"SRV",
|
||||
"TXT",
|
||||
];
|
||||
|
||||
for (let i = 100; i <= 999; i++) {
|
||||
acceptedStatusCodeOptions.push(i.toString());
|
||||
}
|
||||
|
||||
this.acceptedStatusCodeOptions = acceptedStatusCodeOptions;
|
||||
this.dnsresolvetypeOptions = dnsresolvetypeOptions;
|
||||
},
|
||||
methods: {
|
||||
init() {
|
||||
|
@ -221,6 +275,7 @@ export default {
|
|||
upsideDown: false,
|
||||
maxredirects: 10,
|
||||
accepted_statuscodes: ["200-299"],
|
||||
dns_resolve_server: "1.1.1.1",
|
||||
}
|
||||
} else if (this.isEdit) {
|
||||
this.$root.getSocket().emit("getMonitor", this.$route.params.id, (res) => {
|
||||
|
|
Loading…
Reference in New Issue