Split polling & discovery of MIB-based poller

This commit is contained in:
Paul Gear
2015-07-20 14:07:23 +10:00
parent 40a1cef050
commit 7619a340d6
5 changed files with 152 additions and 52 deletions

View File

@@ -836,6 +836,50 @@ function can_ping_device($attribs) {
} }
} // end can_ping_device } // end can_ping_device
/*
* @return true if the requested module type & name is globally enabled
*/
function is_module_enabled($type, $module)
{
global $config;
if (isset($config[$type.'_modules'][$module])) {
return $config[$type.'_modules'][$module] == 1;
}
else {
return false;
}
} // is_module_enabled
/*
* @return true if every string in $arr begins with $str
*/
function begins_with($str, $arr)
{
foreach ($arr as $s) {
$pos = strpos($s, $str);
if ($pos === false || $pos > 0) {
return false;
}
}
return true;
} // begins_with
/*
* @return the longest starting portion of $str that matches everything in $arr
*/
function longest_matching_prefix($str, $arr)
{
$len = strlen($str);
while ($len > 0) {
$prefix = substr($str, 0, $len);
if (begins_with($prefix, $arr)) {
return $prefix;
}
$len -= 1;
}
return '';
} // longest_matching_prefix
/** /**
* Constructs the path to an RRD for the Ceph application * Constructs the path to an RRD for the Ceph application
* @param string $gtype The type of rrd we're looking for * @param string $gtype The type of rrd we're looking for

View File

@@ -16,15 +16,12 @@ if (!$os) {
if (strstr($sysObjectId, '.1.3.6.1.4.1.25053.3.1')) { if (strstr($sysObjectId, '.1.3.6.1.4.1.25053.3.1')) {
$os = 'ruckuswireless'; $os = 'ruckuswireless';
// FIXME: Implement
/*
$ruckus_mibs = array( $ruckus_mibs = array(
"ruckusZDSystemStats" => "RUCKUS-ZD-SYSTEM-MIB", "ruckusZDSystemStats" => "RUCKUS-ZD-SYSTEM-MIB",
"ruckusZDWLANTable" => "RUCKUS-ZD-WLAN-MIB", "ruckusZDWLANTable" => "RUCKUS-ZD-WLAN-MIB",
"ruckusZDWLANAPTable" => "RUCKUS-ZD-WLAN-MIB", "ruckusZDWLANAPTable" => "RUCKUS-ZD-WLAN-MIB",
"ruckusZDWLANAPRadioStatsTable" => "RUCKUS-ZD-WLAN-MIB", "ruckusZDWLANAPRadioStatsTable" => "RUCKUS-ZD-WLAN-MIB",
); );
register_mibs($device, $register_mibs); register_mibs($device, $ruckus_mibs, "includes/discovery/os/ruckuswireless.inc.php");
*/
} }
} }

View File

@@ -12,5 +12,4 @@
* the source code distribution for details. * the source code distribution for details.
*/ */
$devicemib = array($device['sysObjectID'] => 'all'); poll_mibs($device, $graphs);
poll_mibs($devicemib, $device, $graphs);

View File

@@ -43,12 +43,3 @@ $ruckuscountry = first_oid_match($device, $ruckuscountries);
if (isset($ruckuscountry) && $ruckuscountry != '') { if (isset($ruckuscountry) && $ruckuscountry != '') {
$version .= " ($ruckuscountry)"; $version .= " ($ruckuscountry)";
} }
// FIXME: Move this to discovery, and just retrieve the list of MIBs from the database during polling
$ruckus_mibs = array(
'ruckusZDSystemStats' => 'RUCKUS-ZD-SYSTEM-MIB',
'ruckusZDWLANTable' => 'RUCKUS-ZD-WLAN-MIB',
'ruckusZDWLANAPTable' => 'RUCKUS-ZD-WLAN-MIB',
'ruckusZDWLANAPRadioStatsTable' => 'RUCKUS-ZD-WLAN-MIB',
);
poll_mibs($ruckus_mibs, $device, $graphs);

View File

