Monitor GameDig: Resolve domain to IP before request

This commit is contained in:
Mario Garrido 2025-07-01 05:36:58 +01:00
parent 9506b3a16b
commit d9fa67ae03
4 changed files with 78 additions and 24 deletions

View file

@ -20,7 +20,6 @@ const version = require("../../package.json").version;
const apicache = require("../modules/apicache");
const { UptimeKumaServer } = require("../uptime-kuma-server");
const { DockerHost } = require("../docker");
const Gamedig = require("gamedig");
const jwt = require("jsonwebtoken");
const crypto = require("crypto");
const { UptimeCalculator } = require("../uptime-calculator");
@ -702,21 +701,6 @@ class Monitor extends BeanModel {
} else {
throw new Error("Server not found on Steam");
}
} else if (this.type === "gamedig") {
try {
const state = await Gamedig.query({
type: this.game,
host: this.hostname,
port: this.port,
givenPortOnly: this.getGameDigGivenPortOnly(),
});
bean.msg = state.name;
bean.status = UP;
bean.ping = state.ping;
} catch (e) {
throw new Error(e.message);
}
} else if (this.type === "docker") {
log.debug("monitor", `[${this.name}] Prepare Options for Axios`);

View file

@ -0,0 +1,56 @@
const { MonitorType } = require("./monitor-type");
const { UP, DOWN } = require("../../src/util");
const Gamedig = require("gamedig");
const dns = require("dns").promises;
class GameDigMonitorType extends MonitorType {
name = "gamedig";
/**
* @inheritdoc
*/
async check(monitor, heartbeat, server) {
heartbeat.status = DOWN;
let host = monitor.hostname;
if (monitor.gamedigResolveHostToIP) {
host = await this.resolveHostname(monitor.hostname);
}
try {
const state = await Gamedig.query({
type: monitor.game,
host: host,
port: monitor.port,
givenPortOnly: Boolean(monitor.gamedigGivenPortOnly),
});
heartbeat.msg = state.name;
heartbeat.status = UP;
heartbeat.ping = state.ping;
} catch (e) {
throw new Error(e.message);
}
}
/**
* Resolves a domain name to its IPv4 address.
*
* @param {string} hostname - The domain name to resolve (e.g., "example.dyndns.org").
* @returns {Promise<string>} - The resolved IP address.
* @throws Will throw an error if the DNS resolution fails.
*/
async resolveHostname(hostname) {
try {
const result = await dns.lookup(hostname);
return result.address;
} catch (err) {
throw new Error(`DNS resolution failed for ${hostname}: ${err.message}`);
}
}
}
module.exports = {
GameDigMonitorType,
};

View file

@ -118,6 +118,7 @@ class UptimeKumaServer {
UptimeKumaServer.monitorTypeList["snmp"] = new SNMPMonitorType();
UptimeKumaServer.monitorTypeList["mongodb"] = new MongodbMonitorType();
UptimeKumaServer.monitorTypeList["rabbitmq"] = new RabbitMqMonitorType();
UptimeKumaServer.monitorTypeList["gamedig"] = new GameDigMonitorType();
UptimeKumaServer.monitorTypeList["manual"] = new ManualMonitorType();
// Allow all CORS origins (polling) in development
@ -559,5 +560,6 @@ const { GroupMonitorType } = require("./monitor-types/group");
const { SNMPMonitorType } = require("./monitor-types/snmp");
const { MongodbMonitorType } = require("./monitor-types/mongodb");
const { RabbitMqMonitorType } = require("./monitor-types/rabbitmq");
const { GameDigMonitorType } = require("./monitor-types/gamedig");
const { ManualMonitorType } = require("./monitor-types/manual");
const Monitor = require("./model/monitor");

View file

@ -201,7 +201,9 @@
<!-- Game -->
<!-- GameDig only -->
<div v-if="monitor.type === 'gamedig'" class="my-3">
<template v-if="monitor.type === 'gamedig'">
<!-- GameDig Game list -->
<div class="my-3">
<label for="game" class="form-label"> {{ $t("Game") }} </label>
<select id="game" v-model="monitor.game" class="form-select" required>
<option v-for="game in gameList" :key="game.keys[0]" :value="game.keys[0]">
@ -210,6 +212,15 @@
</select>
</div>
<!-- GameDig resolve Host to IP -->
<div class="my-3 form-check">
<input id="gamedigResolveHostToIP" v-model="monitor.gamedigResolveHostToIP" class="form-check-input" type="checkbox">
<label class="form-check-label" for="gamedigResolveHostToIP">
{{ $t("Resolve GameDig Host IP") }}
</label>
</div>
</template>
<template v-if="monitor.type === 'kafka-producer'">
<!-- Kafka Brokers List -->
<div class="my-3">
@ -1186,6 +1197,7 @@ const monitorDefaults = {
authMethod: null,
oauth_auth_method: "client_secret_basic",
httpBodyEncoding: "json",
gamedigResolveHostToIP: false,
kafkaProducerBrokers: [],
kafkaProducerSaslOptions: {
mechanism: "None",