Move ping code to own file
This commit is contained in:
1 parent
0e02b7c7ea
commit
77563fc85e
4 files changed
+104
-49
No files matched your search
+3
-8
@@ -21,14 +21,13 @@ import * as url from "url";
|
|||||||
import * as mongodb from "mongodb";
|
import * as mongodb from "mongodb";
|
||||||
import * as querystring from "querystring";
|
import * as querystring from "querystring";
|
||||||
import * as vm from "vm";
|
import * as vm from "vm";
|
||||||
import { exec } from "child_process";
|
|
||||||
import * as config from "./config";
|
import * as config from "./config";
|
||||||
import * as db from "./db";
|
import * as db from "./db";
|
||||||
import * as query from "./query";
|
import * as query from "./query";
|
||||||
import * as apiFunctions from "./api-functions";
|
import * as apiFunctions from "./api-functions";
|
||||||
import * as cache from "./cache";
|
import * as cache from "./cache";
|
||||||
import { version as VERSION } from "../package.json";
|
import { version as VERSION } from "../package.json";
|
||||||
import * as os from "os";
|
import { ping } from "./ping";
|
||||||
|
|
||||||
const DEVICE_TASKS_REGEX = /^\/devices\/([a-zA-Z0-9\-_%]+)\/tasks\/?$/;
|
const DEVICE_TASKS_REGEX = /^\/devices\/([a-zA-Z0-9\-_%]+)\/tasks\/?$/;
|
||||||
const TASKS_REGEX = /^\/tasks\/([a-zA-Z0-9\-_%]+)(\/[a-zA-Z_]*)?$/;
|
const TASKS_REGEX = /^\/tasks\/([a-zA-Z0-9\-_%]+)(\/[a-zA-Z_]*)?$/;
|
||||||
@@ -43,10 +42,6 @@ const PROVISIONS_REGEX = /^\/provisions\/([a-zA-Z0-9\-_%]+)\/?$/;
|
|||||||
const VIRTUAL_PARAMETERS_REGEX = /^\/virtual_parameters\/([a-zA-Z0-9\-_%]+)\/?$/;
|
const VIRTUAL_PARAMETERS_REGEX = /^\/virtual_parameters\/([a-zA-Z0-9\-_%]+)\/?$/;
|
||||||
const FAULTS_REGEX = /^\/faults\/([a-zA-Z0-9\-_%:]+)\/?$/;
|
const FAULTS_REGEX = /^\/faults\/([a-zA-Z0-9\-_%:]+)\/?$/;
|
||||||
|
|
||||||
function pingVariant(): string {
|
|
||||||
return os.platform() === "freebsd" ? "-t 1 -c 3" : "-w 1 -i 0.2 -c 3";
|
|
||||||
}
|
|
||||||
|
|
||||||
function throwError(err, httpResponse?): never {
|
function throwError(err, httpResponse?): never {
|
||||||
if (httpResponse) {
|
if (httpResponse) {
|
||||||
httpResponse.writeHead(500, { Connection: "close" });
|
httpResponse.writeHead(500, { Connection: "close" });
|
||||||
@@ -596,9 +591,9 @@ export function listener(request, response): void {
|
|||||||
}
|
}
|
||||||
} else if (PING_REGEX.test(urlParts.pathname)) {
|
} else if (PING_REGEX.test(urlParts.pathname)) {
|
||||||
const host = querystring.unescape(PING_REGEX.exec(urlParts.pathname)[1]);
|
const host = querystring.unescape(PING_REGEX.exec(urlParts.pathname)[1]);
|
||||||
const pingArgs = pingVariant();
|
ping(host, (err, res, stdout) => {
|
||||||
exec(`ping ${pingArgs} ${host}`, (err, stdout) => {
|
|
||||||
if (err) {
|
if (err) {
|
||||||
|
if (!res) throwError(err, response);
|
||||||
response.writeHead(404, { "Cache-Control": "no-cache" });
|
response.writeHead(404, { "Cache-Control": "no-cache" });
|
||||||
response.end(`${err.name}: ${err.message}`);
|
response.end(`${err.name}: ${err.message}`);
|
||||||
return;
|
return;
|
||||||
|
|||||||
+89
@@ -0,0 +1,89 @@
|
|||||||
|
/**
|
||||||
|
* Copyright 2013-2019 GenieACS Inc.
|
||||||
|
*
|
||||||
|
* This file is part of GenieACS.
|
||||||
|
*
|
||||||
|
* GenieACS is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as
|
||||||
|
* published by the Free Software Foundation, either version 3 of the
|
||||||
|
* License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* GenieACS is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with GenieACS. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { platform } from "os";
|
||||||
|
import { exec } from "child_process";
|
||||||
|
|
||||||
|
interface Ping {
|
||||||
|
packetsTransmitted: number;
|
||||||
|
packetsReceived: number;
|
||||||
|
packetLoss: number;
|
||||||
|
min: number;
|
||||||
|
avg: number;
|
||||||
|
max: number;
|
||||||
|
mdev: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function ping(
|
||||||
|
host: string,
|
||||||
|
callback: (err, res?, stdout?) => void
|
||||||
|
): void {
|
||||||
|
let cmd: string, parseRegExp1: RegExp, parseRegExp2: RegExp;
|
||||||
|
switch (platform()) {
|
||||||
|
case "linux":
|
||||||
|
cmd = `ping -w 1 -i 0.2 -c 3 ${host}`;
|
||||||
|
parseRegExp1 = /(\d+) packets transmitted, (\d+) received, ([\d.]+)% packet loss[^]*([\d.]+)\/([\d.]+)\/([\d.]+)\/([\d.]+)/;
|
||||||
|
parseRegExp2 = /(\d+) packets transmitted, (\d+) received, ([\d.]+)% packet loss/;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "freebsd":
|
||||||
|
// Send a single packet because on FreeBSD only superuser can send
|
||||||
|
// packets that are only 200 ms apart.
|
||||||
|
cmd = `ping -t 1 -c 3 ${host}`;
|
||||||
|
parseRegExp1 = /(\d+) packets transmitted, (\d+) packets received, ([\d.]+)% packet loss\nround-trip min\/avg\/max\/stddev = ([\d.]+)\/([\d.]+)\/([\d.]+)\/([\d.]+) ms/;
|
||||||
|
parseRegExp2 = /(\d+) packets transmitted, (\d+) packets received, ([\d.]+)% packet loss/;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return callback(new Error("Platform not supported"));
|
||||||
|
}
|
||||||
|
|
||||||
|
exec(cmd, (err, stdout) => {
|
||||||
|
let parsed: Ping;
|
||||||
|
if (stdout) {
|
||||||
|
const m1 = stdout.match(parseRegExp1);
|
||||||
|
if (m1) {
|
||||||
|
parsed = {
|
||||||
|
packetsTransmitted: +m1[1],
|
||||||
|
packetsReceived: +m1[2],
|
||||||
|
packetLoss: +m1[3],
|
||||||
|
min: +m1[4],
|
||||||
|
avg: +m1[5],
|
||||||
|
max: +m1[6],
|
||||||
|
mdev: +m1[7]
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
const m2 = stdout.match(parseRegExp2);
|
||||||
|
if (m2) {
|
||||||
|
parsed = {
|
||||||
|
packetsTransmitted: +m2[1],
|
||||||
|
packetsReceived: +m2[2],
|
||||||
|
packetLoss: +m2[3],
|
||||||
|
min: null,
|
||||||
|
avg: null,
|
||||||
|
max: null,
|
||||||
|
mdev: null
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
callback(err, parsed, stdout);
|
||||||
|
});
|
||||||
|
}
|
||||||
@@ -17,7 +17,6 @@
|
|||||||
* along with GenieACS. If not, see <http://www.gnu.org/licenses/>.
|
* along with GenieACS. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { exec } from "child_process";
|
|
||||||
import { ObjectID } from "mongodb";
|
import { ObjectID } from "mongodb";
|
||||||
import * as db from "./db";
|
import * as db from "./db";
|
||||||
import { del } from "../cache";
|
import { del } from "../cache";
|
||||||
@@ -29,17 +28,6 @@ import {
|
|||||||
connectionRequest,
|
connectionRequest,
|
||||||
deleteDevice
|
deleteDevice
|
||||||
} from "../api-functions";
|
} from "../api-functions";
|
||||||
import * as os from "os";
|
|
||||||
|
|
||||||
function pingVariant(): string {
|
|
||||||
return os.platform() === "freebsd" ? "-t 1 -c 3" : "-w 1 -i 0.2 -c 3";
|
|
||||||
}
|
|
||||||
|
|
||||||
function pingOutRegex(): RegExp {
|
|
||||||
return os.platform() === "freebsd"
|
|
||||||
? /(\d) packets transmitted, (\d) packets received, ([\d.%]+) packet loss\nround-trip min\/avg\/max\/stddev = ([\d.]+)\/([\d.]+)\/([\d.]+)\/([\d.]+) ms/
|
|
||||||
: /(\d) packets transmitted, (\d) received, ([\d.%]+) packet loss[^]*([\d.]+)\/([\d.]+)\/([\d.]+)\/([\d.]+)/;
|
|
||||||
}
|
|
||||||
|
|
||||||
async function deleteFault(id): Promise<void> {
|
async function deleteFault(id): Promise<void> {
|
||||||
const deviceId = id.split(":", 1)[0];
|
const deviceId = id.split(":", 1)[0];
|
||||||
@@ -160,28 +148,6 @@ interface PingResponse {
|
|||||||
mdev: number;
|
mdev: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function ping(host): Promise<PingResponse> {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
const pingArgs = pingVariant();
|
|
||||||
exec(`ping ${pingArgs} ${host}`, (err, stdout) => {
|
|
||||||
if (err) return void reject(err);
|
|
||||||
|
|
||||||
const m = stdout.match(pingOutRegex());
|
|
||||||
if (!m) return void reject(new Error("Could not parse ping response"));
|
|
||||||
|
|
||||||
resolve({
|
|
||||||
packetsTransmitted: +m[1],
|
|
||||||
packetsReceived: +m[2],
|
|
||||||
packetLoss: m[3],
|
|
||||||
min: +m[4],
|
|
||||||
avg: +m[5],
|
|
||||||
max: +m[6],
|
|
||||||
mdev: +m[7]
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function putResource(resource, id, data): Promise<void> {
|
export async function putResource(resource, id, data): Promise<void> {
|
||||||
if (resource === "presets") {
|
if (resource === "presets") {
|
||||||
await db.putPreset(id, data);
|
await db.putPreset(id, data);
|
||||||
|
|||||||
+12
-7
@@ -29,6 +29,7 @@ import { QueryOptions, Expression } from "../types";
|
|||||||
import { generateSalt, hashPassword } from "../auth";
|
import { generateSalt, hashPassword } from "../auth";
|
||||||
import { del } from "../cache";
|
import { del } from "../cache";
|
||||||
import Authorizer from "../common/authorizer";
|
import Authorizer from "../common/authorizer";
|
||||||
|
import { ping } from "../ping";
|
||||||
|
|
||||||
const router = new Router();
|
const router = new Router();
|
||||||
export default router;
|
export default router;
|
||||||
@@ -551,13 +552,17 @@ router.post("/devices/:id/tags", async (ctx, next) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
router.get("/ping/:host", async ctx => {
|
router.get("/ping/:host", async ctx => {
|
||||||
try {
|
return new Promise(resolve => {
|
||||||
ctx.body = await apiFunctions.ping(ctx.params.host);
|
ping(ctx.params.host, (err, parsed) => {
|
||||||
} catch (err) {
|
if (parsed) {
|
||||||
ctx.status = 404;
|
ctx.body = parsed;
|
||||||
ctx.response.headers["Cache-Control"] = "no-cache";
|
} else {
|
||||||
ctx.body = `${err.name}: ${err.message}`;
|
ctx.status = 500;
|
||||||
}
|
ctx.body = `${err.name}: ${err.message}`;
|
||||||
|
}
|
||||||
|
resolve();
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
router.put("/users/:id/password", async (ctx, next) => {
|
router.put("/users/:id/password", async (ctx, next) => {
|
||||||
|
|||||||
Reference in new issue
Block a user