mirror of
https://github.com/Akkadius/glass-isc-dhcp.git
synced 2025-07-27 15:44:32 +02:00
Lots of structural app changes
This commit is contained in:
parent
3d30b00e96
commit
43b0b61393
@ -6,7 +6,7 @@ var express = require('express');
|
|||||||
var router = express.Router();
|
var router = express.Router();
|
||||||
|
|
||||||
router.get('/', function (req, res, next) {
|
router.get('/', function (req, res, next) {
|
||||||
var lease_parser = require('../lib/lease_parser.js');
|
var lease_parser = require('../core/lease-parser.js');
|
||||||
lease_parser.clean();
|
lease_parser.clean();
|
||||||
|
|
||||||
var dhcp_lease_data_return_buffer = {};
|
var dhcp_lease_data_return_buffer = {};
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
var express = require('express');
|
var express = require('express');
|
||||||
var router = express.Router();
|
var router = express.Router();
|
||||||
var authorize = require('../lib/authorize.js');
|
var authorize = require('../core/authorize.js');
|
||||||
|
|
||||||
router.get('/', authorize.auth, function (req, res, next) {
|
router.get('/', authorize.auth, function (req, res, next) {
|
||||||
var json_file = require('jsonfile');
|
var json_file = require('jsonfile');
|
||||||
|
517
app.js
517
app.js
@ -1,33 +1,34 @@
|
|||||||
var express = require('express');
|
var express = require('express');
|
||||||
var path = require('path');
|
var path = require('path');
|
||||||
var favicon = require('serve-favicon');
|
|
||||||
var logger = require('morgan');
|
var logger = require('morgan');
|
||||||
var cookieParser = require('cookie-parser');
|
var cookieParser = require('cookie-parser');
|
||||||
var bodyParser = require('body-parser');
|
var bodyParser = require('body-parser');
|
||||||
|
|
||||||
const execSync = require('child_process').execSync;
|
const execSync = require('child_process').execSync;
|
||||||
|
|
||||||
var app = express();
|
var app = express();
|
||||||
|
|
||||||
/* Read Config */
|
|
||||||
var json_file = require('jsonfile');
|
var json_file = require('jsonfile');
|
||||||
var glass_config = json_file.readFileSync('config/glass_config.json');
|
var glass_config = json_file.readFileSync('config/glass_config.json');
|
||||||
|
|
||||||
// uncomment after placing your favicon in /public
|
/**
|
||||||
//app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
|
* Init Express plugins
|
||||||
|
*/
|
||||||
app.use(logger('dev'));
|
app.use(logger('dev'));
|
||||||
app.use(bodyParser.json());
|
app.use(bodyParser.json());
|
||||||
app.use(bodyParser.urlencoded({extended: false}));
|
app.use(bodyParser.urlencoded({extended: false}));
|
||||||
app.use(cookieParser());
|
app.use(cookieParser());
|
||||||
app.use(express.static(path.join(__dirname, 'public')));
|
app.use(express.static(path.join(__dirname, 'public')));
|
||||||
|
|
||||||
if (glass_config.ip_ranges_to_allow != "") {
|
/**
|
||||||
|
* Check to see if we at least have one subnet allowed
|
||||||
|
*/
|
||||||
|
if (glass_config.ip_ranges_to_allow[0] !== "") {
|
||||||
var ip_filter = require('express-ipfilter').IpFilter;
|
var ip_filter = require('express-ipfilter').IpFilter;
|
||||||
var ips = glass_config.ip_ranges_to_allow;
|
var ips = glass_config.ip_ranges_to_allow;
|
||||||
app.use(ip_filter(ips, {mode: 'allow'}));
|
app.use(ip_filter(ips, {mode: 'allow'}));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Normal Web Routes */
|
/**
|
||||||
|
* Normal web routes
|
||||||
|
*/
|
||||||
app.use('/', require('./routes/index'));
|
app.use('/', require('./routes/index'));
|
||||||
app.use('/users', require('./routes/users'));
|
app.use('/users', require('./routes/users'));
|
||||||
app.use('/get_stats', require('./routes/get_stats'));
|
app.use('/get_stats', require('./routes/get_stats'));
|
||||||
@ -46,7 +47,9 @@ app.use('/glass_alerts', require('./routes/glass_alerts'));
|
|||||||
app.use('/glass_alert_settings_save', require('./routes/glass_alert_settings_save'));
|
app.use('/glass_alert_settings_save', require('./routes/glass_alert_settings_save'));
|
||||||
app.use('/glass_settings_save', require('./routes/glass_settings_save'));
|
app.use('/glass_settings_save', require('./routes/glass_settings_save'));
|
||||||
|
|
||||||
/* API Routes */
|
/**
|
||||||
|
* API Routes
|
||||||
|
*/
|
||||||
app.use('/api/get_active_leases/', require('./api/get_active_leases'));
|
app.use('/api/get_active_leases/', require('./api/get_active_leases'));
|
||||||
app.use('/api/get_subnet_details/', require('./api/get_subnet_details'));
|
app.use('/api/get_subnet_details/', require('./api/get_subnet_details'));
|
||||||
app.use('/api/get_vendor_count/', require('./api/get_vendor_count'));
|
app.use('/api/get_vendor_count/', require('./api/get_vendor_count'));
|
||||||
@ -59,14 +62,18 @@ app.use('/api/get_websocket_config/', require('./api/get_websocket_config'));
|
|||||||
|
|
||||||
app.set('view engine', 'html');
|
app.set('view engine', 'html');
|
||||||
|
|
||||||
// catch 404 and forward to error handler
|
/**
|
||||||
|
* Catch 404
|
||||||
|
*/
|
||||||
app.use(function (req, res, next) {
|
app.use(function (req, res, next) {
|
||||||
var err = new Error('Not Found');
|
var err = new Error('Not Found');
|
||||||
err.status = 404;
|
err.status = 404;
|
||||||
next(err);
|
next(err);
|
||||||
});
|
});
|
||||||
|
|
||||||
// error handler
|
/**
|
||||||
|
* Error handler
|
||||||
|
*/
|
||||||
app.use(function (err, req, res, next) {
|
app.use(function (err, req, res, next) {
|
||||||
// set locals, only providing error in development
|
// set locals, only providing error in development
|
||||||
res.locals.message = err.message;
|
res.locals.message = err.message;
|
||||||
@ -81,294 +88,73 @@ module.exports = app;
|
|||||||
module.exports.glass_config = glass_config;
|
module.exports.glass_config = glass_config;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Global Variables
|
* App Globals
|
||||||
*/
|
*/
|
||||||
leases_per_minute = 0;
|
global.cpu_utilization = 0;
|
||||||
cpu_utilization = 0;
|
global.current_leases_per_second = 0;
|
||||||
total_leases = 0;
|
global.current_time = 0;
|
||||||
|
global.debug_watch_lease_parse_stream = 0;
|
||||||
current_time = 0;
|
global.dhcp_lease_data = {};
|
||||||
leases_per_second = 0;
|
global.dhcp_requests = {};
|
||||||
current_leases_per_second = 0;
|
global.leases_last_update_time = 0;
|
||||||
leases_last_update_time = 0;
|
global.leases_per_minute = 0;
|
||||||
|
global.leases_per_minute_counter = 0;
|
||||||
listening_to_log_file = 0;
|
global.leases_per_minute_data = [];
|
||||||
|
global.leases_per_second = 0;
|
||||||
options = {};
|
global.listening_to_log_file = 0;
|
||||||
options.interval = 1000;
|
global.oui_data = {};
|
||||||
|
global.total_leases = 0;
|
||||||
debug_watch_lease_parse_stream = 0;
|
global.socket_clients = 0;
|
||||||
|
|
||||||
host_name = execSync("cat /etc/hostname").toString().replace("\n", "");
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Ingest OUI Database
|
* Server hostname
|
||||||
*/
|
*/
|
||||||
fs = require('fs');
|
global.host_name = execSync("cat /etc/hostname").toString().replace("\n", "");
|
||||||
var oui_database_file = "bin/oui_table.txt";
|
|
||||||
/* Global oui_data bucket */
|
|
||||||
oui_data = {};
|
|
||||||
if (fs.existsSync(oui_database_file)) {
|
|
||||||
fs.readFile(oui_database_file, 'utf8', function (err, data) {
|
|
||||||
if (err) {
|
|
||||||
return console.log(err);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
/* Iterate through file */
|
|
||||||
lines = data.split("\n");
|
|
||||||
for (l = 0; l < lines.length; l++) {
|
|
||||||
/* Trim whitespaces at each ends of the line */
|
|
||||||
lines[l] = lines[l].trim();
|
|
||||||
var oui_line_data = lines[l].split(":::");
|
|
||||||
|
|
||||||
if (typeof oui_line_data[1] !== "undefined")
|
|
||||||
oui_data[oui_line_data[0].trim()] = oui_line_data[1].trim();
|
|
||||||
}
|
|
||||||
console.log("[Glass Server] OUI Database Loaded");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Ingest Current Lease File
|
* Pull in core handlers
|
||||||
*/
|
*/
|
||||||
var lease_parser = require('./lib/lease_parser.js');
|
let oui_reader = require('./core/oui-reader');
|
||||||
dhcp_lease_data = {};
|
let dhcp_leases = require('./core/dhcp-leases');
|
||||||
lease_read_buffer = "";
|
let glass_config_watcher = require('./core/glass-config-watcher');
|
||||||
|
let dhcp_log_watcher = require('./core/dhcp-log-watcher');
|
||||||
fs = require('fs');
|
let app_timers = require('./core/app-timers');
|
||||||
fs.readFile(glass_config.leases_file, 'utf8', function (err, data) {
|
|
||||||
if (err) {
|
|
||||||
return console.log(err);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
lease_parser.parse(data);
|
|
||||||
console.log("[Glass Server] Leases file loaded");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Leases File Listener
|
* Run routines
|
||||||
*/
|
*/
|
||||||
var tail_module = require('always-tail2');
|
oui_reader.initOuiDatabase();
|
||||||
tail = new tail_module(
|
dhcp_leases.parseLeasesFileOnce(glass_config);
|
||||||
glass_config.leases_file,
|
dhcp_leases.startLeaseListener(glass_config);
|
||||||
"\n",
|
dhcp_leases.setLeasesCleanTimer();
|
||||||
options
|
glass_config_watcher.init();
|
||||||
);
|
dhcp_log_watcher.init(glass_config);
|
||||||
|
|
||||||
tail.on("line", function (data) {
|
|
||||||
unix_time = Math.floor(new Date() / 1000);
|
|
||||||
|
|
||||||
/* Buffering lines until we get full lease data */
|
|
||||||
lease_read_buffer = lease_read_buffer + data + "\n";
|
|
||||||
|
|
||||||
/* End of lease - cut off and parse the buffer */
|
|
||||||
if (/}/i.test(data)) {
|
|
||||||
lease_parser.parse(lease_read_buffer);
|
|
||||||
lease_read_buffer = "";
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Count leases per second */
|
|
||||||
if (/lease/.test(data)) {
|
|
||||||
leases_per_second++;
|
|
||||||
}
|
|
||||||
if (current_time != unix_time) {
|
|
||||||
current_time = unix_time;
|
|
||||||
current_leases_per_second = leases_per_second;
|
|
||||||
leases_last_update_time = unix_time;
|
|
||||||
leases_per_second = 0;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Watch DHCP Log File
|
* Timers
|
||||||
*/
|
*/
|
||||||
|
app_timers.clearStaleWebsocketConnectionsTimer();
|
||||||
var json_file = require('jsonfile');
|
app_timers.pollCpuUtilizationTimer();
|
||||||
var glass_config = json_file.readFileSync('config/glass_config.json');
|
app_timers.purgeRequestDataCompleteTimer();
|
||||||
|
app_timers.purgeRequestDataTimer();
|
||||||
var options = {};
|
app_timers.startDashboardTimer();
|
||||||
options.interval = 1000;
|
app_timers.startLeasesPerMinuteCalculator();
|
||||||
|
|
||||||
var dashboard_timer = setInterval(function () {
|
|
||||||
// console.log("Checking timers...");
|
|
||||||
unix_time = Math.floor(new Date() / 1000);
|
|
||||||
if ((unix_time - 5) > leases_last_update_time) {
|
|
||||||
current_leases_per_second = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// console.log(JSON.stringify(dhcp_lease_data, null, 2));
|
|
||||||
|
|
||||||
}, 5000);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calculate leases per minute
|
* Websockets
|
||||||
*/
|
*/
|
||||||
var leases_per_minute_data = [];
|
|
||||||
var leases_per_minute_counter = 0;
|
|
||||||
|
|
||||||
leases_per_minute_counter_timer = setInterval(function () {
|
|
||||||
// console.log("leases per minute counter %i", leases_per_minute_counter);
|
|
||||||
|
|
||||||
leases_per_minute_data[leases_per_minute_counter] = current_leases_per_second;
|
|
||||||
leases_per_minute_counter++;
|
|
||||||
|
|
||||||
/* Count how many actual data sets we walked that have values */
|
|
||||||
leases_per_minute = 0;
|
|
||||||
for (i = 0; i < 59; i++) {
|
|
||||||
if (leases_per_minute_data[i] > 0) {
|
|
||||||
leases_per_minute += leases_per_minute_data[i];
|
|
||||||
// console.log("iteration " + i + " val: " + leases_per_minute_data[i] + " lpm: " + leases_per_minute);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// console.log("no data " + i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (leases_per_minute_counter == 60)
|
|
||||||
leases_per_minute_counter = 0;
|
|
||||||
|
|
||||||
|
|
||||||
/* Websockets statistics subscription broadcast */
|
|
||||||
if (ws_event_subscribers('dhcp_statistics')) {
|
|
||||||
return_data = {
|
|
||||||
"cpu_utilization": cpu_utilization,
|
|
||||||
"leases_per_second": current_leases_per_second,
|
|
||||||
"leases_per_minute": leases_per_minute
|
|
||||||
};
|
|
||||||
wss.broadcast_event(JSON.stringify(return_data), 'dhcp_statistics');
|
|
||||||
}
|
|
||||||
|
|
||||||
}, 1000);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Poll: CPU Utilization
|
|
||||||
*/
|
|
||||||
cpu_utilization_poll = setInterval(function () {
|
|
||||||
cpu_utilization = parseFloat(execSync("top -bn 1 | awk 'NR>7{s+=$9} END {print s/4}'").toString())
|
|
||||||
}, (15 * 1000));
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Clean Expired Leases
|
|
||||||
*/
|
|
||||||
lease_clean_timer = setInterval(function () {
|
|
||||||
lease_parser.clean();
|
|
||||||
}, (60 * 1000));
|
|
||||||
|
|
||||||
function get_socket_clients_connected_count() {
|
|
||||||
wss.clients.forEach(function each(client) {
|
|
||||||
if (client.readyState === WebSocket.OPEN) {
|
|
||||||
socket_clients++;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return socket_clients;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Watch config changes so we reload it for core functions...
|
|
||||||
*/
|
|
||||||
fs.watch('config/glass_config.json', function (event, filename) {
|
|
||||||
if (filename) {
|
|
||||||
setTimeout(function () {
|
|
||||||
glass_config = json_file.readFileSync('config/glass_config.json');
|
|
||||||
console.log("[Glass Server] Config Loaded");
|
|
||||||
}, 1000);
|
|
||||||
} else {
|
|
||||||
console.log('filename not provided');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Websocket Server
|
|
||||||
*/
|
|
||||||
|
|
||||||
const WebSocket = require('ws');
|
const WebSocket = require('ws');
|
||||||
const ws_port = glass_config.ws_port || 8080;
|
const ws_port = glass_config.ws_port || 8080;
|
||||||
const wss = new WebSocket.Server({port: ws_port});
|
|
||||||
|
|
||||||
options.interval = 300;
|
console.log("[Glass Server] Websocket server starting on port: " + ws_port);
|
||||||
var tail_dhcp_log = new tail_module(
|
|
||||||
glass_config.log_file,
|
|
||||||
"\n",
|
|
||||||
options
|
|
||||||
);
|
|
||||||
|
|
||||||
dhcp_requests = {};
|
global.wss = new WebSocket.Server({port: ws_port});
|
||||||
|
|
||||||
tail_dhcp_log.on("line", function (data) {
|
|
||||||
if (listening_to_log_file) {
|
|
||||||
wss.broadcast_event(data, 'dhcp_log_subscription');
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Collect Excessive DHCP Request Data */
|
|
||||||
if (/DHCPREQUEST/i.test(data)) {
|
|
||||||
|
|
||||||
var request_from = "";
|
|
||||||
var request_for = "";
|
|
||||||
var request_via = "";
|
|
||||||
|
|
||||||
var request_data = data.split(" ");
|
|
||||||
var length = request_data.length;
|
|
||||||
for (var i = 0; i < length; i++) {
|
|
||||||
if (request_data[i] == "from") {
|
|
||||||
request_from = request_data[i + 1];
|
|
||||||
}
|
|
||||||
if (request_data[i] == "for") {
|
|
||||||
request_for = request_data[i + 1];
|
|
||||||
}
|
|
||||||
if (request_data[i] == "via") {
|
|
||||||
request_via = request_data[i + 1];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (typeof dhcp_requests[request_from] === "undefined")
|
|
||||||
dhcp_requests[request_from] = {};
|
|
||||||
|
|
||||||
if (typeof dhcp_requests[request_from].request_for === "undefined")
|
|
||||||
dhcp_requests[request_from].request_for = request_for;
|
|
||||||
|
|
||||||
if (typeof dhcp_requests[request_from].request_via === "undefined")
|
|
||||||
dhcp_requests[request_from].request_via = request_via;
|
|
||||||
|
|
||||||
if (typeof dhcp_requests[request_from].request_count === "undefined")
|
|
||||||
dhcp_requests[request_from].request_count = 0;
|
|
||||||
|
|
||||||
if (typeof request_from !== "undefined") {
|
|
||||||
if (request_from.length == 17 && /:/.test(request_from)) {
|
|
||||||
var mac_oui = request_from.split(":").join("").toUpperCase().slice(0, 6);
|
|
||||||
|
|
||||||
if (typeof dhcp_requests[request_from].request_vendor === "undefined")
|
|
||||||
dhcp_requests[request_from].request_vendor = oui_data[mac_oui];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
dhcp_requests[request_from].request_count++;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
const purge_request_data = setInterval(function () {
|
|
||||||
for (var key in dhcp_requests) {
|
|
||||||
if (dhcp_requests[key].request_count <= 10)
|
|
||||||
delete dhcp_requests[key];
|
|
||||||
}
|
|
||||||
}, 600 * 1000);
|
|
||||||
/* 10 Minutes */
|
|
||||||
|
|
||||||
const purge_request_data_hour = setInterval(function () {
|
|
||||||
dhcp_requests = {};
|
|
||||||
}, 3600 * 1000);
|
|
||||||
/* 60 Minutes */
|
|
||||||
|
|
||||||
wss.on('connection', function connection(ws) {
|
wss.on('connection', function connection(ws) {
|
||||||
socket_clients++;
|
socket_clients++;
|
||||||
console.log("[WS] CLIENT_CONNECT: Socket clients (" + socket_clients + ")");
|
console.log("[WS] CLIENT_CONNECT: Socket clients (" + socket_clients + ")");
|
||||||
|
|
||||||
if (!listening_to_log_file) {
|
if (!listening_to_log_file) {
|
||||||
/* Watch log file for new information */
|
|
||||||
var tail_module = require('always-tail2');
|
|
||||||
|
|
||||||
listening_to_log_file = 1;
|
listening_to_log_file = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -379,51 +165,13 @@ wss.on('close', function close() {
|
|||||||
console.log("[WS] CLIENT_DISCONNECT: Socket clients (" + socket_clients + ")");
|
console.log("[WS] CLIENT_DISCONNECT: Socket clients (" + socket_clients + ")");
|
||||||
});
|
});
|
||||||
|
|
||||||
function heartbeat() {
|
|
||||||
this.isAlive = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
function isJson(str) {
|
|
||||||
try {
|
|
||||||
JSON.parse(str);
|
|
||||||
} catch (e) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
function ws_event_subscribers(event) {
|
|
||||||
if (typeof wss === "undefined")
|
|
||||||
return false;
|
|
||||||
|
|
||||||
var is_listening = false;
|
|
||||||
|
|
||||||
wss.clients.forEach(function each(ws) {
|
|
||||||
|
|
||||||
/* Count event listeners */
|
|
||||||
for (var event_listening in ws.event_subscription) {
|
|
||||||
if (event_listening == event) {
|
|
||||||
is_listening = true;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
if (is_listening) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
wss.on('connection', function connection(ws) {
|
wss.on('connection', function connection(ws) {
|
||||||
ws.isAlive = true;
|
ws.isAlive = true;
|
||||||
ws.on('pong', heartbeat);
|
ws.on('pong', heartbeat);
|
||||||
ws.event_subscription = [];
|
ws.event_subscription = [];
|
||||||
|
|
||||||
ws.on('message', function incoming(data) {
|
ws.on('message', function incoming(data) {
|
||||||
if (data != "" && isJson(data)) {
|
if (data !== "" && isJson(data)) {
|
||||||
var json = JSON.parse(data);
|
var json = JSON.parse(data);
|
||||||
if (typeof json["event_subscription"] !== "undefined") {
|
if (typeof json["event_subscription"] !== "undefined") {
|
||||||
console.log("[WS] Incoming Subscription '%s'", json['event_subscription']);
|
console.log("[WS] Incoming Subscription '%s'", json['event_subscription']);
|
||||||
@ -443,6 +191,15 @@ wss.on('connection', function connection(ws) {
|
|||||||
stale_connections_audit();
|
stale_connections_audit();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
get_socket_clients_connected_count = function () {
|
||||||
|
wss.clients.forEach(function each(client) {
|
||||||
|
if (client.readyState === WebSocket.OPEN) {
|
||||||
|
socket_clients++;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return socket_clients;
|
||||||
|
};
|
||||||
|
|
||||||
wss.broadcast = function broadcast(data) {
|
wss.broadcast = function broadcast(data) {
|
||||||
wss.clients.forEach(function each(client) {
|
wss.clients.forEach(function each(client) {
|
||||||
if (client.readyState === WebSocket.OPEN) {
|
if (client.readyState === WebSocket.OPEN) {
|
||||||
@ -460,7 +217,7 @@ wss.broadcast_event = function broadcast(data, event) {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
function stale_connections_audit() {
|
stale_connections_audit = function() {
|
||||||
socket_clients = 0;
|
socket_clients = 0;
|
||||||
wss.clients.forEach(function each(ws) {
|
wss.clients.forEach(function each(ws) {
|
||||||
if (ws.isAlive === false) return ws.terminate();
|
if (ws.isAlive === false) return ws.terminate();
|
||||||
@ -472,39 +229,44 @@ function stale_connections_audit() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
console.log("[WS] STATUS: Socket clients (" + socket_clients + ")");
|
console.log("[WS] STATUS: Socket clients (" + socket_clients + ")");
|
||||||
|
};
|
||||||
|
|
||||||
|
heartbeat = function() {
|
||||||
|
this.isAlive = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
isJson = function(str) {
|
||||||
|
try {
|
||||||
|
JSON.parse(str);
|
||||||
|
} catch (e) {
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
/* Keepalive - kill stale connections (30s poll) */
|
are_clients_subscribed_to_ws_event = function(event) {
|
||||||
const interval = setInterval(function ping() {
|
if (typeof wss === "undefined")
|
||||||
stale_connections_audit();
|
return false;
|
||||||
}, 30000);
|
|
||||||
|
|
||||||
var socket_clients = 0;
|
var is_listening = false;
|
||||||
|
|
||||||
|
wss.clients.forEach(function each(ws) {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Slack Hooks
|
* Count event listeners
|
||||||
*/
|
*/
|
||||||
|
for (var event_listening in ws.event_subscription) {
|
||||||
var Slack = require('slack-node');
|
if (event_listening === event) {
|
||||||
|
is_listening = true;
|
||||||
webhookUri = glass_config.slack_webhook_url;
|
return true;
|
||||||
|
|
||||||
slack = new Slack();
|
|
||||||
slack.setWebhook(webhookUri);
|
|
||||||
|
|
||||||
function slack_message(message) {
|
|
||||||
console.log("[Slack] %s", message);
|
|
||||||
|
|
||||||
slack.webhook({
|
|
||||||
channel: glass_config.slack_alert_channel,
|
|
||||||
username: "Glass",
|
|
||||||
icon_emoji: "https://imgur.com/wD3CcBi",
|
|
||||||
text: "(" + host_name + ") " + message
|
|
||||||
}, function (err, response) {
|
|
||||||
console.log(response);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return is_listening;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Alert Checks
|
* Alert Checks
|
||||||
@ -515,11 +277,11 @@ alert_status['leases_per_minute'] = 0;
|
|||||||
setTimeout(function () {
|
setTimeout(function () {
|
||||||
console.log("[Glass Server] Alert loop started");
|
console.log("[Glass Server] Alert loop started");
|
||||||
|
|
||||||
alert_check_timer = setInterval(function () {
|
let alert_check_timer = setInterval(function () {
|
||||||
// console.log("[Timer] Alert Timer check");
|
// console.log("[Timer] Alert Timer check");
|
||||||
if (glass_config.leases_per_minute_threshold > 0) {
|
if (glass_config.leases_per_minute_threshold > 0) {
|
||||||
// console.log("[Timer] lpm: %s lpm_th: %s", leases_per_minute, glass_config.leases_per_minute_threshold);
|
// console.log("[Timer] lpm: %s lpm_th: %s", leases_per_minute, glass_config.leases_per_minute_threshold);
|
||||||
if (leases_per_minute <= glass_config.leases_per_minute_threshold && alert_status['leases_per_minute'] == 0) {
|
if (leases_per_minute <= glass_config.leases_per_minute_threshold && alert_status['leases_per_minute'] === 0) {
|
||||||
alert_status['leases_per_minute'] = 1;
|
alert_status['leases_per_minute'] = 1;
|
||||||
|
|
||||||
slack_message(":warning: CRITICAL: DHCP leases per minute have dropped below threshold " +
|
slack_message(":warning: CRITICAL: DHCP leases per minute have dropped below threshold " +
|
||||||
@ -531,7 +293,7 @@ setTimeout(function () {
|
|||||||
"Current: (" + parseInt(leases_per_minute).toLocaleString('en') + ") <br><br>" +
|
"Current: (" + parseInt(leases_per_minute).toLocaleString('en') + ") <br><br>" +
|
||||||
"This is usually indicative of a process or hardware problem and needs to be addressed immediately");
|
"This is usually indicative of a process or hardware problem and needs to be addressed immediately");
|
||||||
}
|
}
|
||||||
else if (leases_per_minute >= glass_config.leases_per_minute_threshold && alert_status['leases_per_minute'] == 1) {
|
else if (leases_per_minute >= glass_config.leases_per_minute_threshold && alert_status['leases_per_minute'] === 1) {
|
||||||
alert_status['leases_per_minute'] = 0;
|
alert_status['leases_per_minute'] = 0;
|
||||||
|
|
||||||
slack_message(":white_check_mark: CLEAR: DHCP leases per minute have returned to above threshold " +
|
slack_message(":white_check_mark: CLEAR: DHCP leases per minute have returned to above threshold " +
|
||||||
@ -550,7 +312,7 @@ setTimeout(function () {
|
|||||||
alert_status_networks_warning = [];
|
alert_status_networks_warning = [];
|
||||||
alert_status_networks_critical = [];
|
alert_status_networks_critical = [];
|
||||||
|
|
||||||
alert_subnet_check_timer = setInterval(function () {
|
let alert_subnet_check_timer = setInterval(function () {
|
||||||
// console.log("[Timer] Alert Timer check - subnets");
|
// console.log("[Timer] Alert Timer check - subnets");
|
||||||
|
|
||||||
if (glass_config.shared_network_warning_threshold > 0 || glass_config.shared_network_critical_threshold > 0) {
|
if (glass_config.shared_network_warning_threshold > 0 || glass_config.shared_network_critical_threshold > 0) {
|
||||||
@ -589,7 +351,7 @@ setTimeout(function () {
|
|||||||
if (
|
if (
|
||||||
utilization >= glass_config.shared_network_warning_threshold &&
|
utilization >= glass_config.shared_network_warning_threshold &&
|
||||||
utilization <= glass_config.shared_network_critical_threshold &&
|
utilization <= glass_config.shared_network_critical_threshold &&
|
||||||
alert_status_networks_warning[dhcp_data['shared-networks'][i].location] == 0
|
alert_status_networks_warning[dhcp_data['shared-networks'][i].location] === 0
|
||||||
) {
|
) {
|
||||||
alert_status_networks_warning[dhcp_data['shared-networks'][i].location] = 1;
|
alert_status_networks_warning[dhcp_data['shared-networks'][i].location] = 1;
|
||||||
|
|
||||||
@ -607,7 +369,7 @@ setTimeout(function () {
|
|||||||
}
|
}
|
||||||
else if (
|
else if (
|
||||||
utilization <= glass_config.shared_network_warning_threshold &&
|
utilization <= glass_config.shared_network_warning_threshold &&
|
||||||
alert_status_networks_warning[dhcp_data['shared-networks'][i].location] == 1
|
alert_status_networks_warning[dhcp_data['shared-networks'][i].location] === 1
|
||||||
) {
|
) {
|
||||||
alert_status_networks_warning[dhcp_data['shared-networks'][i].location] = 0;
|
alert_status_networks_warning[dhcp_data['shared-networks'][i].location] = 0;
|
||||||
|
|
||||||
@ -629,7 +391,7 @@ setTimeout(function () {
|
|||||||
if (glass_config.shared_network_critical_threshold > 0) {
|
if (glass_config.shared_network_critical_threshold > 0) {
|
||||||
if (
|
if (
|
||||||
utilization >= glass_config.shared_network_critical_threshold &&
|
utilization >= glass_config.shared_network_critical_threshold &&
|
||||||
alert_status_networks_critical[dhcp_data['shared-networks'][i].location] == 0
|
alert_status_networks_critical[dhcp_data['shared-networks'][i].location] === 0
|
||||||
) {
|
) {
|
||||||
alert_status_networks_critical[dhcp_data['shared-networks'][i].location] = 1;
|
alert_status_networks_critical[dhcp_data['shared-networks'][i].location] = 1;
|
||||||
slack_message(":fire: CRITICAL: DHCP shared network utilization (" + dhcp_data['shared-networks'][i].location + ") " +
|
slack_message(":fire: CRITICAL: DHCP shared network utilization (" + dhcp_data['shared-networks'][i].location + ") " +
|
||||||
@ -646,7 +408,7 @@ setTimeout(function () {
|
|||||||
}
|
}
|
||||||
else if (
|
else if (
|
||||||
utilization <= glass_config.shared_network_critical_threshold &&
|
utilization <= glass_config.shared_network_critical_threshold &&
|
||||||
alert_status_networks_critical[dhcp_data['shared-networks'][i].location] == 1
|
alert_status_networks_critical[dhcp_data['shared-networks'][i].location] === 1
|
||||||
) {
|
) {
|
||||||
alert_status_networks_critical[dhcp_data['shared-networks'][i].location] = 0;
|
alert_status_networks_critical[dhcp_data['shared-networks'][i].location] = 0;
|
||||||
slack_message(":white_check_mark: CLEAR: Critical DHCP shared network utilization (" + dhcp_data['shared-networks'][i].location + ") " +
|
slack_message(":white_check_mark: CLEAR: Critical DHCP shared network utilization (" + dhcp_data['shared-networks'][i].location + ") " +
|
||||||
@ -674,27 +436,29 @@ function round(num, places) {
|
|||||||
/* Load Mailer */
|
/* Load Mailer */
|
||||||
const nodemailer = require('nodemailer');
|
const nodemailer = require('nodemailer');
|
||||||
|
|
||||||
let transporter = nodemailer.createTransport({
|
let transporter = nodemailer.createTransport(
|
||||||
|
{
|
||||||
sendmail: true,
|
sendmail: true,
|
||||||
newline: 'unix',
|
newline: 'unix',
|
||||||
path: '/usr/sbin/sendmail'
|
path: '/usr/sbin/sendmail'
|
||||||
});
|
}
|
||||||
|
);
|
||||||
|
|
||||||
function email_alert(alert_title, alert_message) {
|
function email_alert(alert_title, alert_message) {
|
||||||
|
if (typeof glass_config.email_alert_to === "undefined" && typeof glass_config.sms_alert_to === "undefined") {
|
||||||
|
console.log("[Glass Server] E-Mail alert triggered, but no addresses configured...");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
console.log("[Glass Server] Loading E-Mail template...");
|
console.log("[Glass Server] Loading E-Mail template...");
|
||||||
fs = require('fs');
|
var fs = require('fs');
|
||||||
var email_body = fs.readFileSync('./public/templates/email_template.html', "utf8");
|
var email_body = fs.readFileSync('./public/templates/email_template.html', "utf8");
|
||||||
console.log("[Glass Server] Loading E-Mail template... DONE...");
|
console.log("[Glass Server] Loading E-Mail template... DONE...");
|
||||||
|
|
||||||
/* E-Mail Template Load */
|
/* E-Mail Template Load */
|
||||||
console.log("[Glass Server] Sending E-Mail Alert...\n");
|
console.log("[Glass Server] Sending E-Mail Alert...\n");
|
||||||
|
|
||||||
if (typeof glass_config.email_alert_to === "undefined" && typeof glass_config.sms_alert_to === "undefined")
|
if (glass_config.email_alert_to === "" && glass_config.sms_alert_to !== "") {
|
||||||
return false;
|
|
||||||
|
|
||||||
if (glass_config.email_alert_to == "" && glass_config.sms_alert_to != "") {
|
|
||||||
console.log("[Glass Server] No email_to specified - returning...");
|
console.log("[Glass Server] No email_to specified - returning...");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -708,7 +472,7 @@ function email_alert(alert_title, alert_message) {
|
|||||||
glass_config.email_alert_to = glass_config.email_alert_to.replace(/^[,\s]+|[,\s]+$/g, '').replace(/,[,\s]*,/g, ',');
|
glass_config.email_alert_to = glass_config.email_alert_to.replace(/^[,\s]+|[,\s]+$/g, '').replace(/,[,\s]*,/g, ',');
|
||||||
|
|
||||||
/* Send regular HTML E-Mails */
|
/* Send regular HTML E-Mails */
|
||||||
if (glass_config.email_alert_to.trim() != "") {
|
if (glass_config.email_alert_to.trim() !== "") {
|
||||||
var mailOptions = {
|
var mailOptions = {
|
||||||
from: "Glass Alerting Monitor glass@noreply.com",
|
from: "Glass Alerting Monitor glass@noreply.com",
|
||||||
to: glass_config.email_alert_to,
|
to: glass_config.email_alert_to,
|
||||||
@ -726,7 +490,7 @@ function email_alert(alert_title, alert_message) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Send SMS */
|
/* Send SMS */
|
||||||
if (glass_config.sms_alert_to.trim() != "") {
|
if (glass_config.sms_alert_to.trim() !== "") {
|
||||||
var mailOptions = {
|
var mailOptions = {
|
||||||
from: "Glass Alerting Monitor glass@noreply.com",
|
from: "Glass Alerting Monitor glass@noreply.com",
|
||||||
to: glass_config.sms_alert_to,
|
to: glass_config.sms_alert_to,
|
||||||
@ -744,4 +508,43 @@ function email_alert(alert_title, alert_message) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Slack Hooks
|
||||||
|
*/
|
||||||
|
|
||||||
|
var Slack = require('slack-node');
|
||||||
|
|
||||||
|
webhookUri = glass_config.slack_webhook_url;
|
||||||
|
|
||||||
|
slack = new Slack();
|
||||||
|
slack.setWebhook(webhookUri);
|
||||||
|
|
||||||
|
function slack_message(message) {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If webhook is not set in config, return
|
||||||
|
*/
|
||||||
|
if (glass_config.slack_webhook_url.trim() === "") {
|
||||||
|
console.log("[Glass Server] Slack alert triggered, but no webhook configured...");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log("[Slack] %s", message);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send message
|
||||||
|
*/
|
||||||
|
slack.webhook(
|
||||||
|
{
|
||||||
|
channel: glass_config.slack_alert_channel,
|
||||||
|
username: "Glass",
|
||||||
|
icon_emoji: "https://imgur.com/wD3CcBi",
|
||||||
|
text: "(" + host_name + ") " + message
|
||||||
|
},
|
||||||
|
function (err, response) {
|
||||||
|
console.log(response);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
console.log("[Glass Server] Bootup complete");
|
console.log("[Glass Server] Bootup complete");
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
"admin_user": "glassadmin",
|
"admin_user": "glassadmin",
|
||||||
"admin_password": "glassadmin",
|
"admin_password": "glassadmin",
|
||||||
"leases_file": "/var/lib/dhcp/dhcpd.leases",
|
"leases_file": "/var/lib/dhcp/dhcpd.leases",
|
||||||
"log_file": "/var/log/dhcp.log",
|
"log_file": "/var/log/syslog",
|
||||||
"config_file": "/etc/dhcp/dhcpd.conf",
|
"config_file": "/etc/dhcp/dhcpd.conf",
|
||||||
"shared_network_critical_threshold": "95",
|
"shared_network_critical_threshold": "95",
|
||||||
"shared_network_warning_threshold": "0",
|
"shared_network_warning_threshold": "0",
|
||||||
|
69
core/app-timers.js
Normal file
69
core/app-timers.js
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
var fs = require('fs');
|
||||||
|
const execSync = require('child_process').execSync;
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
startLeasesPerMinuteCalculator: function () {
|
||||||
|
return setInterval(function () {
|
||||||
|
leases_per_minute_data[leases_per_minute_counter] = current_leases_per_second;
|
||||||
|
leases_per_minute_counter++;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Count how many actual data sets we walked that have values
|
||||||
|
*/
|
||||||
|
leases_per_minute = 0;
|
||||||
|
for (i = 0; i < 59; i++) {
|
||||||
|
if (leases_per_minute_data[i] > 0) {
|
||||||
|
leases_per_minute += leases_per_minute_data[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (leases_per_minute_counter === 60)
|
||||||
|
leases_per_minute_counter = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Websockets statistics subscription broadcast
|
||||||
|
*/
|
||||||
|
if (are_clients_subscribed_to_ws_event('dhcp_statistics')) {
|
||||||
|
return_data = {
|
||||||
|
"cpu_utilization": cpu_utilization,
|
||||||
|
"leases_per_second": current_leases_per_second,
|
||||||
|
"leases_per_minute": leases_per_minute
|
||||||
|
};
|
||||||
|
wss.broadcast_event(JSON.stringify(return_data), 'dhcp_statistics');
|
||||||
|
}
|
||||||
|
|
||||||
|
}, 1000);
|
||||||
|
},
|
||||||
|
startDashboardTimer: function () {
|
||||||
|
return setInterval(function () {
|
||||||
|
unix_time = Math.floor(new Date() / 1000);
|
||||||
|
if ((unix_time - 5) > leases_last_update_time) {
|
||||||
|
current_leases_per_second = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
}, 5000);
|
||||||
|
},
|
||||||
|
pollCpuUtilizationTimer: function () {
|
||||||
|
return setInterval(function () {
|
||||||
|
cpu_utilization = parseFloat(execSync("top -bn 1 | awk 'NR>7{s+=$9} END {print s/4}'").toString())
|
||||||
|
}, (15 * 1000));
|
||||||
|
},
|
||||||
|
clearStaleWebsocketConnectionsTimer: function () {
|
||||||
|
return setInterval(function () {
|
||||||
|
stale_connections_audit();
|
||||||
|
}, 30000);
|
||||||
|
},
|
||||||
|
purgeRequestDataTimer: function () {
|
||||||
|
return setInterval(function () {
|
||||||
|
for (var key in dhcp_requests) {
|
||||||
|
if (dhcp_requests[key].request_count <= 10)
|
||||||
|
delete dhcp_requests[key];
|
||||||
|
}
|
||||||
|
}, 600 * 1000);
|
||||||
|
},
|
||||||
|
purgeRequestDataCompleteTimer: function () {
|
||||||
|
return setInterval(function () {
|
||||||
|
dhcp_requests = {};
|
||||||
|
}, 3600 * 1000)
|
||||||
|
}
|
||||||
|
};
|
65
core/dhcp-leases.js
Normal file
65
core/dhcp-leases.js
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
var lease_parser = require('./lease-parser.js');
|
||||||
|
var fs = require('fs');
|
||||||
|
var tail = require('always-tail2');
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
parseLeasesFileOnce: function (glass_config) {
|
||||||
|
fs.readFile(glass_config.leases_file, 'utf8', function (err, data) {
|
||||||
|
if (err) {
|
||||||
|
return console.log(err);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
lease_parser.parse(data);
|
||||||
|
console.log("[Glass Server] Leases file loaded");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
startLeaseListener: function (glass_config) {
|
||||||
|
var lease_read_buffer = "";
|
||||||
|
var options = {};
|
||||||
|
options.interval = 1000;
|
||||||
|
|
||||||
|
let file_tail = new tail(
|
||||||
|
glass_config.leases_file,
|
||||||
|
"\n",
|
||||||
|
options
|
||||||
|
);
|
||||||
|
|
||||||
|
console.log("[Glass Server] Watching leases file '" + glass_config.leases_file + "'");
|
||||||
|
|
||||||
|
file_tail.on("line", function (data) {
|
||||||
|
unix_time = Math.floor(new Date() / 1000);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Buffering lines until we get full lease data
|
||||||
|
*/
|
||||||
|
lease_read_buffer = lease_read_buffer + data + "\n";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* End of lease - cut off and parse the buffer
|
||||||
|
*/
|
||||||
|
if (/}/i.test(data)) {
|
||||||
|
lease_parser.parse(lease_read_buffer);
|
||||||
|
lease_read_buffer = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Count leases per second
|
||||||
|
*/
|
||||||
|
if (/lease/.test(data)) {
|
||||||
|
leases_per_second++;
|
||||||
|
}
|
||||||
|
if (current_time !== unix_time) {
|
||||||
|
current_time = unix_time;
|
||||||
|
current_leases_per_second = leases_per_second;
|
||||||
|
leases_last_update_time = unix_time;
|
||||||
|
leases_per_second = 0;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
setLeasesCleanTimer: function () {
|
||||||
|
return setInterval(function () {
|
||||||
|
lease_parser.clean();
|
||||||
|
}, (60 * 1000));
|
||||||
|
}
|
||||||
|
};
|
73
core/dhcp-log-watcher.js
Normal file
73
core/dhcp-log-watcher.js
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
var tail = require('always-tail2');
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
init: function (glass_config) {
|
||||||
|
console.log("[Glass Server] DHCP log watcher initialized");
|
||||||
|
|
||||||
|
var options = {};
|
||||||
|
options.interval = 300;
|
||||||
|
var tail_dhcp_log = new tail(
|
||||||
|
glass_config.log_file,
|
||||||
|
"\n",
|
||||||
|
options
|
||||||
|
);
|
||||||
|
|
||||||
|
tail_dhcp_log.on("line", function (data) {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Broadcast log data
|
||||||
|
*/
|
||||||
|
if (listening_to_log_file) {
|
||||||
|
wss.broadcast_event(data, 'dhcp_log_subscription');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Collect Excessive DHCP Request Data
|
||||||
|
*/
|
||||||
|
if (/DHCPREQUEST/i.test(data)) {
|
||||||
|
|
||||||
|
var request_from = "";
|
||||||
|
var request_for = "";
|
||||||
|
var request_via = "";
|
||||||
|
|
||||||
|
var request_data = data.split(" ");
|
||||||
|
var length = request_data.length;
|
||||||
|
for (var i = 0; i < length; i++) {
|
||||||
|
if (request_data[i] === "from") {
|
||||||
|
request_from = request_data[i + 1];
|
||||||
|
}
|
||||||
|
if (request_data[i] === "for") {
|
||||||
|
request_for = request_data[i + 1];
|
||||||
|
}
|
||||||
|
if (request_data[i] === "via") {
|
||||||
|
request_via = request_data[i + 1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof dhcp_requests[request_from] === "undefined")
|
||||||
|
dhcp_requests[request_from] = {};
|
||||||
|
|
||||||
|
if (typeof dhcp_requests[request_from].request_for === "undefined")
|
||||||
|
dhcp_requests[request_from].request_for = request_for;
|
||||||
|
|
||||||
|
if (typeof dhcp_requests[request_from].request_via === "undefined")
|
||||||
|
dhcp_requests[request_from].request_via = request_via;
|
||||||
|
|
||||||
|
if (typeof dhcp_requests[request_from].request_count === "undefined")
|
||||||
|
dhcp_requests[request_from].request_count = 0;
|
||||||
|
|
||||||
|
if (typeof request_from !== "undefined") {
|
||||||
|
if (request_from.length === 17 && /:/.test(request_from)) {
|
||||||
|
var mac_oui = request_from.split(":").join("").toUpperCase().slice(0, 6);
|
||||||
|
|
||||||
|
if (typeof dhcp_requests[request_from].request_vendor === "undefined")
|
||||||
|
dhcp_requests[request_from].request_vendor = oui_data[mac_oui];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dhcp_requests[request_from].request_count++;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
},
|
||||||
|
};
|
17
core/glass-config-watcher.js
Normal file
17
core/glass-config-watcher.js
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
var fs = require('fs');
|
||||||
|
var json_file = require('jsonfile');
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
init: function () {
|
||||||
|
console.log("[Glass Server] Config watcher initialized");
|
||||||
|
|
||||||
|
fs.watch('config/glass_config.json', function (event, filename) {
|
||||||
|
if (filename) {
|
||||||
|
fsTimeout = setTimeout(function () {
|
||||||
|
glass_config = json_file.readFileSync('config/glass_config.json');
|
||||||
|
console.log("[Glass Server] Config Loaded");
|
||||||
|
}, 1000);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
};
|
145
core/lease-parser.js
Normal file
145
core/lease-parser.js
Normal file
@ -0,0 +1,145 @@
|
|||||||
|
/**
|
||||||
|
* Created by cmiles on 8/9/2017.
|
||||||
|
*/
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
parse: function (input) {
|
||||||
|
var lease_data = input.split("lease");
|
||||||
|
for (i = 0; i < lease_data.length; i++) {
|
||||||
|
ip_address = "";
|
||||||
|
|
||||||
|
lines = lease_data[i].split("\n");
|
||||||
|
for (l = 0; l < lines.length; l++) {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Trim whitespaces at each ends of the line
|
||||||
|
*/
|
||||||
|
lines[l] = lines[l].trim();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Break each newline into an array split into spaces
|
||||||
|
* Ex: [ 'starts', '3', '2017/08/09', '04:50:53;' ]
|
||||||
|
*
|
||||||
|
* @type {string[]}
|
||||||
|
*/
|
||||||
|
line_data_arg = lines[l].split(" ");
|
||||||
|
|
||||||
|
if (/{/i.test(lines[l]) && /\./i.test(lines[l]) && !/uid/i.test(lines[l])) {
|
||||||
|
ip_address = line_data_arg[0].trim();
|
||||||
|
if (typeof dhcp_lease_data[ip_address] === "undefined") {
|
||||||
|
dhcp_lease_data[ip_address] = {};
|
||||||
|
}
|
||||||
|
option_data = {};
|
||||||
|
}
|
||||||
|
if (ip_address !== "") {
|
||||||
|
if (/start/i.test(lines[l])) {
|
||||||
|
/*
|
||||||
|
Make sure we force format as UTC because that is what the leases are formatted in
|
||||||
|
*/
|
||||||
|
date = (line_data_arg[2] + ' ' + line_data_arg[3]).trim().replace(/\//gi, '-').replace(/;/i, '') + ' UTC';
|
||||||
|
|
||||||
|
start_unix_time = (Date.parse(date) / 1000);
|
||||||
|
dhcp_lease_data[ip_address].start = start_unix_time;
|
||||||
|
}
|
||||||
|
if (/ends/i.test(lines[l])) {
|
||||||
|
/*
|
||||||
|
Make sure we force format as UTC because that is what the leases are formatted in
|
||||||
|
*/
|
||||||
|
lease_end = (line_data_arg[2] + ' ' + line_data_arg[3]).trim().replace(/\//gi, '-').replace(/;/i, '') + ' UTC';
|
||||||
|
|
||||||
|
now_unix_time = parseInt((new Date().getTime() / 1000).toFixed(0));
|
||||||
|
end_unix_time = parseInt((new Date(lease_end).getTime() / 1000).toFixed(0).toLocaleString());
|
||||||
|
|
||||||
|
/*
|
||||||
|
console.log('now ' + now_unix_time);
|
||||||
|
console.log('end ' + end_unix_time);
|
||||||
|
|
||||||
|
console.log('now ' + new Date());
|
||||||
|
console.log('end_raw ' + lease_end);
|
||||||
|
console.log('end ' + new Date(lease_end));
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (end_unix_time <= now_unix_time) {
|
||||||
|
delete dhcp_lease_data[ip_address];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
dhcp_lease_data[ip_address].end = end_unix_time;
|
||||||
|
}
|
||||||
|
if (/ethernet/i.test(lines[l])) {
|
||||||
|
if (typeof line_data_arg[2] !== "undefined") {
|
||||||
|
dhcp_lease_data[ip_address].mac = line_data_arg[2].replace(/;/gi, '').trim();
|
||||||
|
|
||||||
|
if (dhcp_lease_data[ip_address].mac.split(":").join("").trim() === "")
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (dhcp_lease_data[ip_address].mac.split(":").join("").toUpperCase().trim() === "")
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* Mac OUI Lookup */
|
||||||
|
var mac_oui = dhcp_lease_data[ip_address].mac.split(":").join("").toUpperCase().slice(0, 6);
|
||||||
|
|
||||||
|
dhcp_lease_data[ip_address].mac_oui_vendor = '';
|
||||||
|
if (typeof oui_data[mac_oui] !== "undefined") {
|
||||||
|
dhcp_lease_data[ip_address].mac_oui_vendor = oui_data[mac_oui];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (/hostname/i.test(lines[l])) {
|
||||||
|
if (typeof line_data_arg[1] !== "undefined")
|
||||||
|
dhcp_lease_data[ip_address].host = line_data_arg[1].replace(/;/gi, '').replace(/"/gi, '').trim();
|
||||||
|
}
|
||||||
|
if (/set/i.test(lines[l])) {
|
||||||
|
set_data = lines[l].replace(/;/gi, '').replace(/"/gi, '').replace(/ = /gi, ' ').replace(/set/gi, '').trim();
|
||||||
|
set_data_split = set_data.split(" ");
|
||||||
|
|
||||||
|
option_key = set_data_split[0].trim();
|
||||||
|
option_value = set_data.replace(RegExp(option_key, "g"), '').trim();
|
||||||
|
|
||||||
|
option_data[option_key] = option_value;
|
||||||
|
|
||||||
|
if (typeof dhcp_lease_data[ip_address]['options'] === "undefined")
|
||||||
|
dhcp_lease_data[ip_address]['options'] = [];
|
||||||
|
}
|
||||||
|
if (/option/i.test(lines[l])) {
|
||||||
|
set_data = lines[l].replace(/;/gi, '').replace(/"/gi, '').replace(/ = /gi, ' ').replace(/option/gi, '').trim();
|
||||||
|
set_data_split = set_data.split(" ");
|
||||||
|
|
||||||
|
option_key = set_data_split[0].trim();
|
||||||
|
option_value = set_data.replace(RegExp(option_key, "g"), '').trim();
|
||||||
|
|
||||||
|
option_data[option_key] = option_value;
|
||||||
|
|
||||||
|
if (typeof dhcp_lease_data[ip_address]['options'] === "undefined")
|
||||||
|
dhcp_lease_data[ip_address]['options'] = [];
|
||||||
|
}
|
||||||
|
if (lines[l].charAt(0) === "}" && typeof dhcp_lease_data[ip_address]['options'] !== "undefined") {
|
||||||
|
if (typeof option_data !== 'undefined') {
|
||||||
|
dhcp_lease_data[ip_address]['options'] = option_data;
|
||||||
|
}
|
||||||
|
|
||||||
|
option_data = [];
|
||||||
|
}
|
||||||
|
/* End of Lease */
|
||||||
|
if (lines[l].charAt(0) === "}") {
|
||||||
|
if (debug_watch_lease_parse_stream) {
|
||||||
|
console.log("[Glass Server] Lease Parse");
|
||||||
|
console.log(JSON.stringify(dhcp_lease_data[ip_address], null, 2));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
},
|
||||||
|
clean: function () {
|
||||||
|
for (var key in dhcp_lease_data) {
|
||||||
|
now_unix_time = parseInt((new Date().getTime() / 1000).toFixed(0));
|
||||||
|
end_unix_time = dhcp_lease_data[key].end;
|
||||||
|
|
||||||
|
if ((now_unix_time >= end_unix_time)) {
|
||||||
|
console.log("[DHCP Lease Data] Lease " + key + " has expired - clearing");
|
||||||
|
delete dhcp_lease_data[key];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
27
core/oui-reader.js
Normal file
27
core/oui-reader.js
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
var fs = require('fs');
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
initOuiDatabase: function () {
|
||||||
|
var oui_database_file = "bin/oui_table.txt";
|
||||||
|
|
||||||
|
if (fs.existsSync(oui_database_file)) {
|
||||||
|
fs.readFile(oui_database_file, 'utf8', function (err, data) {
|
||||||
|
if (err) {
|
||||||
|
return console.log(err);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
lines = data.split("\n");
|
||||||
|
for (l = 0; l < lines.length; l++) {
|
||||||
|
/* Trim whitespaces at each ends of the line */
|
||||||
|
lines[l] = lines[l].trim();
|
||||||
|
var oui_line_data = lines[l].split(":::");
|
||||||
|
|
||||||
|
if (typeof oui_line_data[1] !== "undefined")
|
||||||
|
oui_data[oui_line_data[0].trim()] = oui_line_data[1].trim();
|
||||||
|
}
|
||||||
|
console.log("[Glass Server] OUI Database Loaded");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
@ -30,4 +30,3 @@ module.exports = {
|
|||||||
return '<label>' + title + '</label><div class="form-group"><div class="form-line">' + input + '</div></div>';
|
return '<label>' + title + '</label><div class="form-group"><div class="form-line">' + input + '</div></div>';
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
@ -1,140 +0,0 @@
|
|||||||
/**
|
|
||||||
* Created by cmiles on 8/9/2017.
|
|
||||||
*/
|
|
||||||
|
|
||||||
module.exports = {
|
|
||||||
parse: function (input) {
|
|
||||||
var lease_data = input.split("lease");
|
|
||||||
for (i = 0; i < lease_data.length; i++) {
|
|
||||||
ip_address = "";
|
|
||||||
|
|
||||||
lines = lease_data[i].split("\n");
|
|
||||||
for (l = 0; l < lines.length; l++) {
|
|
||||||
/* Trim whitespaces at each ends of the line */
|
|
||||||
lines[l] = lines[l].trim();
|
|
||||||
|
|
||||||
/* Break each newline into an array split into spaces
|
|
||||||
Ex: [ 'starts', '3', '2017/08/09', '04:50:53;' ]
|
|
||||||
*/
|
|
||||||
|
|
||||||
line_data_arg = lines[l].split(" ");
|
|
||||||
|
|
||||||
if (/{/i.test(lines[l]) && /\./i.test(lines[l]) && !/uid/i.test(lines[l])) {
|
|
||||||
ip_address = line_data_arg[0].trim();
|
|
||||||
if (typeof dhcp_lease_data[ip_address] === "undefined") {
|
|
||||||
dhcp_lease_data[ip_address] = {};
|
|
||||||
}
|
|
||||||
option_data = {};
|
|
||||||
}
|
|
||||||
if (ip_address != "") {
|
|
||||||
if (/start/i.test(lines[l])) {
|
|
||||||
/*
|
|
||||||
Make sure we force format as UTC because that is what the leases are formatted in
|
|
||||||
*/
|
|
||||||
date = (line_data_arg[2] + ' ' + line_data_arg[3]).trim().replace(/\//gi, '-').replace(/;/i, '') + ' UTC';
|
|
||||||
|
|
||||||
start_unix_time = (Date.parse(date) / 1000);
|
|
||||||
dhcp_lease_data[ip_address].start = start_unix_time;
|
|
||||||
}
|
|
||||||
if (/ends/i.test(lines[l])) {
|
|
||||||
/*
|
|
||||||
Make sure we force format as UTC because that is what the leases are formatted in
|
|
||||||
*/
|
|
||||||
lease_end = (line_data_arg[2] + ' ' + line_data_arg[3]).trim().replace(/\//gi, '-').replace(/;/i, '') + ' UTC';
|
|
||||||
|
|
||||||
now_unix_time = parseInt((new Date().getTime() / 1000).toFixed(0));
|
|
||||||
end_unix_time = parseInt((new Date(lease_end).getTime() / 1000).toFixed(0).toLocaleString());
|
|
||||||
|
|
||||||
/*
|
|
||||||
console.log('now ' + now_unix_time);
|
|
||||||
console.log('end ' + end_unix_time);
|
|
||||||
|
|
||||||
console.log('now ' + new Date());
|
|
||||||
console.log('end_raw ' + lease_end);
|
|
||||||
console.log('end ' + new Date(lease_end));
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (end_unix_time <= now_unix_time) {
|
|
||||||
delete dhcp_lease_data[ip_address];
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
dhcp_lease_data[ip_address].end = end_unix_time;
|
|
||||||
}
|
|
||||||
if (/ethernet/i.test(lines[l])) {
|
|
||||||
if (typeof line_data_arg[2] !== "undefined") {
|
|
||||||
dhcp_lease_data[ip_address].mac = line_data_arg[2].replace(/;/gi, '').trim();
|
|
||||||
|
|
||||||
if (dhcp_lease_data[ip_address].mac.split(":").join("").trim() == "")
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (dhcp_lease_data[ip_address].mac.split(":").join("").toUpperCase().trim() == "")
|
|
||||||
continue;
|
|
||||||
|
|
||||||
/* Mac OUI Lookup */
|
|
||||||
var mac_oui = dhcp_lease_data[ip_address].mac.split(":").join("").toUpperCase().slice(0, 6);
|
|
||||||
|
|
||||||
dhcp_lease_data[ip_address].mac_oui_vendor = '';
|
|
||||||
if (typeof oui_data[mac_oui] !== "undefined") {
|
|
||||||
dhcp_lease_data[ip_address].mac_oui_vendor = oui_data[mac_oui];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (/hostname/i.test(lines[l])) {
|
|
||||||
if (typeof line_data_arg[1] !== "undefined")
|
|
||||||
dhcp_lease_data[ip_address].host = line_data_arg[1].replace(/;/gi, '').replace(/"/gi, '').trim();
|
|
||||||
}
|
|
||||||
if (/set/i.test(lines[l])) {
|
|
||||||
set_data = lines[l].replace(/;/gi, '').replace(/"/gi, '').replace(/ = /gi, ' ').replace(/set/gi, '').trim();
|
|
||||||
set_data_split = set_data.split(" ");
|
|
||||||
|
|
||||||
option_key = set_data_split[0].trim();
|
|
||||||
option_value = set_data.replace(RegExp(option_key, "g"), '').trim();
|
|
||||||
|
|
||||||
option_data[option_key] = option_value;
|
|
||||||
|
|
||||||
if (typeof dhcp_lease_data[ip_address]['options'] === "undefined")
|
|
||||||
dhcp_lease_data[ip_address]['options'] = [];
|
|
||||||
}
|
|
||||||
if (/option/i.test(lines[l])) {
|
|
||||||
set_data = lines[l].replace(/;/gi, '').replace(/"/gi, '').replace(/ = /gi, ' ').replace(/option/gi, '').trim();
|
|
||||||
set_data_split = set_data.split(" ");
|
|
||||||
|
|
||||||
option_key = set_data_split[0].trim();
|
|
||||||
option_value = set_data.replace(RegExp(option_key, "g"), '').trim();
|
|
||||||
|
|
||||||
option_data[option_key] = option_value;
|
|
||||||
|
|
||||||
if (typeof dhcp_lease_data[ip_address]['options'] === "undefined")
|
|
||||||
dhcp_lease_data[ip_address]['options'] = [];
|
|
||||||
}
|
|
||||||
if (lines[l].charAt(0) == "}" && typeof dhcp_lease_data[ip_address]['options'] !== "undefined") {
|
|
||||||
if (typeof option_data !== 'undefined') {
|
|
||||||
dhcp_lease_data[ip_address]['options'] = option_data;
|
|
||||||
}
|
|
||||||
|
|
||||||
option_data = [];
|
|
||||||
}
|
|
||||||
/* End of Lease */
|
|
||||||
if (lines[l].charAt(0) == "}") {
|
|
||||||
if (debug_watch_lease_parse_stream) {
|
|
||||||
console.log("[Glass Server] Lease Parse");
|
|
||||||
console.log(JSON.stringify(dhcp_lease_data[ip_address], null, 2));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
},
|
|
||||||
clean: function () {
|
|
||||||
for (var key in dhcp_lease_data) {
|
|
||||||
now_unix_time = parseInt((new Date().getTime() / 1000).toFixed(0));
|
|
||||||
end_unix_time = dhcp_lease_data[key].end;
|
|
||||||
|
|
||||||
if ((now_unix_time >= end_unix_time)) {
|
|
||||||
console.log("[DHCP Lease Data] Lease " + key + " has expired - clearing");
|
|
||||||
delete dhcp_lease_data[key];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
};
|
|
@ -2,11 +2,13 @@ function log_action (action) {
|
|||||||
switch (action) {
|
switch (action) {
|
||||||
case "stop":
|
case "stop":
|
||||||
websockets_unsubscribe_event("dhcp_log_subscription");
|
websockets_unsubscribe_event("dhcp_log_subscription");
|
||||||
|
notification('Log watch stopped');
|
||||||
break;
|
break;
|
||||||
case "start":
|
case "start":
|
||||||
killed_connection = 0;
|
killed_connection = 0;
|
||||||
console.log('start readystate is ' + socket.readyState);
|
console.log('start readystate is ' + socket.readyState);
|
||||||
websockets_subscribe_event("dhcp_log_subscription");
|
websockets_subscribe_event("dhcp_log_subscription");
|
||||||
|
notification('Log watch started');
|
||||||
break;
|
break;
|
||||||
case "clear":
|
case "clear":
|
||||||
editor.setValue("");
|
editor.setValue("");
|
||||||
|
@ -157,8 +157,8 @@
|
|||||||
<!-- Footer -->
|
<!-- Footer -->
|
||||||
<div class="legal">
|
<div class="legal">
|
||||||
<div class="copyright">
|
<div class="copyright">
|
||||||
© 2017 <a href="javascript:void(0);">Glass | Chris Miles</a><br>
|
© 2017 - 2018 <a href="https://github.com/Akkadius/glass-isc-dhcp" target="glass">Glass | Chris Miles</a><br>
|
||||||
© 2016 - 2017 <a href="javascript:void(0);">AdminBSB - Material Design</a>
|
© 2016 - 2017 <a href="https://github.com/gurayyarar/AdminBSBMaterialDesign" target="bsb">AdminBSB - Material Design</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="version">
|
<div class="version">
|
||||||
<b>Version: </b> 1.0.0
|
<b>Version: </b> 1.0.0
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
var express = require('express');
|
var express = require('express');
|
||||||
var router = express.Router();
|
var router = express.Router();
|
||||||
var fs = require('fs');
|
var fs = require('fs');
|
||||||
var template_render = require('../lib/render_template.js');
|
var template_render = require('../core/render-template.js');
|
||||||
|
|
||||||
router.get('/', function(req, res, next) {
|
router.get('/', function(req, res, next) {
|
||||||
|
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
var express = require('express');
|
var express = require('express');
|
||||||
var router = express.Router();
|
var router = express.Router();
|
||||||
var fs = require('fs');
|
var fs = require('fs');
|
||||||
var template_render = require('../lib/render_template.js');
|
var template_render = require('../core/render-template.js');
|
||||||
var authorize = require('../lib/authorize.js');
|
var authorize = require('../core/authorize.js');
|
||||||
|
|
||||||
router.get('/', authorize.auth, function(req, res, next) {
|
router.get('/', authorize.auth, function(req, res, next) {
|
||||||
|
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
var express = require('express');
|
var express = require('express');
|
||||||
var router = express.Router();
|
var router = express.Router();
|
||||||
|
|
||||||
var authorize = require('../lib/authorize.js');
|
var authorize = require('../core/authorize.js');
|
||||||
|
|
||||||
router.post('/', authorize.auth, function(req, res, next) {
|
router.post('/', authorize.auth, function(req, res, next) {
|
||||||
var request = req.body;
|
var request = req.body;
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
var express = require('express');
|
var express = require('express');
|
||||||
var router = express.Router();
|
var router = express.Router();
|
||||||
var fs = require('fs');
|
var fs = require('fs');
|
||||||
var template_render = require('../lib/render_template.js');
|
var template_render = require('../core/render-template.js');
|
||||||
var authorize = require('../lib/authorize.js');
|
var authorize = require('../core/authorize.js');
|
||||||
|
|
||||||
router.post('/', authorize.auth, function(req, res, next) {
|
router.post('/', authorize.auth, function(req, res, next) {
|
||||||
var request = req.body;
|
var request = req.body;
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
var express = require('express');
|
var express = require('express');
|
||||||
var router = express.Router();
|
var router = express.Router();
|
||||||
var fs = require('fs');
|
var fs = require('fs');
|
||||||
var template_render = require('../lib/render_template.js');
|
var template_render = require('../core/render-template.js');
|
||||||
var authorize = require('../lib/authorize.js');
|
var authorize = require('../core/authorize.js');
|
||||||
|
|
||||||
function human_time (time){
|
function human_time (time){
|
||||||
var time = new Date(time);
|
var time = new Date(time);
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
var express = require('express');
|
var express = require('express');
|
||||||
var router = express.Router();
|
var router = express.Router();
|
||||||
var fs = require('fs');
|
var fs = require('fs');
|
||||||
var template_render = require('../lib/render_template.js');
|
var template_render = require('../core/render-template.js');
|
||||||
|
|
||||||
function human_time (time){
|
function human_time (time){
|
||||||
var time = new Date(time);
|
var time = new Date(time);
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
var express = require('express');
|
var express = require('express');
|
||||||
var router = express.Router();
|
var router = express.Router();
|
||||||
var fs = require('fs');
|
var fs = require('fs');
|
||||||
var template_render = require('../lib/render_template.js');
|
var template_render = require('../core/render-template.js');
|
||||||
|
|
||||||
function human_time (time){
|
function human_time (time){
|
||||||
var time = new Date(time);
|
var time = new Date(time);
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
var express = require('express');
|
var express = require('express');
|
||||||
var router = express.Router();
|
var router = express.Router();
|
||||||
var fs = require('fs');
|
var fs = require('fs');
|
||||||
var template_render = require('../lib/render_template.js');
|
var template_render = require('../core/render-template.js');
|
||||||
|
|
||||||
function human_time (time){
|
function human_time (time){
|
||||||
var time = new Date(time);
|
var time = new Date(time);
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
var express = require('express');
|
var express = require('express');
|
||||||
var router = express.Router();
|
var router = express.Router();
|
||||||
var template_render = require('../lib/render_template.js');
|
var template_render = require('../core/render-template.js');
|
||||||
var authorize = require('../lib/authorize.js');
|
var authorize = require('../core/authorize.js');
|
||||||
|
|
||||||
router.get('/', authorize.auth, function (req, res, next) {
|
router.get('/', authorize.auth, function (req, res, next) {
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
var express = require('express');
|
var express = require('express');
|
||||||
var router = express.Router();
|
var router = express.Router();
|
||||||
var fs = require('fs');
|
var fs = require('fs');
|
||||||
var template_render = require('../lib/render_template.js');
|
var template_render = require('../core/render-template.js');
|
||||||
|
|
||||||
router.get('/', function(req, res, next) {
|
router.get('/', function(req, res, next) {
|
||||||
dhcp_leases = template_render.get_template("dhcp_statistics_page");
|
dhcp_leases = template_render.get_template("dhcp_statistics_page");
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
var express = require('express');
|
var express = require('express');
|
||||||
var router = express.Router();
|
var router = express.Router();
|
||||||
var authorize = require('../lib/authorize.js');
|
var authorize = require('../core/authorize.js');
|
||||||
|
|
||||||
router.post('/', authorize.auth, function(req, res, next) {
|
router.post('/', authorize.auth, function(req, res, next) {
|
||||||
var request = req.body;
|
var request = req.body;
|
||||||
|
@ -5,8 +5,8 @@
|
|||||||
var express = require('express');
|
var express = require('express');
|
||||||
var router = express.Router();
|
var router = express.Router();
|
||||||
var fs = require('fs');
|
var fs = require('fs');
|
||||||
var template_render = require('../lib/render_template.js');
|
var template_render = require('../core/render-template.js');
|
||||||
var authorize = require('../lib/authorize.js');
|
var authorize = require('../core/authorize.js');
|
||||||
|
|
||||||
router.get('/', authorize.auth, function(req, res, next) {
|
router.get('/', authorize.auth, function(req, res, next) {
|
||||||
|
|
||||||
|
@ -5,8 +5,8 @@
|
|||||||
var express = require('express');
|
var express = require('express');
|
||||||
var router = express.Router();
|
var router = express.Router();
|
||||||
var fs = require('fs');
|
var fs = require('fs');
|
||||||
var template_render = require('../lib/render_template.js');
|
var template_render = require('../core/render-template.js');
|
||||||
var authorize = require('../lib/authorize.js');
|
var authorize = require('../core/authorize.js');
|
||||||
|
|
||||||
router.get('/', authorize.auth, function(req, res, next) {
|
router.get('/', authorize.auth, function(req, res, next) {
|
||||||
|
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
var express = require('express');
|
var express = require('express');
|
||||||
var router = express.Router();
|
var router = express.Router();
|
||||||
var authorize = require('../lib/authorize.js');
|
var authorize = require('../core/authorize.js');
|
||||||
|
|
||||||
router.post('/', authorize.auth, function(req, res, next) {
|
router.post('/', authorize.auth, function(req, res, next) {
|
||||||
var request = req.body;
|
var request = req.body;
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
var express = require('express');
|
var express = require('express');
|
||||||
var router = express.Router();
|
var router = express.Router();
|
||||||
var fs = require('fs');
|
var fs = require('fs');
|
||||||
var template_render = require('../lib/render_template.js');
|
var template_render = require('../core/render-template.js');
|
||||||
|
|
||||||
/* GET home page. */
|
/* GET home page. */
|
||||||
router.get('/', function(req, res, next) {
|
router.get('/', function(req, res, next) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user