mirror of
https://github.com/librenms/librenms.git
synced 2024-10-07 16:52:45 +00:00
refactor: OS Discovery cleanup (Part 1) (#4335)
* refactor: OS Discovery cleanup (Part 1) Convert linux.inc.php to use new string functions Create OS discovery tests Use glob instead of readdir in os discovery (could change discovery order) Stop discovering once $os is set * Remove duplicate file header.
This commit is contained in:
committed by
Neil Lathwood
parent
f42406e2b0
commit
f6134f429c
@@ -7,73 +7,50 @@ if (!$os) {
|
|||||||
'.1.3.6.1.4.1.17713.21',
|
'.1.3.6.1.4.1.17713.21',
|
||||||
'.1.3.6.1.4.1.2.3.51.3'
|
'.1.3.6.1.4.1.2.3.51.3'
|
||||||
);
|
);
|
||||||
if (preg_match('/^Linux/', $sysDescr) && !in_array($sysObjectId, $skip_oids)) {
|
if (starts_with($sysDescr, 'Linux') && !in_array($sysObjectId, $skip_oids)) {
|
||||||
$os = 'linux';
|
$os = 'linux';
|
||||||
}
|
|
||||||
|
|
||||||
// Specific Linux-derivatives
|
// Specific Linux-derivatives
|
||||||
if ($os == 'linux') {
|
if (starts_with($sysObjectId, array('.1.3.6.1.4.1.5528.100.20.10.2014', '.1.3.6.1.4.1.5528.100.20.10.2016'))) {
|
||||||
// Check for QNAP Systems TurboNAS
|
|
||||||
$entPhysicalMfgName = snmp_get($device, 'ENTITY-MIB::entPhysicalMfgName.1', '-Osqnv');
|
|
||||||
|
|
||||||
if (str_contains($sysObjectId, '.1.3.6.1.4.1.5528.100.20.10.2014') || str_contains($sysObjectId, '.1.3.6.1.4.1.5528.100.20.10.2016')) {
|
|
||||||
$os = 'netbotz';
|
$os = 'netbotz';
|
||||||
} elseif (str_contains($sysDescr, 'endian')) {
|
} elseif (str_contains($sysDescr, 'endian')) {
|
||||||
$os = 'endian';
|
$os = 'endian';
|
||||||
} elseif (preg_match('/Cisco Small Business/', $sysDescr)) {
|
} elseif (str_contains($sysDescr, 'Cisco Small Business')) {
|
||||||
$os = 'ciscosmblinux';
|
$os = 'ciscosmblinux';
|
||||||
} elseif (strpos($entPhysicalMfgName, 'QNAP') !== false) {
|
} elseif (str_contains(snmp_get($device, 'ENTITY-MIB::entPhysicalMfgName.1', '-Osqnv'), 'QNAP')) {
|
||||||
$os = 'qnap';
|
$os = 'qnap';
|
||||||
} elseif (stristr($sysObjectId, 'packetlogic') || str_contains($sysObjectId, '.1.3.6.1.4.1.15397.2')) {
|
} elseif (starts_with($sysObjectId, '.1.3.6.1.4.1.15397.2')) {
|
||||||
$os = 'procera';
|
$os = 'procera';
|
||||||
} elseif (str_contains($sysObjectId, '.1.3.6.1.4.1.10002.1') || str_contains($sysObjectId, '.1.3.6.1.4.1.41112.1.4') || strpos(trim(snmp_get($device, 'dot11manufacturerName.5', '-Osqnv', 'IEEE802dot11-MIB')), 'Ubiquiti') !== false) {
|
} elseif (starts_with($sysObjectId, array('.1.3.6.1.4.1.10002.1', '.1.3.6.1.4.1.41112.1.4')) || str_contains(snmp_get($device, 'dot11manufacturerName.5', '-Osqnv', 'IEEE802dot11-MIB'), 'Ubiquiti')) {
|
||||||
$os = 'airos';
|
$os = 'airos';
|
||||||
if (strpos(trim(snmp_get($device, 'dot11manufacturerProductName.5', '-Osqnv', 'IEEE802dot11-MIB')), 'UAP') !== false) {
|
if (str_contains(snmp_walk($device, 'dot11manufacturerProductName', '-Osqnv', 'IEEE802dot11-MIB'), 'UAP')) {
|
||||||
$os = 'unifi';
|
$os = 'unifi';
|
||||||
} elseif (strpos(trim(snmp_get($device, 'dot11manufacturerProductName.2', '-Osqnv', 'IEEE802dot11-MIB')), 'UAP') !== false) {
|
} elseif (snmp_get($device, 'fwVersion.1', '-Osqnv', 'UBNT-AirFIBER-MIB') !== false) {
|
||||||
$os = 'unifi';
|
|
||||||
} elseif (strpos(trim(snmp_get($device, 'dot11manufacturerProductName.3', '-Osqnv', 'IEEE802dot11-MIB')), 'UAP') !== false) {
|
|
||||||
$os = 'unifi';
|
|
||||||
} elseif (strpos(trim(snmp_get($device, 'dot11manufacturerProductName.4', '-Osqnv', 'IEEE802dot11-MIB')), 'UAP') !== false) {
|
|
||||||
$os = 'unifi';
|
|
||||||
} elseif (strpos(trim(snmp_get($device, 'dot11manufacturerProductName.6', '-Osqnv', 'IEEE802dot11-MIB')), 'UAP') !== false) {
|
|
||||||
$os = 'unifi';
|
|
||||||
} elseif (trim(snmp_get($device, 'fwVersion.1', '-Osqnv', 'UBNT-AirFIBER-MIB')) != '') {
|
|
||||||
$os = 'airos-af';
|
$os = 'airos-af';
|
||||||
}
|
}
|
||||||
} elseif (snmp_get($device, 'GANDI-MIB::rxCounter.0', '-Osqnv', 'GANDI-MIB') !== false) {
|
} elseif (snmp_get($device, 'GANDI-MIB::rxCounter.0', '-Osqnv', 'GANDI-MIB') !== false) {
|
||||||
$os = 'pktj';
|
$os = 'pktj';
|
||||||
$pktj_mibs = array (
|
$pktj_mibs = array (
|
||||||
"rxCounter" => "GANDI-MIB", // RX Packets
|
"rxCounter" => "GANDI-MIB", // RX Packets
|
||||||
"txCounter" => "GANDI-MIB", // TX Packets
|
"txCounter" => "GANDI-MIB", // TX Packets
|
||||||
"dropCounter" => "GANDI-MIB", // Dropped counters
|
"dropCounter" => "GANDI-MIB", // Dropped counters
|
||||||
"acldropCounter" => "GANDI-MIB", // ACL Dropped counter
|
"acldropCounter" => "GANDI-MIB", // ACL Dropped counter
|
||||||
"ratedropCounter" => "GANDI-MIB", // Rate Dropped counter
|
"ratedropCounter" => "GANDI-MIB", // Rate Dropped counter
|
||||||
"KNIrxCounter" => "GANDI-MIB", // KNI RX counter
|
"KNIrxCounter" => "GANDI-MIB", // KNI RX counter
|
||||||
"KNItxCounter" => "GANDI-MIB", // KNI TX counter
|
"KNItxCounter" => "GANDI-MIB", // KNI TX counter
|
||||||
"KNIdropCounter" => "GANDI-MIB", // KNI DROP counter
|
"KNIdropCounter" => "GANDI-MIB", // KNI DROP counter
|
||||||
);
|
);
|
||||||
register_mibs($device, $pktj_mibs, "include/discovery/os/linux.inc.php");
|
register_mibs($device, $pktj_mibs, "include/discovery/os/linux.inc.php");
|
||||||
} elseif (stristr($sysObjectId, 'cumulusMib') || str_contains($sysObjectId, '.1.3.6.1.4.1.40310')) {
|
} elseif (starts_with($sysObjectId, '.1.3.6.1.4.1.40310')) {
|
||||||
$os = 'cumulus';
|
$os = 'cumulus';
|
||||||
} elseif (str_contains($sysDescr, array('g56fa85e', 'gc80f187', 'g829be90', 'g63c0044', 'gba768e5'))) {
|
} elseif (str_contains($sysDescr, array('g56fa85e', 'gc80f187', 'g829be90', 'g63c0044', 'gba768e5'))) {
|
||||||
$os = 'sophos';
|
$os = 'sophos';
|
||||||
} elseif (snmp_get($device, 'SFA-INFO::systemName.0', '-Osqnv', 'SFA-INFO') !== false) {
|
} elseif (snmp_get($device, 'SFA-INFO::systemName.0', '-Osqnv', 'SFA-INFO') !== false) {
|
||||||
$os = 'ddnos';
|
$os = 'ddnos';
|
||||||
} else {
|
} elseif (str_contains(snmp_get($device, 'HOST-RESOURCES-MIB::hrSystemInitialLoadParameters.0', '-Osqnv'), 'syno_hw_version')) {
|
||||||
// Check for Synology DSM
|
$os = 'dsm'; // Synology DSM
|
||||||
$hrSystemInitialLoadParameters = trim(snmp_get($device, 'HOST-RESOURCES-MIB::hrSystemInitialLoadParameters.0', '-Osqnv'));
|
} elseif (is_numeric(trim(snmp_get($device, 'roomTemp.0', '-OqvU', 'CAREL-ug40cdz-MIB')))) {
|
||||||
|
$os = 'pcoweb'; // Carel PCOweb
|
||||||
if (strpos($hrSystemInitialLoadParameters, 'syno_hw_version') !== false) {
|
|
||||||
$os = 'dsm';
|
|
||||||
} else {
|
|
||||||
// Check for Carel PCOweb
|
|
||||||
$roomTemp = trim(snmp_get($device, 'roomTemp.0', '-OqvU', 'CAREL-ug40cdz-MIB'));
|
|
||||||
|
|
||||||
if (is_numeric($roomTemp)) {
|
|
||||||
$os = 'pcoweb';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -106,20 +106,15 @@ function getHostOS($device)
|
|||||||
|
|
||||||
d_echo("| $sysDescr | $sysObjectId | ");
|
d_echo("| $sysDescr | $sysObjectId | ");
|
||||||
|
|
||||||
$path = $config['install_dir'] . "/includes/discovery/os";
|
$pattern = $config['install_dir'] . '/includes/discovery/os/*.inc.php';
|
||||||
$dir_handle = @opendir($path) or die("Unable to open $path");
|
foreach (glob($pattern) as $file) {
|
||||||
while ($file = readdir($dir_handle)) {
|
include $file;
|
||||||
if (preg_match("/.php$/", $file)) {
|
if (isset($os)) {
|
||||||
include($config['install_dir'] . "/includes/discovery/os/" . $file);
|
return $os;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
closedir($dir_handle);
|
|
||||||
|
|
||||||
if ($os) {
|
return "generic";
|
||||||
return $os;
|
|
||||||
} else {
|
|
||||||
return "generic";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function percent_colour($perc)
|
function percent_colour($perc)
|
||||||
|
174
tests/OSDiscoveryTest.php
Normal file
174
tests/OSDiscoveryTest.php
Normal file
@@ -0,0 +1,174 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* DiscoveryTest.php
|
||||||
|
*
|
||||||
|
* -Description-
|
||||||
|
*
|
||||||
|
* This program 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.
|
||||||
|
*
|
||||||
|
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* @package LibreNMS
|
||||||
|
* @link http://librenms.org
|
||||||
|
* @copyright 2016 Tony Murray
|
||||||
|
* @author Tony Murray <murraytony@gmail.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace LibreNMS\Tests;
|
||||||
|
|
||||||
|
include 'tests/mocks/mock.snmp.inc.php';
|
||||||
|
|
||||||
|
class DiscoveryTest extends \PHPUnit_Framework_TestCase
|
||||||
|
{
|
||||||
|
public function testAiros()
|
||||||
|
{
|
||||||
|
$this->checkOS('airos', 'Linux', '.1.3.6.1.4.1.10002.1');
|
||||||
|
$this->checkOS('airos', 'Linux', '.1.3.6.1.4.1.41112.1.4');
|
||||||
|
|
||||||
|
$mockSnmp = array(
|
||||||
|
'dot11manufacturerName.5' => 'Ubiquiti',
|
||||||
|
);
|
||||||
|
$this->checkOS('airos', 'Linux', '', $mockSnmp);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set up variables and include os discovery
|
||||||
|
*
|
||||||
|
* @param string $expectedOS the OS to test for
|
||||||
|
* @param string $sysDescr set the snmp sysDescr variable
|
||||||
|
* @param string $sysObjectId set the snmp sysObjectId variable
|
||||||
|
* @param array $snmpMock set arbitrary snmp variables with an associative array
|
||||||
|
* @param array $device device array to send
|
||||||
|
*/
|
||||||
|
private function checkOS($expectedOS, $sysDescr = '', $sysObjectId = '', $mockSnmp = array(), $device = array())
|
||||||
|
{
|
||||||
|
global $config;
|
||||||
|
setSnmpMock($mockSnmp);
|
||||||
|
$os = null;
|
||||||
|
|
||||||
|
// cannot use getHostOS() because of functions.php includes
|
||||||
|
$pattern = $config['install_dir'] . '/includes/discovery/os/*.inc.php';
|
||||||
|
foreach (glob($pattern) as $file) {
|
||||||
|
include $file;
|
||||||
|
if (isset($os)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->assertEquals($expectedOS, $os);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testAirosAf()
|
||||||
|
{
|
||||||
|
$mockSnmp = array(
|
||||||
|
'fwVersion.1' => '1.0',
|
||||||
|
);
|
||||||
|
$this->checkOS('airos-af', 'Linux', '.1.3.6.1.4.1.10002.1', $mockSnmp);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testCiscosmblinux()
|
||||||
|
{
|
||||||
|
$this->checkOS('ciscosmblinux', 'Linux Cisco Small Business');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testCumulus()
|
||||||
|
{
|
||||||
|
$this->checkOS('cumulus', 'Linux', '.1.3.6.1.4.1.40310');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testDdnos()
|
||||||
|
{
|
||||||
|
$mockSnmp = array(
|
||||||
|
'SFA-INFO::systemName.0' => 1,
|
||||||
|
);
|
||||||
|
$this->checkOS('ddnos', 'Linux', '', $mockSnmp);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testDsm()
|
||||||
|
{
|
||||||
|
$mockSnmp = array(
|
||||||
|
'HOST-RESOURCES-MIB::hrSystemInitialLoadParameters.0' => 'syno_hw_version',
|
||||||
|
);
|
||||||
|
$this->checkOS('dsm', 'Linux', '', $mockSnmp);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testEndian()
|
||||||
|
{
|
||||||
|
$this->checkOS('endian', 'Linux endian');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testLinux()
|
||||||
|
{
|
||||||
|
$this->checkOS('linux', 'Linux');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testNetbotz()
|
||||||
|
{
|
||||||
|
$this->checkOS('netbotz', 'Linux', '.1.3.6.1.4.1.5528.100.20.10.2014');
|
||||||
|
$this->checkOS('netbotz', 'Linux', '.1.3.6.1.4.1.5528.100.20.10.2016');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testPcoweb()
|
||||||
|
{
|
||||||
|
$mockSnmp = array(
|
||||||
|
'roomTemp.0' => 1,
|
||||||
|
);
|
||||||
|
$this->checkOS('pcoweb', 'Linux', '', $mockSnmp);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testPktj()
|
||||||
|
{
|
||||||
|
$mockSnmp = array(
|
||||||
|
'GANDI-MIB::rxCounter.0' => 1,
|
||||||
|
);
|
||||||
|
$this->checkOS('pktj', 'Linux', '', $mockSnmp);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testProcera()
|
||||||
|
{
|
||||||
|
$this->checkOS('procera', 'Linux', '.1.3.6.1.4.1.15397.2');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testQnap()
|
||||||
|
{
|
||||||
|
$mockSnmp = array(
|
||||||
|
'ENTITY-MIB::entPhysicalMfgName.1' => 'QNAP',
|
||||||
|
);
|
||||||
|
$this->checkOS('qnap', 'Linux', '', $mockSnmp);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testSophos()
|
||||||
|
{
|
||||||
|
$this->checkOS('sophos', 'Linux g56fa85e');
|
||||||
|
$this->checkOS('sophos', 'Linux gc80f187');
|
||||||
|
$this->checkOS('sophos', 'Linux g829be90');
|
||||||
|
$this->checkOS('sophos', 'Linux g63c0044');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testUnifi()
|
||||||
|
{
|
||||||
|
$mockSnmp = array(
|
||||||
|
'dot11manufacturerProductName.6' => 'UAP',
|
||||||
|
);
|
||||||
|
$this->checkOS('unifi', 'Linux', '.1.3.6.1.4.1.10002.1', $mockSnmp);
|
||||||
|
|
||||||
|
$mockSnmp = array(
|
||||||
|
'dot11manufacturerProductName.4' => 'UAP-PRO',
|
||||||
|
);
|
||||||
|
$this->checkOS('unifi', 'Linux', '.1.3.6.1.4.1.10002.1', $mockSnmp);
|
||||||
|
|
||||||
|
$mockSnmp = array(
|
||||||
|
'dot11manufacturerProductName.0' => 'UAP-AC2',
|
||||||
|
);
|
||||||
|
$this->checkOS('unifi', 'Linux', '.1.3.6.1.4.1.10002.1', $mockSnmp);
|
||||||
|
}
|
||||||
|
}
|
@@ -33,3 +33,6 @@ $classLoader->registerDir($install_dir . '/tests', 'LibreNMS\Tests');
|
|||||||
require_once $install_dir . '/includes/common.php';
|
require_once $install_dir . '/includes/common.php';
|
||||||
require_once $install_dir . '/includes/rrdtool.inc.php';
|
require_once $install_dir . '/includes/rrdtool.inc.php';
|
||||||
require_once $install_dir . '/includes/syslog.php';
|
require_once $install_dir . '/includes/syslog.php';
|
||||||
|
|
||||||
|
ini_set('display_errors', 1);
|
||||||
|
ini_set('error_reporting', E_ALL);
|
||||||
|
64
tests/mocks/mock.snmp.inc.php
Normal file
64
tests/mocks/mock.snmp.inc.php
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* mock.snmp.inc.php
|
||||||
|
*
|
||||||
|
* Mock functions from includes/snmp.inc.php to allow tests to run without real snmp
|
||||||
|
*
|
||||||
|
* This program 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.
|
||||||
|
*
|
||||||
|
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* @package LibreNMS
|
||||||
|
* @link http://librenms.org
|
||||||
|
* @copyright 2016 Tony Murray
|
||||||
|
* @author Tony Murray <murraytony@gmail.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
function setSnmpMock($mockSnmpArray)
|
||||||
|
{
|
||||||
|
global $mockSnmp;
|
||||||
|
$mockSnmp = $mockSnmpArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
function snmp_get($device, $oid)
|
||||||
|
{
|
||||||
|
global $mockSnmp;
|
||||||
|
if (isset($mockSnmp) && !empty($mockSnmp)) {
|
||||||
|
if (isset($mockSnmp[$oid])) {
|
||||||
|
return $mockSnmp[$oid];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
function snmp_walk($device, $oid)
|
||||||
|
{
|
||||||
|
global $mockSnmp;
|
||||||
|
$output = '';
|
||||||
|
foreach ($mockSnmp as $key => $value) {
|
||||||
|
if (starts_with($key, $oid)) {
|
||||||
|
$output .= $value . PHP_EOL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (empty($output)) {
|
||||||
|
// does this match the behavior of the real snmp_walk()?
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
return $output;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function register_mibs()
|
||||||
|
{
|
||||||
|
// stub
|
||||||
|
}
|
Reference in New Issue
Block a user