Merge pull request #2536 from paulgear/mib-poller-alpha2

MIB-based poller alpha2
This commit is contained in:
Neil Lathwood
2016-01-06 09:08:56 +00:00
42 changed files with 1371 additions and 478 deletions
+216 -36
View File
@@ -580,6 +580,7 @@ function edit_service($service, $descr, $service_ip, $service_param = "", $servi
}
/*
* convenience function - please use this instead of 'if ($debug) { echo ...; }'
*/
@@ -596,7 +597,8 @@ function d_echo($text, $no_debug_text = null) {
elseif ($no_debug_text) {
echo "$no_debug_text";
}
}
} // d_echo
/*
* convenience function - please use this instead of 'if ($debug) { print_r ...; }'
@@ -609,37 +611,8 @@ function d_print_r($var, $no_debug_text = null) {
elseif ($no_debug_text) {
echo "$no_debug_text";
}
}
} // d_print_r
/*
* Shorten the name so it works as an RRD data source name (limited to 19 chars by default).
* Substitute for $subst if necessary.
* @return the shortened name
*/
function name_shorten($name, $common = null, $subst = "mibval", $len = 19) {
if ($common !== null) {
// remove common from the beginning of the string, if present
if (strlen($name) > $len && strpos($name, $common) >= 0) {
$newname = str_replace($common, '', $name);
$name = $newname;
}
}
if (strlen($name) > $len) {
$name = $subst;
}
return $name;
}
/*
* @return the name of the rrd file for $host's $extra component
* @param host Host name
* @param extra Components of RRD filename - will be separated with "-"
*/
function rrd_name($host, $extra, $exten = ".rrd") {
global $config;
$filename = safename(is_array($extra) ? implode("-", $extra) : $extra);
return implode("/", array($config['rrd_dir'], $host, $filename.$exten));
}
/*
* @return true if the given graph type is a dynamic MIB graph
@@ -647,7 +620,8 @@ function rrd_name($host, $extra, $exten = ".rrd") {
function is_mib_graph($type, $subtype) {
global $config;
return $config['graph_types'][$type][$subtype]['section'] == 'mib';
}
} // is_mib_graph
/*
* @return true if client IP address is authorized to access graphs
@@ -670,7 +644,8 @@ function is_client_authorized($clientip) {
}
return false;
}
} // is_client_authorized
/*
* @return an array of all graph subtypes for the given type
@@ -702,7 +677,8 @@ function get_graph_subtypes($type) {
sort($types);
return $types;
}
} // get_graph_subtypes
function get_smokeping_files($device) {
global $config;
@@ -733,6 +709,7 @@ function get_smokeping_files($device) {
return $smokeping_files;
} // end get_smokeping_files
function generate_smokeping_file($device,$file='') {
global $config;
if ($config['smokeping']['integration'] === true) {
@@ -741,7 +718,8 @@ function generate_smokeping_file($device,$file='') {
else {
return $config['smokeping']['dir'] . '/' . $file;
}
}
} // generate_smokeping_file
/*
* @return rounded value to 10th/100th/1000th depending on input (valid: 10, 100, 1000)
@@ -758,6 +736,153 @@ function round_Nth($val = 0, $round_to) {
}
} // end round_Nth
/*
* FIXME: Dummy implementation
*/
function count_mib_mempools($device)
{
if ($device['os'] == 'ruckuswireless') {
return 1;
}
return 0;
} // count_mib_mempools
/*
* FIXME: Dummy implementation
*/
function count_mib_processors($device)
{
if ($device['os'] == 'ruckuswireless') {
return 1;
}
return 0;
} // count_mib_processors
function count_mib_health($device)
{
return count_mib_mempools($device) + count_mib_processors($device);
} // count_mib_health
function get_mibval($device, $oid)
{
$sql = 'SELECT * FROM `device_oids` WHERE `device_id` = ? AND `oid` = ?';
return dbFetchRow($sql, array($device['device_id'], $oid));
} // get_mibval
/*
* FIXME: Dummy implementation - needs an abstraction for each device
*/
function get_mib_mempools($device)
{
$mempools = array();
if ($device['os'] == 'ruckuswireless') {
$mempool = array();
$mibvals = get_mibval($device, '.1.3.6.1.4.1.25053.1.2.1.1.1.15.14.0');
$mempool['mempool_descr'] = $mibvals['object_type'];
$mempool['mempool_id'] = 0;
$mempool['mempool_total'] = 100;
$mempool['mempool_used'] = $mibvals['numvalue'];
$mempool['mempool_free'] = 100 - $mibvals['numvalue'];
$mempool['percentage'] = true;
$mempools[] = $mempool;
}
return $mempools;
} // get_mib_mempools
/*
* FIXME: Dummy implementation - needs an abstraction for each device
*/
function get_mib_processors($device)
{
$processors = array();
if ($device['os'] == 'ruckuswireless') {
$proc = array();
$mibvals = get_mibval($device, '.1.3.6.1.4.1.25053.1.2.1.1.1.15.13.0');
$proc['processor_descr'] = $mibvals['object_type'];
$proc['processor_id'] = 0;
$proc['processor_usage'] = $mibvals['numvalue'];
$processors[] = $proc;
}
return $processors;
} // get_mib_processors
/*
* FIXME: Dummy implementation - needs an abstraction for each device
* @return true if there is a custom graph defined for this type, subtype, and device
*/
function is_custom_graph($type, $subtype, $device)
{
if ($device['os'] == 'ruckuswireless' && $type == 'device') {
switch ($subtype) {
case 'cpumem':
case 'mempool':
case 'processor':
return true;
}
}
return false;
} // is_custom_graph
/*
* FIXME: Dummy implementation
* Set section/graph entries in $graph_enable for graphs specific to $os.
*/
function enable_os_graphs($os, &$graph_enable)
{
/*
foreach (dbFetchRows("SELECT * FROM graph_conditions WHERE graph_type = 'device' AND condition_name = 'os' AND condition_value = ?", array($os)) as $graph) {
$graph_enable[$graph['graph_section']][$graph['graph_subtype']] = "device_".$graph['graph_subtype'];
}
*/
} // enable_os_graphs
/*
* For each os-based or global graph relevant to $device, set its section/graph entry in $graph_enable.
*/
function enable_graphs($device, &$graph_enable)
{
// These are standard graphs we should have for all systems
$graph_enable['poller']['poller_perf'] = 'device_poller_perf';
if (can_ping_device($device) === true) {
$graph_enable['poller']['ping_perf'] = 'device_ping_perf';
}
enable_os_graphs($device['os'], $graph_enable);
} // enable_graphs
//
// maintain a simple cache of objects
//
function object_add_cache($section, $obj)
{
global $object_cache;
$object_cache[$section][$obj] = true;
} // object_add_cache
function object_is_cached($section, $obj)
{
global $object_cache;
if (array_key_exists($obj, $object_cache)) {
return $object_cache[$section][$obj];
}
else {
return false;
}
} // object_is_cached
/**
* Checks if config allows us to ping this device
* $attribs contains an array of all of this devices
@@ -775,6 +900,61 @@ function can_ping_device($attribs) {
}
} // 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
function search_phrase_column($c)
{
global $searchPhrase;
return "$c LIKE '%$searchPhrase%'";
} // search_phrase_column
/**
* Constructs the path to an RRD for the Ceph application
* @param string $gtype The type of rrd we're looking for
@@ -794,7 +974,7 @@ function ceph_rrd($gtype) {
$rrd = join('-', array('app', 'ceph', $vars['id'], $gtype, $var)).'.rrd';
return join('/', array($config['rrd_dir'], $device['hostname'], $rrd));
}
} // ceph_rrd
/**
* Parse location field for coordinates
+11
View File
@@ -315,6 +315,17 @@ $config['graph_colours']['purples'] = array(
);
$config['graph_colours']['default'] = $config['graph_colours']['blues'];
// Colour values from http://www.sapdesignguild.org/goodies/diagram_guidelines/color_palettes.html
$config['graph_colours']['manycolours'] = array(
"FFF8A3", "FAE16B", "F8D753", "F3C01C", "F0B400", // yellows
"A9CC8F", "82B16A", "5C9746", "3D8128", "1E6C0B", // greens
"B2C8D9", "779DBF", "3E75A7", "205F9A", "00488C", // blues
"BEA37A", "907A52", "7A653E", "63522B", "3D3000", // browns
"F3AA79", "EB8953", "E1662A", "DC5313", "D84000", // oranges
"B5B5A9", "8B8D82", "74796F", "5D645A", "434C43", // greys
"E6A4A5", "D6707B", "C4384F", "BC1C39", "B30023", // pinks
);
// Map colors
$config['network_map_legend'] = array(
'0' => '#aeaeae',
+2 -2
View File
@@ -60,12 +60,12 @@ foreach (dbFetchRows($sql, array($deviceid)) as $entry) {
}
// Attempt discovery of each IP only once per run.
if (arp_discovery_is_cached($ip)) {
if (object_is_cached('arp_discovery', $ip)) {
echo '.';
continue;
}
arp_discovery_add_cache($ip);
object_add_cache('arp_discovery', $ip);
$name = gethostbyaddr($ip);
echo '+';
+5 -24
View File
@@ -131,6 +131,11 @@ function discover_device($device, $options=null) {
}
}
if (is_mib_poller_enabled($device)) {
$devicemib = array($device['sysObjectID'] => 'all');
register_mibs($device, $devicemib, "includes/discovery/functions.inc.php");
}
// Set type to a predefined type for the OS if it's not already set
if ($device['type'] == 'unknown' || $device['type'] == '') {
if ($config['os'][$device['os']]['type']) {
@@ -575,7 +580,6 @@ function discover_processor(&$valid, $device, $oid, $index, $type, $descr, $prec
'processor_precision' => $precision,
);
dbUpdate($update_data, 'processors', '`device_id`=? AND `processor_index`=? AND `processor_type`=?', array($device['device_id'], $index, $type));
d_echo($query."\n");
}//end if
$valid[$type][$index] = 1;
}//end if
@@ -630,7 +634,6 @@ function discover_mempool(&$valid, $device, $index, $type, $descr, $precision='1
}
dbUpdate($update_data, 'mempools', 'device_id=? AND mempool_index=? AND mempool_type=?', array($device['device_id'], $index, $type));
d_echo($query."\n");
}//end if
$valid[$type][$index] = 1;
}//end if
@@ -704,25 +707,3 @@ function discover_process_ipv6(&$valid, $ifIndex, $ipv6_address, $ipv6_prefixlen
}//end if
}//end discover_process_ipv6()
// maintain a simple cache of seen IPs during ARP discovery
function arp_discovery_add_cache($ip) {
global $arp_discovery;
$arp_discovery[$ip] = true;
}//end arp_discovery_add_cache()
function arp_discovery_is_cached($ip) {
global $arp_discovery;
if (array_key_exists($ip, $arp_discovery)) {
return $arp_discovery[$ip];
}
else {
return false;
}
}//end arp_discovery_is_cached()
@@ -3,6 +3,8 @@
* LibreNMS Ruckus Wireless OS information module
*
* Copyright (c) 2015 Søren Friis Rosiak <sorenrosiak@gmail.com>
* Copyright (c) 2015 Gear Consulting Pty Ltd <github@libertysys.com.au>
*
* 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
@@ -13,5 +15,13 @@
if (!$os) {
if (strstr($sysObjectId, '.1.3.6.1.4.1.25053.3.1')) {
$os = 'ruckuswireless';
$ruckus_mibs = array(
"ruckusZDSystemStats" => "RUCKUS-ZD-SYSTEM-MIB",
"ruckusZDWLANTable" => "RUCKUS-ZD-WLAN-MIB",
"ruckusZDWLANAPTable" => "RUCKUS-ZD-WLAN-MIB",
"ruckusZDWLANAPRadioStatsTable" => "RUCKUS-ZD-WLAN-MIB",
);
register_mibs($device, $ruckus_mibs, "includes/discovery/os/ruckuswireless.inc.php");
}
}
+7 -2
View File
@@ -14,9 +14,14 @@
// load graph types from the database
foreach (dbFetchRows('select * from graph_types') as $graph) {
// remove leading 'graph_' from column names
foreach ($graph as $k => $v) {
$key = strpos($k, 'graph_') == 0 ? str_replace('graph_', '', $k) : $k;
if (strpos($k, 'graph_') == 0) {
// remove leading 'graph_' from column name
$key = str_replace('graph_', '', $k);
}
else {
$key = $k;
}
$g[$key] = $v;
}
-25
View File
@@ -412,31 +412,6 @@ function poll_mib_def($device, $mib_name_table, $mib_subdir, $mib_oids, $mib_gra
}//end poll_mib_def()
/*
* Please use this instead of creating & updating RRD files manually.
* @param device Device object - only 'hostname' is used at present
* @param name Array of rrdname components
* @param def Array of data definitions
* @param val Array of value definitions
*
*/
function rrd_create_update($device, $name, $def, $val, $step=300) {
global $config;
$rrd = rrd_name($device['hostname'], $name);
if (!is_file($rrd) && $def != null) {
// add the --step and the rra definitions to the array
$newdef = "--step $step ".implode(' ', $def).$config['rrd_rra'];
rrdtool_create($rrd, $newdef);
}
rrdtool_update($rrd, $val);
}//end rrd_create_update()
function get_main_serial($device) {
if ($device['os_group'] == 'cisco') {
$serial_output = snmp_get_multi($device, 'entPhysicalSerialNum.1 entPhysicalSerialNum.1001', '-OQUs', 'ENTITY-MIB:OLD-CISCO-CHASSIS-MIB');
+1 -2
View File
@@ -12,5 +12,4 @@
* the source code distribution for details.
*/
$devicemib = array($device['sysObjectID'] => 'all');
poll_mibs($devicemib, $device, $graphs);
poll_mibs($device, $graphs);
@@ -43,10 +43,3 @@ $ruckuscountry = first_oid_match($device, $ruckuscountries);
if (isset($ruckuscountry) && $ruckuscountry != '') {
$version .= " ($ruckuscountry)";
}
$ruckus_mibs = array(
'ruckusZDSystemStats' => 'RUCKUS-ZD-SYSTEM-MIB',
'ruckusZDWLANTable' => 'RUCKUS-ZD-WLAN-MIB',
'ruckusZDWLANAPTable' => 'RUCKUS-ZD-WLAN-MIB',
);
poll_mibs($ruckus_mibs, $device, $graphs);
+83 -21
View File
@@ -22,7 +22,8 @@
*/
function rrdtool_pipe_open(&$rrd_process, &$rrd_pipes) {
function rrdtool_pipe_open(&$rrd_process, &$rrd_pipes)
{
global $config;
$command = $config['rrdtool'].' -';
@@ -73,7 +74,8 @@ function rrdtool_pipe_open(&$rrd_process, &$rrd_pipes) {
*/
function rrdtool_pipe_close($rrd_process, &$rrd_pipes) {
function rrdtool_pipe_close($rrd_process, &$rrd_pipes)
{
d_echo(stream_get_contents($rrd_pipes[1]));
d_echo(stream_get_contents($rrd_pipes[2]));
@@ -100,7 +102,8 @@ function rrdtool_pipe_close($rrd_process, &$rrd_pipes) {
*/
function rrdtool_graph($graph_file, $options) {
function rrdtool_graph($graph_file, $options)
{
global $config, $debug;
rrdtool_pipe_open($rrd_process, $rrd_pipes);
@@ -163,7 +166,8 @@ function rrdtool_graph($graph_file, $options) {
*/
function rrdtool($command, $filename, $options) {
function rrdtool($command, $filename, $options)
{
global $config, $debug, $rrd_pipes, $console_color;
if ($config['rrdcached'] &&
@@ -209,7 +213,8 @@ function rrdtool($command, $filename, $options) {
*/
function rrdtool_create($filename, $options) {
function rrdtool_create($filename, $options)
{
global $config;
if( $config['rrdcached'] && $config['rrdtool_version'] >= 1.5 ) {
$chk = rrdtool('info', $filename, '');
@@ -230,7 +235,8 @@ function rrdtool_create($filename, $options) {
*/
function rrdtool_update($filename, $options) {
function rrdtool_update($filename, $options)
{
$values = array();
// Do some sanitisation on the data if passed as an array.
@@ -250,26 +256,25 @@ function rrdtool_update($filename, $options) {
else {
return 'Bad options passed to rrdtool_update';
}
}
} // rrdtool_update
function rrdtool_fetch($filename, $options) {
function rrdtool_fetch($filename, $options)
{
return rrdtool('fetch', $filename, $options);
}
} // rrdtool_fetch
function rrdtool_last($filename, $options) {
function rrdtool_last($filename, $options)
{
return rrdtool('last', $filename, $options);
}
} // rrdtool_last
function rrdtool_lastupdate($filename, $options){
function rrdtool_lastupdate($filename, $options)
{
return rrdtool('lastupdate', $filename, $options);
}
} // rrdtool_lastupdate
/**
@@ -280,8 +285,6 @@ function rrdtool_lastupdate($filename, $options){
* @param string string to escape
* @param integer if passed, string will be padded and trimmed to exactly this length (after rrdtool unescapes it)
*/
function rrdtool_escape($string, $maxlength=null){
$result = shorten_interface_type($string);
$result = str_replace("'", '', $result); # remove quotes
@@ -296,8 +299,20 @@ function rrdtool_escape($string, $maxlength=null){
$result = str_replace(':', '\:', $result); # escape colons
return $result.' ';
} // rrdtool_escape
}
/*
* @return the name of the rrd file for $host's $extra component
* @param host Host name
* @param extra Components of RRD filename - will be separated with "-"
*/
function rrd_name($host, $extra, $exten = ".rrd")
{
global $config;
$filename = safename(is_array($extra) ? implode("-", $extra) : $extra);
return implode("/", array($config['rrd_dir'], $host, $filename.$exten));
} // rrd_name
function rrdtool_tune($type, $filename, $max) {
$fields = array();
@@ -314,4 +329,51 @@ function rrdtool_tune($type, $filename, $max) {
$options = "--maximum " . implode(":$max --maximum ", $fields). ":$max";
rrdtool('tune', $filename, $options);
}
}
} // rrdtool_tune
/*
* Please use this instead of creating & updating RRD files manually.
* @param device Device object - only 'hostname' is used at present
* @param name Array of rrdname components
* @param def Array of data definitions
* @param val Array of value definitions
*
*/
function rrd_create_update($device, $name, $def, $val, $step=300)
{
global $config;
$rrd = rrd_name($device['hostname'], $name);
if (!is_file($rrd) && $def != null) {
// add the --step and the rra definitions to the array
$newdef = "--step $step ".implode(' ', $def).$config['rrd_rra'];
rrdtool_create($rrd, $newdef);
}
rrdtool_update($rrd, $val);
} // rrd_create_update
/*
* @return bool indicating existence of RRD file
* @param device Device object as used with rrd_create_update()
* @param name RRD name array as used with rrd_create_update() and rrd_name()
*/
function rrd_file_exists($device, $name)
{
return is_file(rrd_name($device['hostname'], $name));
} // rrd_file_exists
/*
* @return bool indicating rename success or failure
* @param device Device object as used with rrd_create_update()
* @param oldname RRD name array as used with rrd_create_update() and rrd_name()
* @param newname RRD name array as used with rrd_create_update() and rrd_name()
*/
function rrd_file_rename($device, $oldname, $newname)
{
$oldrrd = rrd_name($device['hostname'], $oldname);
$newrrd = rrd_name($device['hostname'], $newname);
return rename($oldrrd, $newrrd);
} // rrd_file_rename
+240 -77
View File
@@ -1,4 +1,19 @@
<?php
/*
* LibreNMS - SNMP Functions
*
* Original Observium code by: Adam Armstrong, Tom Laermans
* Copyright (c) 2010-2012 Adam Armstrong.
*
* Additions for LibreNMS by Paul Gear
* Copyright (c) 2014-2015 Gear Consulting Pty Ltd <http://libertysys.com.au/>
*
* 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. Please see LICENSE.txt at the top level of
* the source code distribution for details.
*/
function string_to_oid($string) {
$oid = strlen($string);
@@ -200,7 +215,7 @@ function snmp_walk($device, $oid, $options=null, $mib=null, $mibdir=null) {
function snmpwalk_cache_cip($device, $oid, $array=array(), $mib=0) {
global $config;
global $config, $debug;
$timeout = prep_snmp_setting($device, 'timeout');
$retries = prep_snmp_setting($device, 'retries');
@@ -236,7 +251,6 @@ function snmpwalk_cache_cip($device, $oid, $array=array(), $mib=0) {
}
$data = trim(external_exec($cmd));
$device_id = $device['device_id'];
// echo("Caching: $oid\n");
foreach (explode("\n", $data) as $entry) {
@@ -272,7 +286,7 @@ function snmpwalk_cache_cip($device, $oid, $array=array(), $mib=0) {
function snmp_cache_ifIndex($device) {
// FIXME: this is not yet using our own snmp_*
global $config;
global $config, $debug;
$timeout = prep_snmp_setting($device, 'timeout');
$retries = prep_snmp_setting($device, 'retries');
@@ -303,7 +317,6 @@ function snmp_cache_ifIndex($device) {
}
$data = trim(external_exec($cmd));
$device_id = $device['device_id'];
$array = array();
foreach (explode("\n", $data) as $entry) {
@@ -433,7 +446,7 @@ function snmpwalk_cache_triple_oid($device, $oid, $array, $mib=null, $mibdir=nul
function snmpwalk_cache_twopart_oid($device, $oid, $array, $mib=0) {
global $config;
global $config, $debug;
$timeout = prep_snmp_setting($device, 'timeout');
$retries = prep_snmp_setting($device, 'retries');
@@ -470,7 +483,6 @@ function snmpwalk_cache_twopart_oid($device, $oid, $array, $mib=0) {
$data = trim(external_exec($cmd));
$device_id = $device['device_id'];
foreach (explode("\n", $data) as $entry) {
list($oid,$value) = explode('=', $entry, 2);
$oid = trim($oid);
@@ -524,7 +536,6 @@ function snmpwalk_cache_threepart_oid($device, $oid, $array, $mib=0) {
$data = trim(external_exec($cmd));
$device_id = $device['device_id'];
foreach (explode("\n", $data) as $entry) {
list($oid,$value) = explode('=', $entry, 2);
$oid = trim($oid);
@@ -547,7 +558,7 @@ function snmpwalk_cache_threepart_oid($device, $oid, $array, $mib=0) {
function snmp_cache_slotport_oid($oid, $device, $array, $mib=0) {
global $config;
global $config, $debug;
$timeout = prep_snmp_setting($device, 'timeout');
$retries = prep_snmp_setting($device, 'retries');
@@ -583,7 +594,6 @@ function snmp_cache_slotport_oid($oid, $device, $array, $mib=0) {
}
$data = trim(external_exec($cmd));
$device_id = $device['device_id'];
foreach (explode("\n", $data) as $entry) {
$entry = str_replace($oid.'.', '', $entry);
@@ -609,7 +619,7 @@ function snmp_cache_oid($oid, $device, $array, $mib=0) {
function snmp_cache_port_oids($oids, $port, $device, $array, $mib=0) {
global $config;
global $config, $debug;
$timeout = prep_snmp_setting($device, 'timeout');
$retries = prep_snmp_setting($device, 'retries');
@@ -680,7 +690,6 @@ function snmp_cache_portIfIndex($device, $array) {
$cmd .= ' '.$device['transport'].':'.$device['hostname'].':'.$device['port'].' portIfIndex';
$output = trim(external_exec($cmd));
$device_id = $device['device_id'];
foreach (explode("\n", $output) as $entry) {
$entry = str_replace('CISCO-STACK-MIB::portIfIndex.', '', $entry);
@@ -717,7 +726,6 @@ function snmp_cache_portName($device, $array) {
$cmd .= ' '.$device['transport'].':'.$device['hostname'].':'.$device['port'].' portName';
$output = trim(external_exec($cmd));
$device_id = $device['device_id'];
// echo("Caching: portName\n");
foreach (explode("\n", $output) as $entry) {
$entry = str_replace('portName.', '', $entry);
@@ -787,7 +795,7 @@ function snmp_gen_auth(&$device) {
/*
* Translate the given MIB into a vaguely useful PHP array. Each keyword becomes an array index.
* Translate the given MIB into a PHP array. Each keyword becomes an array index.
*
* Example:
* snmptranslate -Td -On -M mibs -m RUCKUS-ZD-SYSTEM-MIB RUCKUS-ZD-SYSTEM-MIB::ruckusZDSystemStatsNumSta
@@ -801,11 +809,7 @@ function snmp_gen_auth(&$device) {
* ::= { iso(1) org(3) dod(6) internet(1) private(4) enterprises(1) ruckusRootMIB(25053) ruckusObjects(1) ruckusZD(2) ruckusZDSystemModule(1) ruckusZDSystemMIB(1) ruckusZDSystemObjects(1)
* ruckusZDSystemStats(15) 30 }
*/
function snmp_mib_parse($oid, $mib, $module, $mibdir=null) {
global $debug;
$fulloid = explode('.', $oid);
$lastpart = end($fulloid);
@@ -827,8 +831,6 @@ function snmp_mib_parse($oid, $mib, $module, $mibdir=null) {
// then the name of the object type
if ($f[1] && $f[1] == 'OBJECT-TYPE') {
$result['object_type'] = $f[0];
$result['shortname'] = str_replace($mib, '', $f[0]);
$result['dsname'] = name_shorten($f[0], $mib);
continue;
}
@@ -873,8 +875,7 @@ function snmp_mib_parse($oid, $mib, $module, $mibdir=null) {
else {
return null;
}
}//end snmp_mib_parse()
} // snmp_mib_parse
/*
@@ -891,7 +892,8 @@ function snmp_mib_parse($oid, $mib, $module, $mibdir=null) {
*/
function snmp_mib_walk($mib, $module, $mibdir=null) {
function snmp_mib_walk($mib, $module, $mibdir=null)
{
$cmd = 'snmptranslate -Ts';
$cmd .= mibdir($mibdir);
$cmd .= ' -m '.$module;
@@ -909,24 +911,73 @@ function snmp_mib_walk($mib, $module, $mibdir=null) {
return $result;
}//end snmp_mib_walk()
} // snmp_mib_walk
function quote_column($a)
{
return '`'.$a.'`';
} // quote_column
function join_array($a, $b)
{
return quote_column($a).'='.$b;
} // join_array
/*
* @return an array containing all of the mib objects, keyed by object-type;
* returns an empty array if something goes wrong.
* Update the given table in the database with the given row & column data.
* @param tablename The table to update
* @param columns An array of column names
* @param numkeys The number of columns which are in the primary key of the table; these primary keys must be first in the list of columns
* @param rows Row data to insert, an array of arrays with column names as the second-level keys
*/
function update_db_table($tablename, $columns, $numkeys, $rows)
{
dbBeginTransaction();
foreach ($rows as $nothing => $obj) {
// create a parameter list based on the columns
$params = array();
foreach ($columns as $column) {
$params[] = $obj[$column];
}
$column_placeholders = array_fill(0, count($columns), '?');
// build the "ON DUPLICATE KEY" part
$non_key_columns = array_slice($columns, $numkeys);
$non_key_placeholders = array_slice($column_placeholders, $numkeys);
$update_definitions = array_map("join_array", $non_key_columns, $non_key_placeholders);
$non_key_params = array_slice($params, $numkeys);
function snmp_mib_load($mib, $module, $mibdir=null) {
$sql = 'INSERT INTO `' . $tablename . '` (' .
implode(',', array_map("quote_column", $columns)) .
') VALUES (' . implode(',', $column_placeholders) .
') ON DUPLICATE KEY UPDATE ' . implode(',', $update_definitions);
$result = dbQuery($sql, array_merge($params, $non_key_params));
d_echo("Result: $result\n");
}
dbCommitTransaction();
} // update_db_table
/*
* Load the given MIB into the database.
* @return count of objects loaded
*/
function snmp_mib_load($mib, $module, $included_by, $mibdir = null)
{
$mibs = array();
foreach (snmp_mib_walk($mib, $module, $mibdir) as $obj) {
$mibs[$obj['object_type']] = $obj;
$mibs[$obj['object_type']]['included_by'] = $included_by;
}
d_print_r($mibs);
// 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);
return count($mibs);
return $mibs;
}//end snmp_mib_load()
} // snmp_mib_load
/*
@@ -936,9 +987,8 @@ function snmp_mib_load($mib, $module, $mibdir=null) {
* snmptranslate -m all -M mibs .1.3.6.1.4.1.8072.3.2.10 2>/dev/null
* NET-SNMP-TC::linux
*/
function snmp_translate($oid, $module, $mibdir=null) {
function snmp_translate($oid, $module, $mibdir = null)
{
if ($module !== 'all') {
$oid = "$module::$oid";
}
@@ -966,16 +1016,15 @@ function snmp_translate($oid, $module, $mibdir=null) {
$matches[2],
);
}//end snmp_translate()
} // snmp_translate
/*
* check if the type of the oid is a numeric type, and if so,
* @return the name of RRD type that is best suited to saving it
*/
function oid_rrd_type($oid, $mibdef) {
function oid_rrd_type($oid, $mibdef)
{
if (!isset($mibdef[$oid])) {
return false;
}
@@ -986,8 +1035,16 @@ function oid_rrd_type($oid, $mibdef) {
return false;
case 'TimeTicks':
// Need to find a way to flag that this should be parsed
// return 'COUNTER';
// FIXME
return false;
case 'INTEGER':
case 'Integer32':
// FIXME
return false;
case 'Counter32':
// FIXME
return false;
case 'Counter64':
@@ -999,7 +1056,7 @@ function oid_rrd_type($oid, $mibdef) {
return false;
}//end oid_rrd_type()
} // oid_rrd_type
/*
@@ -1008,9 +1065,8 @@ function oid_rrd_type($oid, $mibdef) {
* Update the database with graph definitions as needed.
* We don't include the index in the graph name - that is handled at display time.
*/
function tag_graphs($mibname, $oids, $mibdef, &$graphs) {
function tag_graphs($mibname, $oids, $mibdef, &$graphs)
{
foreach ($oids as $index => $array) {
foreach ($array as $oid => $val) {
$graphname = $mibname.'-'.$mibdef[$oid]['shortname'];
@@ -1018,15 +1074,14 @@ function tag_graphs($mibname, $oids, $mibdef, &$graphs) {
}
}
}//end tag_graphs()
} // tag_graphs
/*
* Ensure a graph_type definition exists in the database for the entities in this MIB
*/
function update_mib_graph_types($mibname, $oids, $mibdef, $graphs) {
function update_mib_graph_types($mibname, $oids, $mibdef, $graphs)
{
$seengraphs = array();
// Get the list of graphs currently in the database
@@ -1054,35 +1109,57 @@ function update_mib_graph_types($mibname, $oids, $mibdef, $graphs) {
dbInsert($graphdef, 'graph_types');
}
}
}//end foreach
}//end update_mib_graph_types()
}
} // update_mib_graph_types
/*
* Save all of the measurable oids for the device in their own RRDs.
* Save the current value of all the oids in the database.
*/
function save_mibs($device, $mibname, $oids, $mibdef, &$graphs) {
function save_mibs($device, $mibname, $oids, $mibdef, &$graphs)
{
$usedoids = array();
$deviceoids = array();
foreach ($oids as $index => $array) {
foreach ($array as $oid => $val) {
$type = oid_rrd_type($oid, $mibdef);
foreach ($array as $obj => $val) {
// build up the device_oid row for saving into the database
$numvalue = preg_match('/^\d+$/', $val) ? $val : null;
$deviceoids[] = array(
'device_id' => $device['device_id'],
'oid' => $mibdef[$obj]['oid'].".".$index,
'module' => $mibdef[$obj]['module'],
'mib' => $mibdef[$obj]['mib'],
'object_type' => $obj,
'value' => $val,
'numvalue' => $numvalue,
);
$type = oid_rrd_type($obj, $mibdef);
if ($type === false) {
continue;
}
$usedoids[$index][$oid] = $val;
$usedoids[$index][$obj] = $val;
// if there's a file from the previous version of MIB-based polling, rename it
if (rrd_file_exists($device, array($mibname, $mibdef[$obj]['object_type'], $index))
&& !rrd_file_exists($device, array($mibname, $mibdef[$obj]['shortname'], $index))) {
rrd_file_rename($device,
array($mibname, $mibdef[$obj]['object_type'], $index),
array($mibname, $mibdef[$obj]['shortname'], $index));
// Note: polling proceeds regardless of rename result
}
rrd_create_update(
$device,
array(
$mibname,
$mibdef[$oid]['shortname'],
$mibdef[$obj]['shortname'],
$index,
),
array('DS:'.$mibdef[$oid]['dsname'].":$type"),
array($mibdef[$oid]['dsname'] => $val)
array("DS:mibval:$type"),
array("mibval" => $val)
);
}
}
@@ -1090,43 +1167,129 @@ function save_mibs($device, $mibname, $oids, $mibdef, &$graphs) {
tag_graphs($mibname, $usedoids, $mibdef, $graphs);
update_mib_graph_types($mibname, $usedoids, $mibdef, $graphs);
}//end save_mibs()
// update database
$columns = array('device_id', 'oid', 'module', 'mib', 'object_type', 'value', 'numvalue');
update_db_table('device_oids', $columns, 2, $deviceoids);
} // save_mibs
/*
* Take a list of MIB name => module pairs.
* Validate MIBs and poll based on the results.
* @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;
} // load_mibdefs
/*
* @return an array of MIB names and modules for $device from the database
*/
function load_device_mibs($device)
{
$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;
} // load_device_mibs
function poll_mibs($list, $device, &$graphs) {
/*
* @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')) {
d_echo('MIB module disabled for '.$device['hostname']."\n");
return false;
}
return true;
} // is_mib_poller_enabled
/*
* Run MIB-based polling for $device. Update $graphs with the results.
*/
function poll_mibs($device, &$graphs)
{
if (!is_mib_poller_enabled($device)) {
return;
}
$mibdefs = array();
echo 'MIB-based polling:';
echo 'MIB: polling ';
d_echo("\n");
foreach ($list as $name => $module) {
foreach (load_device_mibs($device) as $name => $module) {
echo "$name ";
d_echo("\n");
$oids = snmpwalk_cache_oid($device, $name, array(), $module, null, "-OQUsb");
d_print_r($oids);
save_mibs($device, $name, $oids, load_mibdefs($module, $name), $graphs);
}
echo "\n";
} // poll_mibs
/*
* Take a list of MIB name => module pairs.
* Validate MIBs and store the device->mib mapping in the database.
* See includes/discovery/os/ruckuswireless.inc.php for an example of usage.
*/
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) {
echo " $module::$name";
d_echo("\n");
$mod = $translated[0];
$nam = $translated[1];
$mibdefs[$nam] = snmp_mib_load($nam, $mod);
$oids = snmpwalk_cache_oid($device, $nam, array(), $mod, null, '-OQUsb');
d_print_r($oids);
save_mibs($device, $nam, $oids, $mibdefs[$nam], $graphs);
$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 {
d_echo("MIB: no match for $module::$name\n");
echo("MIB: Could not find $module::$name\n");
}
}
d_echo('Done MIB-based polling');
echo "\n";
}//end poll_mibs()
} // register_mibs