mirror of
https://github.com/louislam/uptime-kuma.git
synced 2025-06-01 19:32:34 +02:00
Feat: Handle DNS multiple A Records
This commit is contained in:
parent
b3bff8d735
commit
7df13b440a
2 changed files with 95 additions and 25 deletions
|
@ -5,7 +5,7 @@ var timezone = require('dayjs/plugin/timezone')
|
||||||
dayjs.extend(utc)
|
dayjs.extend(utc)
|
||||||
dayjs.extend(timezone)
|
dayjs.extend(timezone)
|
||||||
const axios = require("axios");
|
const axios = require("axios");
|
||||||
const {tcping, ping} = require("../util-server");
|
const {tcping, ping, dnsLookup, isIpAddress} = 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")
|
||||||
|
@ -70,34 +70,67 @@ class Monitor extends BeanModel {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (this.type === "http" || this.type === "keyword") {
|
if (this.type === "http" || this.type === "keyword") {
|
||||||
let startTime = dayjs().valueOf();
|
// Parse URL
|
||||||
let res = await axios.get(this.url, {
|
const targetUrl = new URL(this.url);
|
||||||
headers: { 'User-Agent':'Uptime-Kuma' }
|
const serversToCheck = [];
|
||||||
})
|
if (!isIpAddress(targetUrl.hostname)) {
|
||||||
bean.msg = `${res.status} - ${res.statusText}`
|
// Get DNS Result
|
||||||
bean.ping = dayjs().valueOf() - startTime;
|
const dnsResults = await dnsLookup(targetUrl.hostname);
|
||||||
|
serversToCheck.push(...dnsResults);
|
||||||
if (this.type === "http") {
|
|
||||||
bean.status = 1;
|
|
||||||
} else {
|
} else {
|
||||||
|
serversToCheck.push({ address: targetUrl.hostname });
|
||||||
let data = res.data;
|
|
||||||
|
|
||||||
// Convert to string for object/array
|
|
||||||
if (typeof data !== "string") {
|
|
||||||
data = JSON.stringify(data)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (data.includes(this.keyword)) {
|
|
||||||
bean.msg += ", keyword is found"
|
|
||||||
bean.status = 1;
|
|
||||||
} else {
|
|
||||||
throw new Error(bean.msg + ", but keyword is not found")
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
// Check each server in parallel
|
||||||
|
await Promise.all(
|
||||||
|
serversToCheck.map(async (server) => {
|
||||||
|
let startTime = dayjs().valueOf();
|
||||||
|
let res;
|
||||||
|
|
||||||
|
// Catch connection errors inside
|
||||||
|
try {
|
||||||
|
res = await axios.get(
|
||||||
|
`${targetUrl.protocol}//${server.address}`,
|
||||||
|
{
|
||||||
|
headers: {
|
||||||
|
"User-Agent": "Uptime-Kuma",
|
||||||
|
host: targetUrl.hostname,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
);
|
||||||
|
} catch (error) {
|
||||||
|
bean.msg = `server [${server.address}]: ${error.message}`;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Stop if we found a server that's up
|
||||||
|
if (bean.status == 1) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
bean.msg = `${res.status} - ${res.statusText}`;
|
||||||
|
bean.ping = dayjs().valueOf() - startTime;
|
||||||
|
|
||||||
|
if (this.type === "http") {
|
||||||
|
bean.status = 1;
|
||||||
|
} else {
|
||||||
|
let data = res.data;
|
||||||
|
|
||||||
|
// Convert to string for object/array
|
||||||
|
if (typeof data !== "string") {
|
||||||
|
data = JSON.stringify(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data.includes(this.keyword)) {
|
||||||
|
bean.msg += ", keyword is found";
|
||||||
|
bean.status = 1;
|
||||||
|
} else {
|
||||||
|
throw new Error(
|
||||||
|
bean.msg + ", but keyword is not found"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
);
|
||||||
} else if (this.type === "port") {
|
} else if (this.type === "port") {
|
||||||
bean.ping = await tcping(this.hostname, this.port);
|
bean.ping = await tcping(this.hostname, this.port);
|
||||||
bean.msg = ""
|
bean.msg = ""
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
const tcpp = require('tcp-ping');
|
const tcpp = require('tcp-ping');
|
||||||
const Ping = require("./ping-lite");
|
const Ping = require("./ping-lite");
|
||||||
const {R} = require("redbean-node");
|
const {R} = require("redbean-node");
|
||||||
|
const dns = require('dns');
|
||||||
|
|
||||||
exports.tcping = function (hostname, port) {
|
exports.tcping = function (hostname, port) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
|
@ -58,3 +59,39 @@ exports.getSettings = async function (type) {
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Async function wrapper for dns.lookup()
|
||||||
|
// Returns list of resolved IP Addresses
|
||||||
|
exports.dnsLookup = async function (name) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
dns.lookup(name, { all: true, family: 0 }, (err, ips) => {
|
||||||
|
if (err) {
|
||||||
|
reject(err);
|
||||||
|
} else {
|
||||||
|
resolve(ips);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// check if string is a valid IP address
|
||||||
|
// is-ipv6-node by @anatoliygatt
|
||||||
|
exports.isIpAddress = function (ipAddress) {
|
||||||
|
// v4
|
||||||
|
if (
|
||||||
|
/^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/.test(
|
||||||
|
ipAddress
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
// v6
|
||||||
|
if (
|
||||||
|
/(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))/.test(
|
||||||
|
ipAddress
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
Loading…
Add table
Reference in a new issue