2014-05-12 20:08:19 +02:00
|
|
|
'use strict';
|
|
|
|
|
2018-12-17 22:49:54 +01:00
|
|
|
const _ = require('lodash')
|
|
|
|
const deepExtend = require('deep-extend')
|
|
|
|
|
2020-04-08 01:55:48 +02:00
|
|
|
const Constraints = require('../validation/constraints')
|
2018-12-17 22:49:54 +01:00
|
|
|
const ErrorTypes = require('../utils/errorTypes')
|
|
|
|
const Logger = require('../logger')
|
|
|
|
const MonitoringService = require('../services/monitoringService')
|
|
|
|
const NodeService = require('../services/nodeService')
|
|
|
|
const Strings = require('../utils/strings')
|
|
|
|
const Validator = require('../validation/validator')
|
|
|
|
const Resources = require('../utils/resources')
|
|
|
|
|
|
|
|
const nodeFields = ['hostname', 'key', 'email', 'nickname', 'mac', 'coords', 'monitoring'];
|
|
|
|
|
|
|
|
function getNormalizedNodeData(reqData) {
|
|
|
|
const node = {};
|
|
|
|
_.each(nodeFields, function (field) {
|
|
|
|
let value = Strings.normalizeString(reqData[field]);
|
|
|
|
if (field === 'mac') {
|
|
|
|
value = Strings.normalizeMac(value);
|
|
|
|
}
|
|
|
|
node[field] = value;
|
|
|
|
});
|
|
|
|
return node;
|
|
|
|
}
|
|
|
|
|
|
|
|
const isValidNode = Validator.forConstraints(Constraints.node);
|
|
|
|
const isValidToken = Validator.forConstraint(Constraints.token);
|
2014-05-12 20:08:19 +02:00
|
|
|
|
2018-12-17 22:49:54 +01:00
|
|
|
module.exports = {
|
|
|
|
create: function (req, res) {
|
|
|
|
const data = Resources.getData(req);
|
2014-05-12 20:08:19 +02:00
|
|
|
|
2018-12-17 22:49:54 +01:00
|
|
|
const node = getNormalizedNodeData(data);
|
|
|
|
if (!isValidNode(node)) {
|
|
|
|
return Resources.error(res, {data: 'Invalid node data.', type: ErrorTypes.badRequest});
|
|
|
|
}
|
2014-05-12 20:08:19 +02:00
|
|
|
|
2018-12-17 22:49:54 +01:00
|
|
|
return NodeService.createNode(node, function (err, token, node) {
|
|
|
|
if (err) {
|
|
|
|
return Resources.error(res, err);
|
2014-05-12 20:08:19 +02:00
|
|
|
}
|
2018-12-17 22:49:54 +01:00
|
|
|
return Resources.success(res, {token: token, node: node});
|
|
|
|
});
|
|
|
|
},
|
2014-05-12 20:08:19 +02:00
|
|
|
|
2018-12-17 22:49:54 +01:00
|
|
|
update: function (req, res) {
|
|
|
|
const data = Resources.getData(req);
|
2014-05-12 20:08:19 +02:00
|
|
|
|
2018-12-17 22:49:54 +01:00
|
|
|
const token = Strings.normalizeString(data.token);
|
|
|
|
if (!isValidToken(token)) {
|
|
|
|
return Resources.error(res, {data: 'Invalid token.', type: ErrorTypes.badRequest});
|
|
|
|
}
|
2014-05-12 20:08:19 +02:00
|
|
|
|
2018-12-17 22:49:54 +01:00
|
|
|
const node = getNormalizedNodeData(data);
|
|
|
|
if (!isValidNode(node)) {
|
|
|
|
return Resources.error(res, {data: 'Invalid node data.', type: ErrorTypes.badRequest});
|
|
|
|
}
|
2014-05-12 20:08:19 +02:00
|
|
|
|
2018-12-17 22:49:54 +01:00
|
|
|
return NodeService.updateNode(token, node, function (err, token, node) {
|
|
|
|
if (err) {
|
|
|
|
return Resources.error(res, err);
|
2014-05-12 20:08:19 +02:00
|
|
|
}
|
2018-12-17 22:49:54 +01:00
|
|
|
return Resources.success(res, {token: token, node: node});
|
|
|
|
});
|
|
|
|
},
|
2014-05-12 20:08:19 +02:00
|
|
|
|
2018-12-17 22:49:54 +01:00
|
|
|
delete: function (req, res) {
|
|
|
|
const data = Resources.getData(req);
|
2014-05-12 20:08:19 +02:00
|
|
|
|
2018-12-17 22:49:54 +01:00
|
|
|
const token = Strings.normalizeString(data.token);
|
|
|
|
if (!isValidToken(token)) {
|
|
|
|
return Resources.error(res, {data: 'Invalid token.', type: ErrorTypes.badRequest});
|
|
|
|
}
|
2016-05-16 18:27:03 +02:00
|
|
|
|
2018-12-17 22:49:54 +01:00
|
|
|
return NodeService.deleteNode(token, function (err) {
|
|
|
|
if (err) {
|
|
|
|
return Resources.error(res, err);
|
2016-05-16 18:27:03 +02:00
|
|
|
}
|
2018-12-17 22:49:54 +01:00
|
|
|
return Resources.success(res, {});
|
|
|
|
});
|
|
|
|
},
|
2016-05-16 18:27:03 +02:00
|
|
|
|
2018-12-17 22:49:54 +01:00
|
|
|
get: function (req, res) {
|
|
|
|
const token = Strings.normalizeString(Resources.getData(req).token);
|
|
|
|
if (!isValidToken(token)) {
|
|
|
|
return Resources.error(res, {data: 'Invalid token.', type: ErrorTypes.badRequest});
|
|
|
|
}
|
2016-05-16 18:27:03 +02:00
|
|
|
|
2018-12-17 22:49:54 +01:00
|
|
|
return NodeService.getNodeDataByToken(token, function (err, node) {
|
|
|
|
if (err) {
|
|
|
|
return Resources.error(res, err);
|
2014-05-12 20:08:19 +02:00
|
|
|
}
|
2018-12-17 22:49:54 +01:00
|
|
|
return Resources.success(res, node);
|
|
|
|
});
|
|
|
|
},
|
2014-05-12 20:08:19 +02:00
|
|
|
|
2018-12-17 22:49:54 +01:00
|
|
|
getAll: function (req, res) {
|
|
|
|
Resources.getValidRestParams('list', 'node', req, function (err, restParams) {
|
|
|
|
if (err) {
|
|
|
|
return Resources.error(res, err);
|
|
|
|
}
|
2016-06-07 00:21:26 +02:00
|
|
|
|
2018-12-17 22:49:54 +01:00
|
|
|
return NodeService.getAllNodes(function (err, nodes) {
|
2016-06-07 00:21:26 +02:00
|
|
|
if (err) {
|
|
|
|
return Resources.error(res, err);
|
|
|
|
}
|
|
|
|
|
2018-12-17 22:49:54 +01:00
|
|
|
const realNodes = _.filter(nodes, function (node) {
|
|
|
|
// We ignore nodes without tokens as those are only manually added ones like gateways.
|
|
|
|
return node.token;
|
|
|
|
});
|
2016-06-07 10:50:15 +02:00
|
|
|
|
2018-12-17 22:49:54 +01:00
|
|
|
const macs = _.map(realNodes, function (node) {
|
|
|
|
return node.mac;
|
|
|
|
});
|
2016-06-22 00:06:32 +02:00
|
|
|
|
2018-12-17 22:49:54 +01:00
|
|
|
MonitoringService.getByMacs(macs, function (err, nodeStateByMac) {
|
|
|
|
if (err) {
|
|
|
|
Logger.tag('nodes', 'admin').error('Error getting nodes by MACs:', err);
|
|
|
|
return Resources.error(res, {data: 'Internal error.', type: ErrorTypes.internalError});
|
|
|
|
}
|
2016-06-26 19:09:12 +02:00
|
|
|
|
2018-12-17 22:49:54 +01:00
|
|
|
const enhancedNodes = _.map(realNodes, function (node) {
|
|
|
|
const nodeState = nodeStateByMac[node.mac];
|
|
|
|
if (nodeState) {
|
|
|
|
return deepExtend({}, node, {
|
|
|
|
site: nodeState.site,
|
|
|
|
domain: nodeState.domain,
|
|
|
|
onlineState: nodeState.state
|
|
|
|
});
|
2016-06-26 19:09:12 +02:00
|
|
|
}
|
|
|
|
|
2018-12-17 22:49:54 +01:00
|
|
|
return node;
|
2016-06-26 19:09:12 +02:00
|
|
|
});
|
2018-12-17 22:49:54 +01:00
|
|
|
|
|
|
|
const filteredNodes = Resources.filter(
|
|
|
|
enhancedNodes,
|
|
|
|
[
|
|
|
|
'hostname',
|
|
|
|
'nickname',
|
|
|
|
'email',
|
|
|
|
'token',
|
|
|
|
'mac',
|
|
|
|
'site',
|
|
|
|
'domain',
|
|
|
|
'key',
|
|
|
|
'onlineState'
|
|
|
|
],
|
|
|
|
restParams
|
|
|
|
);
|
|
|
|
const total = filteredNodes.length;
|
|
|
|
|
|
|
|
const sortedNodes = Resources.sort(
|
|
|
|
filteredNodes,
|
|
|
|
[
|
|
|
|
'hostname',
|
|
|
|
'nickname',
|
|
|
|
'email',
|
|
|
|
'token',
|
|
|
|
'mac',
|
|
|
|
'key',
|
|
|
|
'site',
|
|
|
|
'domain',
|
|
|
|
'coords',
|
|
|
|
'onlineState',
|
|
|
|
'monitoringState'
|
|
|
|
],
|
|
|
|
restParams
|
|
|
|
);
|
|
|
|
const pageNodes = Resources.getPageEntities(sortedNodes, restParams);
|
|
|
|
|
|
|
|
res.set('X-Total-Count', total);
|
|
|
|
return Resources.success(res, pageNodes);
|
2016-06-07 10:50:15 +02:00
|
|
|
});
|
2016-06-07 00:21:26 +02:00
|
|
|
});
|
2018-12-17 22:49:54 +01:00
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|