@@ -827,7 +827,6 @@ function snmp_mib_parse($oid, $mib, $module, $mibdir=null) {
// then the name of the object type // then the name of the object type
if ($f[1] && $f[1] == 'OBJECT-TYPE') { if ($f[1] && $f[1] == 'OBJECT-TYPE') {
$result['object_type'] = $f[0]; $result['object_type'] = $f[0];
$result['shortname'] = str_replace($mib, '', $f[0]);
continue; continue;
} }
@@ -948,21 +947,21 @@ function update_db_table($tablename, $columns, $numkeys, $rows)
} }
/* /*
* @return an array containing all of the MIB objects keyed by object-type, * Load the given MIB into the database.
* or an empty array if something goes wrong. * @return count of objects loaded
*/ */
function snmp_mib_load($mib, $module, $mibdir = null) function snmp_mib_load($mib, $module, $included_by, $mibdir = null)
{ {
$mibs = array(); $mibs = array();
// FIXME: Measure whether it's more efficient to use the database
// to cache this rather than parse it via snmptranslate every time.
foreach (snmp_mib_walk($mib, $module, $mibdir) as $obj) { foreach (snmp_mib_walk($mib, $module, $mibdir) as $obj) {
$mibs[$obj['object_type']] = $obj; $mibs[$obj['object_type']] = $obj;
$mibs[$obj['object_type']]['included_by'] = $included_by;
} }
d_print_r($mibs); d_print_r($mibs);
$columns = array('module', 'mib', 'object_type', 'oid', 'syntax', 'description', 'max_access', 'status'); // NOTE: `last_modified` omitted due to being automatically maintained by MySQL
$columns = array('module', 'mib', 'object_type', 'oid', 'syntax', 'description', 'max_access', 'status', 'included_by');
update_db_table('mibdefs', $columns, 3, $mibs); update_db_table('mibdefs', $columns, 3, $mibs);
return $mibs; return count($mibs);
}//end snmp_mib_load() }//end snmp_mib_load()
@@ -1125,53 +1124,123 @@ function save_mibs($device, $mibname, $oids, $mibdef, &$graphs)
}//end save_mibs() }//end save_mibs()
/*
* @return an array of MIB objects matching $module, $name, keyed by object_type
*/
function load_mibdefs($module, $name)
{
$params = array($module, $name);
$result = array();
$object_types = array();
foreach (dbFetchRows("SELECT * FROM `mibdefs` WHERE `module` = ? AND `mib` = ?", $params) as $row) {
$mib = $row['object_type'];
$object_types[] = $mib;
$result[$mib] = $row;
}
// add shortname to each element
$prefix = longest_matching_prefix($name, $object_types);
foreach ($result as $mib => $m) {
$result[$mib]['shortname'] = str_replace($prefix, '', $m['object_type']);
}
d_print_r($result);
return $result;
}
/* /*
* FIXME: Get list of MIBs from the database * @return an array of MIB names and modules for $device from the database
* Poll based on the results.
*/ */
function poll_mibs($list, $device, &$graphs) function load_device_mibs($device)
{ {
// FIXME: check that mib polling module is enabled $params = array($device['device_id']);
$result = array();
foreach (dbFetchRows("SELECT `mib`, `module` FROM device_mibs WHERE device_id = ?", $params) as $row) {
$result[$row['mib']] = $row['module'];
}
return $result;
}
/*
* @return true if this device should be polled with MIB-based discovery
*/
function is_mib_poller_enabled($device)
{
if (!is_module_enabled('poller', 'mib')) {
d_echo("MIB polling module disabled globally.\n");
return false;
}
if (!is_dev_attrib_enabled($device, 'poll_mib')) { if (!is_dev_attrib_enabled($device, 'poll_mib')) {
d_echo('MIB module disabled for '.$device['hostname']."\n"); d_echo('MIB module disabled for '.$device['hostname']."\n");
return false;
}
return true;
}
/*
* Run MIB-based polling for $device. Update $graphs with the results.
*/
function poll_mibs($device, &$graphs)
{
if (!is_mib_poller_enabled($device)) {
return; return;
} }
$mibdefs = array(); echo 'MIB: polling ';
echo 'MIB-based polling:';
d_echo("\n"); d_echo("\n");
foreach ($list as $name => $module) { foreach (load_device_mibs($device) as $name => $module) {
$translated = snmp_translate($name, $module); echo "$name ";
if ($translated) { d_echo("\n");
echo " $module::$name"; $oids = snmpwalk_cache_oid($device, $name, array(), $module, null, "-OQUsb");
d_echo("\n"); d_print_r($oids);
$mod = $translated[0]; save_mibs($device, $name, $oids, load_mibdefs($module, $name), $graphs);
$nam = $translated[1];
$mibdefs[$nam] = snmp_mib_load($nam, $mod);
if (count($mibdefs[$nam] > 0)) {
$oids = snmpwalk_cache_oid($device, $nam, array(), $mod, null, "-OQUsb");
d_print_r($oids);
save_mibs($device, $nam, $oids, $mibdefs[$nam], $graphs);
}
else {
echo("MIB: Could not load definition for $mod::$nam\n");
}
}
else {
d_echo("MIB: no match for $module::$name\n");
}
} }
d_echo('Done MIB-based polling');
echo "\n"; echo "\n";
}//end poll_mibs() }//end poll_mibs()
/* /*
* Take a list of MIB name => module pairs. * Take a list of MIB name => module pairs.
* Validate MIBs and store the device->mib mapping in the database. * Validate MIBs and store the device->mib mapping in the database.
* FIXME: Implement; most of code can be moved in from poll_mibs() above. * See includes/discovery/os/ruckuswireless.inc.php for an example of usage.
*/ */
function register_mibs($device, $mibs) function register_mibs($device, $mibs, $included_by)
{ {
if (!is_mib_poller_enabled($device)) {
return;
}
echo "MIB: registering\n";
foreach ($mibs as $name => $module) {
$translated = snmp_translate($name, $module);
if ($translated) {
$mod = $translated[0];
$nam = $translated[1];
echo " $mod::$nam\n";
if (snmp_mib_load($nam, $mod, $included_by) > 0) {
// NOTE: `last_modified` omitted due to being automatically maintained by MySQL
$columns = array('device_id', 'module', 'mib', 'included_by');
$rows = array();
$rows[] = array(
'device_id' => $device['device_id'],
'module' => $mod,
'mib' => $nam,
'included_by' => $included_by,
);
update_db_table('device_mibs', $columns, 3, $rows);
}
else {
echo("MIB: Could not load definition for $mod::$nam\n");
}
}
else {
echo("MIB: Could not find $module::$name\n");
}
}
echo "\n";
} }