/
linux_iplatency.js
128 lines (119 loc) · 4.13 KB
/
linux_iplatency.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
/**
* Domotz Custom Driver
* Name: Linux Monitor IP Latency
* Description: This script its designed to ping a list of IP addresses specified in the 'ipAddresses' variable from a linux host machine and retrieve their average latency and packet loss percentage.
*
* Communication protocol is SSH
*
* Tested on Linux Distributions:
* - Ubuntu 20.04 LTS
* Shell Version:
* - Bash 5.1.16
*
* Creates a Custom Driver table with a list of IP addresses, their average latency, and their packet loss.
*
**/
var packetCount = 2; // Number of packets to send during the ping command.
var ipAddresses = D.getParameter('ipAddressesToCheck');
// Set up the SSH command options
var sshCommandOptions = {
username: D.device.username(),
password: D.device.password(),
timeout: 10000
};
var tableColumns = D.createTable(
"IP Latency",
[
{ label: "Latency", unit: "ms" },
{ label: "Packet Loss", unit: "%" }
]
);
// A function to check for authentication errors during execution
function checkSshError(err) {
if (err.message) console.error(err.message);
if (err.code == 5) D.failure(D.errorType.AUTHENTICATION_ERROR);
console.error(err);
D.failure(D.errorType.GENERIC_ERROR);
}
function executeCommand(command) {
var d = D.q.defer();
sshCommandOptions.command = command;
D.device.sendSSHCommand(sshCommandOptions, function (output, error) {
if (error) {
d.resolve(error);
}else{
d.resolve(output);
}
});
return d.promise;
}
/**
* @remote_procedure
* @label Host Device Can Measure Latency
* @documentation This procedure is used to validate if the driver can be applied on a device during association as well as to verify the connectivity using the 'ping' command with specific parameters.
*/
function validate() {
var command = "man -P cat ping";
executeCommand(command)
.then(parseValidateOutput)
.then(D.success)
.catch(function (err) {
console.error(err);
D.failure(D.errorType.GENERIC_ERROR);
});
}
function parseValidateOutput(output) {
if (output.trim !== undefined && output.trim() !== "") {
console.info("Validation successful");
} else {
console.error("Validation unsuccessful. Unexpected output: " + JSON.stringify(output));
D.failure(D.errorType.RESOURCE_UNAVAILABLE);
}
}
/**
* @remote_procedure
* @label Measure IP Latency For IP Addresses
* @documentation This procedure retrieves the latency of each IP address by sending ping commands.
* It populates the Custom Driver table with the IP address, latency, and packet loss.
*/
function get_status() {
var commands = ipAddresses.map(function (ipAddress) {
var command = "ping -c " + packetCount + " " + ipAddress;
return executeCommand(command, ipAddress)
.then(function (output) {
parseOutput(output, ipAddress);
})
.catch(function (error) {
checkSshError(error);
});
});
D.q.all(commands)
.then(function () {
D.success(tableColumns);
})
.catch(function (error) {
checkSshError(error);
});
}
function sanitize(output){
var recordIdReservedWords = ['\\?', '\\*', '\\%', 'table', 'column', 'history'];
var recordIdSanitisationRegex = new RegExp(recordIdReservedWords.join('|'), 'g');
return output.replace(recordIdSanitisationRegex, '').slice(0, 50).replace(/\s+/g, '-').toLowerCase();
}
function parseOutput(output, ipAddress) {
var latencyValue, packetLossValue;
var matchLatency = /(\d+\.\d+)\/(\d+\.\d+)\/(\d+\.\d+)\/(\d+\.\d+) ms/.exec(output);
if (matchLatency && matchLatency.length >= 3) {
latencyValue = matchLatency[2];
} else {
latencyValue = "-1";
}
var matchPacketLoss = /(\d+)% packet loss/.exec(output);
if (matchPacketLoss && matchPacketLoss.length >= 2) {
packetLossValue = matchPacketLoss[1];
} else {
packetLossValue = "100";
}
var recordId = sanitize(ipAddress);
tableColumns.insertRecord(recordId, [latencyValue, packetLossValue]);
}