UNPKG

domotz-remote-pawn

Version:

Domotz Agent

172 lines (149 loc) 7.14 kB
/** This file is part of Domotz Agent. * Copyright (C) 2016 Domotz UK LLP * * Domotz Agent is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Domotz Agent 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Domotz Agent. If not, see <http://www.gnu.org/licenses/>. **/ /** * Created by Massimiliano Cuzzoli <massi@domotz.com> on 18/10/16. */ const DISCOVERY_SEMAPHORE = 'SNMP_INTERFACE_SEMAPHORE'; const OIDS_TO_DISCOVER = { '1.3.6.1.2.1.2.2.1.3': 'int', // ifType '1.3.6.1.2.1.31.1.1.1.1': 'string', // ifName '1.3.6.1.2.1.2.2.1.2': 'string', // ifDescription '1.3.6.1.2.1.31.1.1.1.15': 'int', // ifHighSpeed '1.3.6.1.2.1.31.1.1.1.18': 'string', // ifAlias '1.3.6.1.2.1.2.2.1.7': 'int', // ifAdminStatus '1.3.6.1.2.1.2.2.1.8': 'int', // ifOperationalStatus '1.3.6.1.2.1.2.2.1.10': 'int', // ifInOctets '1.3.6.1.2.1.2.2.1.16': 'int', // ifOutOctets '1.3.6.1.2.1.2.2.1.13': 'int', // ifInDiscards '1.3.6.1.2.1.2.2.1.19': 'int', // ifOutDiscards '1.3.6.1.2.1.2.2.1.14': 'int', // ifInErrors '1.3.6.1.2.1.2.2.1.20': 'int' // ifOutErrors }; const DEFAULT_READ_COMMUNITY = 'public'; const SNMP_SUBTREE_TIMEOUT = 20000; var snmpDiscoveryFactory = function (resourceLocator, commandBuilder, responseRendering, snmpSubtreeFactory) { "use strict"; var mutex = resourceLocator.utils.mutex; var q = resourceLocator.q; var engineRequest = resourceLocator.engineRequest; var discoveryUtils = resourceLocator.discovery.utils; var hostInfo = resourceLocator.devices.info; var deviceDetailsByIp = {}; var ipToId = {}; var snmpDiscoverySnapshotData = {}; var deferredSnmpSubtree = function (snmpCommand, host) { var deferred = q.defer(); snmpSubtreeFactory(snmpCommand, resourceLocator).execute( function (result) { console.debug('SNMP Interface Discovery:: Received result for %s -> %s', host, JSON.stringify(result)); result['host'] = host; result['timestamp'] = new Date().toISOString(); deferred.resolve(result); } ); return deferred.promise; }; var lock_discovery = function () { return mutex.lock(DISCOVERY_SEMAPHORE, 1); }; var unlock_discovery = function () { mutex.unlock(DISCOVERY_SEMAPHORE, 1); }; var gatherInterfaceInfoForDevice = function (ipAddress, community) { var snmpCommand = commandBuilder.buildSubtreeCommand(OIDS_TO_DISCOVER, ipAddress, community || DEFAULT_READ_COMMUNITY, SNMP_SUBTREE_TIMEOUT); console.info("SNMP Interface Discovery:: Gathering information for %s", ipAddress); return deferredSnmpSubtree(snmpCommand, ipAddress); }; var renderDiscoveryData = function (rawResultList) { for (var i = 0; i < rawResultList.length; i++) { var dataToRender = rawResultList[i]; var ipAddress = dataToRender.host; console.debug("SNMP Interface Discovery:: Rendering discovery data for %s", dataToRender.host); snmpDiscoverySnapshotData[ipAddress] = responseRendering(dataToRender); } }; var _do_discovery = function (callback, errCallback) { snmpDiscoverySnapshotData = {}; ipToId = discoveryUtils.getDevicesMaps().ipToId; deviceDetailsByIp = discoveryUtils.getDetailsFieldsForDevices(['interface_number_snmp', 'snmp_read_community']); var devicePromises = []; for (var ipAddress in deviceDetailsByIp) { if (deviceDetailsByIp.hasOwnProperty(ipAddress) && deviceDetailsByIp[ipAddress] && deviceDetailsByIp[ipAddress].interface_number_snmp) { devicePromises.push(gatherInterfaceInfoForDevice(ipAddress, deviceDetailsByIp[ipAddress].snmp_read_community)); } } q.all(devicePromises) .then(function (results) { renderDiscoveryData(results); unlock_discovery(); if (callback) callback(snmpDiscoverySnapshotData, ipToId); }) .catch(function (err) { unlock_discovery(); console.error("SNMP Interface Discovery:: Error on snmp information processing", err); if (errCallback) errCallback(err); }); }; var discover = function (callback, errCallback, forceInvalidateList) { if (!lock_discovery()) { console.warn("WARNING: SNMP Interface Discovery already in progress, ignoring the call"); return; } var deviceListGetter = (forceInvalidateList) ? hostInfo.invalidateList : hostInfo.getList; deviceListGetter().then(function (deviceList) { console.info("SNMP Interface Discovery: %d devices present", Object.keys(deviceList).length); return _do_discovery(callback, errCallback); }); }; var sendDiscoveryDataToEngine = function (discoveryData, ipToIdMap) { console.info("SNMP Interface Discovery: records to send %d", Object.keys(discoveryData).length); try { for (var ipAddress in discoveryData) { if (discoveryData.hasOwnProperty(ipAddress) && discoveryData[ipAddress] && discoveryData[ipAddress].oids) { var deviceId = ipToIdMap[ipAddress]; if (!deviceId) { console.info("SNMP Interface Discovery: ID not found for %s", ipAddress); continue; } console.info("SNMP Interface Discovery: Sending data for deviceId=%d", deviceId); engineRequest.sendWithPromise('/device/' + deviceId + '/interface/snmp-info', 'POST', discoveryData[ipAddress]) .catch(function (e) { console.error("Error sending snmp data to Engine: %s", JSON.stringify(e)); }); } } } catch(e) { console.error("Error preparing data to send %s", JSON.stringify(e)); } }; return { discover: discover, sendDiscoveryDataToEngine: sendDiscoveryDataToEngine, isDiscoveryInProgress: function () { return mutex.isLocked(DISCOVERY_SEMAPHORE); }, getCurrentSnapshotData: function () { return snmpDiscoverySnapshotData; } }; }; module.exports.factory = snmpDiscoveryFactory;