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.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';
|
||||
}
|
||||
|
||||
// Specific Linux-derivatives
|
||||
if ($os == 'linux') {
|
||||
// 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')) {
|
||||
// Specific Linux-derivatives
|
||||
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'))) {
|
||||
$os = 'netbotz';
|
||||
} elseif (str_contains($sysDescr, 'endian')) {
|
||||
$os = 'endian';
|
||||
} elseif (preg_match('/Cisco Small Business/', $sysDescr)) {
|
||||
} elseif (str_contains($sysDescr, 'Cisco Small Business')) {
|
||||
$os = 'ciscosmblinux';
|
||||
} elseif (strpos($entPhysicalMfgName, 'QNAP') !== false) {
|
||||
} elseif (str_contains(snmp_get($device, 'ENTITY-MIB::entPhysicalMfgName.1', '-Osqnv'), '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';
|
||||
} 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';
|
||||
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';
|
||||
} elseif (strpos(trim(snmp_get($device, 'dot11manufacturerProductName.2', '-Osqnv', 'IEEE802dot11-MIB')), 'UAP') !== 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')) != '') {
|
||||
} elseif (snmp_get($device, 'fwVersion.1', '-Osqnv', 'UBNT-AirFIBER-MIB') !== false) {
|
||||
$os = 'airos-af';
|
||||
}
|
||||
} elseif (snmp_get($device, 'GANDI-MIB::rxCounter.0', '-Osqnv', 'GANDI-MIB') !== false) {
|
||||
$os = 'pktj';
|
||||
$pktj_mibs = array (
|
||||
"rxCounter" => "GANDI-MIB", // RX Packets
|
||||
"txCounter" => "GANDI-MIB", // TX Packets
|
||||
"dropCounter" => "GANDI-MIB", // Dropped counters
|
||||
"acldropCounter" => "GANDI-MIB", // ACL Dropped counter
|
||||
"ratedropCounter" => "GANDI-MIB", // Rate Dropped counter
|
||||
"KNIrxCounter" => "GANDI-MIB", // KNI RX counter
|
||||
"KNItxCounter" => "GANDI-MIB", // KNI TX counter
|
||||
"KNIdropCounter" => "GANDI-MIB", // KNI DROP counter
|
||||
"rxCounter" => "GANDI-MIB", // RX Packets
|
||||
"txCounter" => "GANDI-MIB", // TX Packets
|
||||
"dropCounter" => "GANDI-MIB", // Dropped counters
|
||||
"acldropCounter" => "GANDI-MIB", // ACL Dropped counter
|
||||
"ratedropCounter" => "GANDI-MIB", // Rate Dropped counter
|
||||
"KNIrxCounter" => "GANDI-MIB", // KNI RX counter
|
||||
"KNItxCounter" => "GANDI-MIB", // KNI TX counter
|
||||
"KNIdropCounter" => "GANDI-MIB", // KNI DROP counter
|
||||
);
|
||||
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';
|
||||
} elseif (str_contains($sysDescr, array('g56fa85e', 'gc80f187', 'g829be90', 'g63c0044', 'gba768e5'))) {
|
||||
$os = 'sophos';
|
||||
} elseif (snmp_get($device, 'SFA-INFO::systemName.0', '-Osqnv', 'SFA-INFO') !== false) {
|
||||
$os = 'ddnos';
|
||||
} else {
|
||||
// Check for Synology DSM
|
||||
$hrSystemInitialLoadParameters = trim(snmp_get($device, 'HOST-RESOURCES-MIB::hrSystemInitialLoadParameters.0', '-Osqnv'));
|
||||
|
||||
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';
|
||||
}
|
||||
}
|
||||
} elseif (str_contains(snmp_get($device, 'HOST-RESOURCES-MIB::hrSystemInitialLoadParameters.0', '-Osqnv'), 'syno_hw_version')) {
|
||||
$os = 'dsm'; // Synology DSM
|
||||
} elseif (is_numeric(trim(snmp_get($device, 'roomTemp.0', '-OqvU', 'CAREL-ug40cdz-MIB')))) {
|
||||
$os = 'pcoweb'; // Carel PCOweb
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -106,20 +106,15 @@ function getHostOS($device)
|
||||
|
||||
d_echo("| $sysDescr | $sysObjectId | ");
|
||||
|
||||
$path = $config['install_dir'] . "/includes/discovery/os";
|
||||
$dir_handle = @opendir($path) or die("Unable to open $path");
|
||||
while ($file = readdir($dir_handle)) {
|
||||
if (preg_match("/.php$/", $file)) {
|
||||
include($config['install_dir'] . "/includes/discovery/os/" . $file);
|
||||
$pattern = $config['install_dir'] . '/includes/discovery/os/*.inc.php';
|
||||
foreach (glob($pattern) as $file) {
|
||||
include $file;
|
||||
if (isset($os)) {
|
||||
return $os;
|
||||
}
|
||||
}
|
||||
closedir($dir_handle);
|
||||
|
||||
if ($os) {
|
||||
return $os;
|
||||
} else {
|
||||
return "generic";
|
||||
}
|
||||
return "generic";
|
||||
}
|
||||
|
||||
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/rrdtool.inc.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