Files
dashy/services/ping-check.js
Benjamin GILLET daa576d30c 🔀 feat: add ICMP ping check support to item (#2180)
* feat: add ICMP ping check support to item

* Replaced ping package with pingman package to be compliant with Dashy CI NodeJS version (20).
Fixed a behavior bug in status indicator component which didn't changed icon to yellow when checking.
Made otherStatusText a computed field to make it reflecting dynamically a new check request.
Added more examples to default conf.yml

* Removed a forgotten trace to console

* Made changes requested by Lissy after review of the PR.
Corrected tests using localhost which is not a valid host for pingman.
Added a Validator.js file in src/utils with function to check validity of hosts.
Reverted conf.yml file to the original version.

* Fixed a problem in configuration of pingman call after adding support of IPV6 addresses.

* Updated Dockerfile to pass Docker smoke tests in CI

* Revert to latest version of `user-data/conf.yml` from `master`

* Removed the duplicated feature line for ping check and just added `hosts` to the existing one

* Removed the unused `shouldEnabledPingCheck` function

* Add the ping system package and give rights to use to the node user so the pingman module can work in Docker container

* Remove `src/utils/Validator.js` file. Rely on `pingman` internal validation of hostname instead to avoid command injection.
2026-06-06 12:54:17 +01:00

52 lines
1.9 KiB
JavaScript

/**
* This file contains the Node.js code, used for the optional ping check feature
* It accepts many parameters (host, count, timeout) and will make a system ping icmp
* request and then resolve the average response time.
*/
const ping = require('pingman');
const net = require('net');
/* Returned if the URL params are not present or correct */
const immediateError = (render, error) => {
render(JSON.stringify({
successStatus: false,
message: error || 'Ping check failed for unknown reason.',
}));
};
/* Main function, will check if a URL present, and call function */
module.exports = (paramStr, render) => {
if (!paramStr || !paramStr.includes('=')) {
immediateError(render);
} else {
// Prepare the parameters, which are got from the URL
const params = new URLSearchParams(paramStr);
const host = decodeURIComponent(params.get('host'));
const count = Number(decodeURIComponent(params.get('count'))) || 2;
const timeout = Number(decodeURIComponent(params.get('timeout'))) || 2000;
if (!host || typeof host !== 'string') {
immediateError(render, 'Invalid host given for ping check.');
return;
}
(async () => {
try {
const configuration = {
timeout: Math.round(timeout/1000),
numberOfEchos: count,
IPV4: net.isIPv4(host),
IPV6: net.isIPv6(host),
};
const response = await ping(host, configuration);
const results = {
successStatus: response.alive,
message: `${response.host} ${response.numericHost == response.host ? '' : `(${response.numericHost}) `} is ${response.alive ? `UP (${response.avg} ms)` : 'DOWN'}`,
timeTaken: response.time,
};
render(JSON.stringify(results));
} catch (error) {
immediateError(render, 'Ping check failed : ' + (error.message || 'Unknown error'));
}
})();
}
};