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
+20
View File
@@ -0,0 +1,20 @@
#!/bin/sh
# Script to convert RRDs from the experimental first release of MIB-based polling.
set -e
set -u
for i; do
base=${i%%.rrd}
if [ -e $i.old ]; then
continue
fi
mv $i $i.old
echo "Processing $i"
rrdtool dump $i.old | sed -e 's|<name>.*</name>|<name>mibval</name>|' > $base.xml
rrdtool restore $base.xml $i
rm -f $base.xml
done
exit 0
+1
View File
@@ -5,6 +5,7 @@ find . \
-path ./html/includes/geshi -prune -o \
-path ./html/includes/jpgraph -prune -o \
-path ./html/js/jqplot -prune -o \
-path ./lib -prune -o \
-path ./junk -prune -o \
-path ./logs -prune -o \
-path ./mibs -prune -o \
+159
View File
@@ -0,0 +1,159 @@
## WARNING ##
MIB-based polling is experimental. It might overload your LibreNMS server,
destroy your data, set your routers on fire, and kick your cat. It has been
tested against a very limited set of devices (namely Ruckus ZD1000 wireless
controllers, and `net-snmp` on Linux). It may fail badly on other hardware.
The approach taken is fairly simplistic and I claim no special expertise in
understanding MIBs. Most of my knowledge of SNMP comes from reading net-snmp
man pages, and reverse engineering the output of snmptranslate and snmpwalk
and trying to make devices work with LibreNMS. I may have made false
assumptions and probably use wrong terminology in many places. Feel free to
offer corrections/suggestions via pull requests or email.
Paul Gear <paul@librenms.org>
## Overview ##
This is the 2nd experimental release of MIB polling. If you used the 1st
release, you MUST perform a data conversion of the MIB-based polling files
using the script `contrib/convert-mib-graphs.sh`. Failure to do so will
result in your data collection silently stopping.
MIB-based polling is disabled by default; you must set
`$config['poller_modules']['mib'] = 1;`
in `config.php` to enable it.
## Preparation ##
MIB-based polling results in the creation of a separate RRD file for each
device-MIB-OID-index combination encountered by LibreNMS. Thus it can cause
your disk space requirements to grow enormously and rapidly. As an example,
enabling MIB-based polling on my test Ruckus ZD1000 wireless controller with
one (1) AP and one (1) user on that AP resulted in a 5 MB increase in RRD
space usage for that device. Each RRD file is around 125 KB in size (on
x64-64 systems) and is pre-allocated, so after the first discovery and poller
run of each devicewith MIB-based polling enabled, disk space should be stable.
However, monitoring disk usage is your responsibility. (The good news: you
can do this with LibreNMS. :-)
Unless you are running LibreNMS on a powerful system with pure SSD for RRD
storage, it is strongly recommended that you enable rrdcached and ensure it is
working *before* enabling MIB-based polling.
## Components ##
The components involved in MIB-based polling are:
### Discovery ###
- OS discovery determines whether there are MIBs which should be polled. If
so, they are registered in the `device_mibs` association table as relevant
to that device. MIB associations for each device can be viewed at:
http://your.librenms.server/device/device=XXXX/tab=mib/
All MIBs used by MIB-based polling may be viewed at:
http://your.librenms.server/mibs/
All device associations created by MIB-based polling may be viewed at:
http://your.librenms.server/mib_assoc/ (Devices -> MIB associations)
- In addition, all devices are checked for a MIB matching their sysObjectID.
If there is a matching MIB available, it is automatically included.
The sysObjectID for each device is now displayed on the overview page:
http://your.librenms.server/device/device=XXXX/
- Note that the above means that no MIB-based polling will occur until the
devices in question are rediscovered. If you want to begin MIB-based
polling immediately, you must force rediscovery from the web UI, or run it
from the CLI using `./discovery.php -h HOSTNAME`
- During discovery, relevant MIBs are parsed using `snmptranslate`, and the
data returned is used to populate a database which guides the poller in
what to store. At the moment, only OIDs with Unsigned32 and Counter64
data types are parsed.
- Devices may be excluded from MIB polling by changing the setting in the
device edit screen:
http://your.librenms.server/device/device=XXXX/tab=edit/section=modules/
### Polling ###
- During polling the MIB associations for the device are looked up, and the
MIB is polled for current values. You can see the values which LibreNMS
has retrieved from the MIB poller in the "Device MIB values" section of
http://your.librenms.server/device/device=XXXX/tab=mib/
- Data from the latest poll is saved in the table `device_oids`, and RRD
files are saved in the relevant device directory as
mibName-oidName-index.rrd
### Graphing ###
- For each graph type defined in the database, a graph will appear in:
http://your.librenms.server/device/device=XXXX/tab=graphs/group=mib/
- MIB graphs are generated generically by
`html/includes/graphs/device/mib.inc.php`
There is presently no customisation of graphs available.
- If there is only one index under a given OID, it is displayed as a normal
line graph; if there multiple OIDs, they are displayed as a stacked graph.
At the moment, all indices are placed in the same graph. This is
non-optimal for, e.g., wifi controllers with hundreds of APs attached.
### Alerting ###
There is no specific support for alerting in the MIB-based polling engine, but
the data it collects may be used in alerts. Here's an example of an alert
which detects when a Ruckus wireless controller reports meshing disabled on an
access point:
http://libertysys.com.au/imagebin/3btw98DR.png
## Adding/testing other device types ##
One of the goals of this work is to help take out the heavy lifting of adding
new device types. Even if you want fully-customised graphs or tables, you can
still use the MIB-based poller to make it easy to gather the data you want to
graph.
### How to add a new device MIB ###
1. Ensure the manufacturer's MIB is present in the mibs directory. If you
plan to submit your work to LibreNMS, make sure you attribute the source
of the MIB, including the exact download URL if possible, or explicit
instructions about how to obtain it.
2. Check that `snmptranslate -Ts -M mibs -m MODULE | grep mibName` produces
a named list of OIDs. See the comments on `snmp_mib_walk()` in
`includes/snmp.inc.php` for an example.
3. Check that `snmptranslate -Td -On -M mibs -m MODULE MODULE::mibName`
produces a parsed description of the OID values. An example can be
found in the comments for `snmp_mib_parse()` in `includes/snmp.inc.php`.
4. Get the `sysObjectID` from a device, for example:
```snmpget -v2c -c public -OUsb -m SNMPv2-MIB -M /opt/librenms/mibs -t 30 hostname sysObjectID.0```
5. Ensure `snmptranslate -m all -M /opt/librenms/mibs OID 2>/dev/null`
(where OID is the value returned for sysObjectID above) results in a
valid name for the MIB. See the comments for `snmp_translate()` in
`includes/snmp.inc.php` for an example. If this step fails, it means
there is something wrong with the MIB and `net-snmp` cannot parse it.
6. Add any additional MIBs you wish to poll for specific device types to
`includes/discovery/os/OSNAME.inc.php` by calling `poll_mibs()` with the
MIB module and name. See `includes/discovery/os/ruckuswireless.inc.php`
for an example.
7. That should be all you need to see MIB graphs!
8. If you want to develop more customised support for a particular OS, you
can follow the above process, then use the resultant data collected by
LibreNMS in the RRD files or the database tables `device_oids`
## TODO ##
What's not included in MIB-based polling at present? These may be present in
future versions. Pull requests gratefully accepted!
- Parse and save integer and timetick data types.
- Filter MIBs/OIDs from being polled and/or saved.
- Move graphs from the MIB section to elsewhere. e.g. If a device uses a
unique MIB for CPU utilisation, we should display it under the relevant
health tab.
- Combine multiple MIB values into graphs automatically on a predefined or
user-defined basis.
- Include MIB types in stats submissions.
-100
View File
@@ -1,100 +0,0 @@
## WARNING ##
MIB-based polling is experimental. It might overload your LibreNMS server,
destroy your data, set your routers on fire, and kick your cat. It has been
tested against a very limited set of devices (namely Ruckus ZD1000 wireless
controllers, and `net-snmp` on Linux). It may fail badly on other hardware.
The approach taken is fairly basic and I claim no special expertise in
understanding MIBs. Most of my understanding of SNMP comes from reading
net-snmp man pages, and reverse engineering the output of snmptranslate and
snmpwalk and trying to make devices work with LibreNMS. I may have made
false assumptions and probably use wrong terminology in many places. Feel
free to offer corrections/suggestions via pull requests or email.
Paul Gear <paul@librenms.org>
## Overview ##
MIB-based polling is disabled by default; you must set
`$config['poller_modules']['mib'] = 1;`
in `config.php` to enable it.
The components involved in of MIB-based support are:
### Discovery ###
- MIB-based detection is not involved; any work done here would have to be
duplicated by the poller and thus would only increase load.
### Polling ###
- The file `includes/snmp.inc.php` now contains code which can parse MIBs
using `snmptranslate` and use the data returned to populate an array
which guides the poller in what to store. At the moment, only OIDs with
Unsigned32 and Counter64 data types are parsed.
- `includes/polling/mib.inc.php` looks for a MIB matching sysObjectID in
the MIB directory; if one is found, it:
- parses it
- walks that MIB on the device
- stores any numeric results in individual RRD files
- updates/adds graph definitions in the previously-unused graph_types
database table
- Individual OSes (`includes/polling/os/*.inc.php`) can poll extra MIBs
for a given OS by calling `poll_mib()`. At the moment, this actually
happens before the general MIB polling.
- Devices may be excluded from MIB polling by changing the setting in the
device edit screen (`/device/device=ID/tab=edit/section=modules/`)
### Graphing ###
- For each graph type defined in the database, a graph will appear in:
Device -> Graphs -> MIB
- MIB graphs are generated generically by
`html/includes/graphs/device/mib.inc.php`
- At the moment, all units are placed in the same graph. This is probably
non-optimal for, e.g., wifi controllers with hundreds of APs attached.
## Adding/testing other device types ##
One of the goals of this work is to help take out the heavy lifting of
adding new device types. Even if you want fully customised graphs or
tables, you can use the automatic collection of MIBs to make it easy to
gather the data you want.
### How to add a new device MIB ###
1. Ensure the manufacturer's MIB is present in the mibs directory. If you
plan to submit your work to LibreNMS, make sure you attribute the source
of the MIB, including the exact download URL.
2. Check that `snmptranslate -Ts -M mibs -m MODULE | grep mibName` produces
a named list of OIDs. See the comments for `snmp_mib_walk()` in
`includes/snmp.inc.php` for an example.
3. Check that `snmptranslate -Td -On -M mibs -m MODULE MODULE::mibName`
produces a parsed description of the OID values. An example can be
found in the comments for `snmp_mib_parse()` in `includes/snmp.inc.php`.
4. Get the `sysObjectID` from a device, for example:
```snmpget -v2c -c public -OUsb -m SNMPv2-MIB -M /opt/librenms/mibs -t 30 hostname sysObjectID.0```
5. Ensure `snmptranslate -m all -M /opt/librenms/mibs OID 2>/dev/null`
(where OID is the value returned for sysObjectID above) results in a
valid name for the MIB. See the comments for `snmp_translate()` in
`includes/snmp.inc.php` for an example. If this step fails, it means
there is something wrong with the MIB and `net-snmp` cannot parse it.
6. Add any additional MIBs you wish to poll for specific device types to
`includes/polling/os/OSNAME.inc.php` by calling `poll_mibs()` with the
MIB module and name. See `includes/polling/os/ruckuswireless.inc.php` for
an example.
7. That should be all you need to see MIB graphs!
## TODO ##
- Save the most recent MIB data in the database (including string types
which cannot be graphed). Display it in the appropriate places.
- Parse and save integer and timetick data types.
- Filter MIBs/OIDs from being polled and/or saved.
- Move graphs from the MIB section to elsewhere. e.g. There is already
specific support for wireless APs - this should be utilised, but isn't
yet.
- Combine multiple MIB values into graphs automatically on a predefined or
user-defined basis.
- Include MIB types in stats submissions.
-20
View File
@@ -1,20 +0,0 @@
- Device support:
- Ruckus wireless controllers
- Investigate generic device support based on MIBs. It should be
possible to do basic graphs based just on the MIB. They would
obviously not be as customised as the specifically supported devices
but should still be useful to users.
- Functionality/performance improvements:
- Investigate solutions for poller performance improvement.
- Investigate solutions for multiple communities per device.
- Eliminate interface churn for transient interfaces (e.g. ppp/tun) on
net-snmp.
- Consider adding some non-monitoring administrative functions:
- enabling/disabling ports
- changing access port VLANs
- editing port labels
- Integrate as many usability improvements as time permits:
- Front page: more automation; GUI configuration
+7
View File
@@ -49,6 +49,13 @@ if ($device['serial']) {
</tr>';
}
if ($device['sysObjectID']) {
echo '<tr>
<td>Object ID</td>
<td>'.$device['sysObjectID'].'</td>
</tr>';
}
if ($device['sysContact']) {
echo '<tr>
<td>Contact</td>';
+43
View File
@@ -0,0 +1,43 @@
<?php
/*
* LibreNMS custom graphing
*
* Author: Paul Gear
* Copyright (c) 2015 Gear Consulting Pty Ltd <[email protected]>
*
* 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.
*/
// FIXME: Dummy implementation which only supports ruckuswireless processor & mempool
$i = 0;
$rrd_list = array();
if ($subtype == 'processor') {
$rrd_list[0] = array(
'area' => 1,
'ds' => 'mibval',
'descr' => 'CPU Utilization',
'filename' => rrd_name($device['hostname'], array('ruckusZDSystemStats-CPUUtil-0')),
);
}
if ($subtype == 'mempool') {
$rrd_list[0] = array(
'area' => 1,
'ds' => 'mibval',
'descr' => 'Memory Utilization',
'filename' => rrd_name($device['hostname'], array('ruckusZDSystemStats-MemoryUtil-0')),
);
}
$units = '%%';
$colours = 'mixed';
$scale_min = '0';
$scale_max = '100';
$nototal = 1;
require_once 'includes/graphs/generic_multi_line.inc.php';
+20 -10
View File
@@ -13,25 +13,35 @@
*/
$rrd_list = array();
$prefix = rrd_name($device['hostname'], array($subtype, ''), '');
foreach (glob($prefix.'*.rrd') as $filename) {
$prefix = rrd_name($device['hostname'], array($subtype, ''), '');
$filenames = glob($prefix."*.rrd");
$count = count($filenames);
foreach ($filenames as $filename) {
// find out what * expanded to
$globpart = str_replace($prefix, '', $filename);
// take off the prefix
$instance = substr($globpart, 0, -4);
// take off ".rrd"
$globpart = str_replace($prefix, '', $filename); // take off the prefix
$instance = substr($globpart, 0, -4); // take off ".rrd"
$ds = array();
$mibparts = explode('-', $subtype);
$mibvar = end($mibparts);
$ds['ds'] = name_shorten($mibvar);
$ds['ds'] = 'mibval';
$ds['descr'] = "$mibvar-$instance";
$ds['filename'] = $filename;
$rrd_list[] = $ds;
}
$colours = 'mixed';
$scale_min = '0';
$nototal = 0;
$simple_rrd = true;
require 'includes/graphs/generic_multi_line.inc.php';
// If there are multiple matching files, use a stacked graph instead of a line graph
if ($count > 1) {
$nototal = 1;
$divider = $count;
$text_orig = 1;
$colours = 'manycolours';
include "includes/graphs/generic_multi_simplex_seperated.inc.php";
}
else {
$colours = 'mixed';
$nototal = 0;
include "includes/graphs/generic_multi_line.inc.php";
}
@@ -18,7 +18,7 @@ foreach ($procs as $proc) {
$unit_text = 'Load %';
$units = '%';
$units = '';
$total_units = '%';
$colours = 'mixed';
@@ -36,6 +36,9 @@ foreach ($rrd_list as $rrd) {
}
$colour = $config['graph_colours'][$colours][$iter];
if (!empty($rrd['area']) && empty($rrd['areacolour'])) {
$rrd['areacolour'] = $colour."20";
}
$ds = $rrd['ds'];
$filename = $rrd['filename'];
@@ -69,8 +72,8 @@ foreach ($rrd_list as $rrd) {
}
}
$rrd_optionsb .= ' GPRINT:'.$id.':LAST:%5.2lf%s GPRINT:'.$id.'min:MIN:%5.2lf%s';
$rrd_optionsb .= ' GPRINT:'.$id.'max:MAX:%5.2lf%s GPRINT:'.$id.":AVERAGE:'%5.2lf%s\\n'";
$rrd_optionsb .= ' GPRINT:'.$id.':LAST:%5.2lf%s'.$units.' GPRINT:'.$id.'min:MIN:%5.2lf%s'.$units;
$rrd_optionsb .= ' GPRINT:'.$id.'max:MAX:%5.2lf%s'.$units.' GPRINT:'.$id.":AVERAGE:'%5.2lf%s$units\\n'";
$i++;
$iter++;
+5 -2
View File
@@ -43,12 +43,15 @@ if ($auth !== true && $auth != 1) {
require $config['install_dir']."/html/includes/graphs/$type/auth.inc.php";
if ($auth === true && is_file($config['install_dir']."/html/includes/graphs/$type/$subtype.inc.php")) {
include $config['install_dir']."/html/includes/graphs/$type/$subtype.inc.php";
if ($auth === true && is_custom_graph($type, $subtype, $device)) {
include($config['install_dir'] . "/html/includes/graphs/custom.inc.php");
}
else if ($auth === true && is_mib_graph($type, $subtype)) {
include $config['install_dir']."/html/includes/graphs/$type/mib.inc.php";
}
elseif ($auth === true && is_file($config['install_dir']."/html/includes/graphs/$type/$subtype.inc.php")) {
include $config['install_dir']."/html/includes/graphs/$type/$subtype.inc.php";
}
else {
graph_error("$type*$subtype ");
// Graph Template Missing");
+4
View File
@@ -110,6 +110,8 @@ if ( dbFetchCell("SELECT 1 from `packages` LIMIT 1") ) {
<li><a href="<?php echo(generate_url(array('page'=>'search','search'=>'ipv6'))); ?>"><i class="fa fa-search fa-fw fa-lg"></i> IPv6 Search</a></li>
<li><a href="<?php echo(generate_url(array('page'=>'search','search'=>'mac'))); ?>"><i class="fa fa-search fa-fw fa-lg"></i> MAC Search</a></li>
<li><a href="<?php echo(generate_url(array('page'=>'search','search'=>'arp'))); ?>"><i class="fa fa-search fa-fw fa-lg"></i> ARP Tables</a></li>
<li role="presentation" class="divider"></li>
<li><a href="<?php echo(generate_url(array('page'=>'mibs'))); ?>"><i class="fa fa-file-text-o fa-fw fa-lg"></i> MIB definitions</a></li>
</ul>
</li>
<li class="dropdown">
@@ -167,6 +169,8 @@ if ($_SESSION['userlevel'] >= '10') {
}
echo '
<li role="presentation" class="divider"></li>
<li><a href='.generate_url(array('page'=>'mib_assoc')).'><i class="fa fa-file-text-o fa-fw fa-lg"></i> MIB associations</a></li>
<li role="presentation" class="divider"></li>
';
if ($config['navbar']['manage_groups']['hide'] === 0) {
+96
View File
@@ -0,0 +1,96 @@
<?php
/*
* LibreNMS device MIB association browser
*
* Copyright (c) 2015 Gear Consulting Pty Ltd <github@libertysys.com.au>
*
* by Paul Gear
* based on code by Søren Friis Rosiak <sorenrosiak@gmail.com>
* in commit 054bf3ae209f34a2c3bc8968300722004903df1b
*
* 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.
*/
$columns = array(
'module',
'mib',
'included_by',
'last_modified',
);
if (isset($_POST['device_id'])) {
// device_id supplied - get details for a single device
// used by device MIB page
$params = array(
$_POST['device_id'],
);
$sql = 'SELECT * FROM `device_mibs`';
$wheresql = ' WHERE `device_id` = ?';
$sortcolumns = 3;
$count_sql = "SELECT COUNT(*) FROM `device_mibs`".$wheresql;
}
else {
// device_id not supplied - get details for a all devices
// used by all device MIBs page
$params = array();
$sql = 'SELECT `d`.`hostname` as `hostname`, `dm`.* FROM `devices` `d`, `device_mibs` `dm`';
$wheresql = ' WHERE `d`.`device_id` = `dm`.`device_id`';
array_unshift($columns, 'hostname');
$sortcolumns = 4;
$count_sql = "SELECT COUNT(*) FROM `devices` `d`, `device_mibs` `dm`".$wheresql;
}
// all columns are searchable - search across them
if (isset($searchPhrase) && !empty($searchPhrase)) {
$searchsql = implode(' OR ', array_map("search_phrase_column", array_map("mres", $columns)));
$wheresql .= " AND ( $searchsql )";
}
$sql .= $wheresql;
// get total
$total = dbFetchCell($count_sql, $params);
if (empty($total)) {
$total = 0;
}
// set up default sort
if (!isset($sort) || empty($sort)) {
$sort = implode(', ', array_map("mres", array_slice($columns, 0, $sortcolumns)));
}
$sql .= " ORDER BY $sort";
// select only the required rows
if (isset($current)) {
$limit_low = (($current * $rowCount) - ($rowCount));
$limit_high = $rowCount;
}
if ($rowCount != -1) {
$sql .= " LIMIT $limit_low,$limit_high";
}
// load data from database into response array
$response = array();
foreach (dbFetchRows($sql, $params) as $mib) {
$mibrow = array();
foreach ($columns as $col) {
$mibrow[$col] = $mib[$col];
}
if (!isset($_POST['device_id'])) {
$device = device_by_id_cache($mib['device_id']);
$mibrow['hostname'] = generate_device_link($device,
$mib['hostname'], array('tab' => 'mib'));
}
$response[] = $mibrow;
}
$output = array(
'current' => $current,
'rowCount' => $rowCount,
'rows' => $response,
'total' => $total,
);
echo _json_encode($output);
+83
View File
@@ -0,0 +1,83 @@
<?php
/*
* LibreNMS device MIB OID browser
*
* Copyright (c) 2015 Gear Consulting Pty Ltd <github@libertysys.com.au>
*
* by Paul Gear
* based on code by Søren Friis Rosiak <sorenrosiak@gmail.com>
* in commit 054bf3ae209f34a2c3bc8968300722004903df1b
*
* 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.
*/
$columns = array(
'module',
'mib',
'object_type',
'oid',
'value',
'numvalue',
'last_modified',
);
$params = array(
$_POST['device_id'],
);
// start of sql definition
$sql = 'SELECT * FROM `device_oids`';
$wheresql = ' WHERE `device_id` = ?';
// all columns are searchable - search across them
if (isset($searchPhrase) && !empty($searchPhrase)) {
$searchsql = implode(' OR ', array_map("search_phrase_column", array_map("mres", $columns)));
$wheresql .= " AND ( $searchsql )";
}
$sql .= $wheresql;
// get total
$count_sql = "SELECT COUNT(*) FROM `device_oids`".$wheresql;
$total = dbFetchCell($count_sql, $params);
if (empty($total)) {
$total = 0;
}
// sort by first three columns by default
if (!isset($sort) || empty($sort)) {
$sort = implode(', ', array_map("mres", array_slice($columns, 0, 3)));
}
$sql .= " ORDER BY $sort";
// select only the required rows
if (isset($current)) {
$limit_low = (($current * $rowCount) - ($rowCount));
$limit_high = $rowCount;
}
if ($rowCount != -1) {
$sql .= " LIMIT $limit_low,$limit_high";
}
// load data from database into response array
$response = array();
foreach (dbFetchRows($sql, $params) as $mib) {
$mibrow = array();
foreach ($columns as $col) {
$mibrow[$col] = $mib[$col];
}
$response[] = $mibrow;
}
$output = array(
'current' => $current,
'rowCount' => $rowCount,
'rows' => $response,
'total' => $total,
);
echo _json_encode($output);
+81
View File
@@ -0,0 +1,81 @@
<?php
/*
* LibreNMS MIB definition browser
*
* Copyright (c) 2015 Gear Consulting Pty Ltd <github@libertysys.com.au>
*
* by Paul Gear
* based on code by Søren Friis Rosiak <sorenrosiak@gmail.com>
* in commit 054bf3ae209f34a2c3bc8968300722004903df1b
*
* 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.
*/
$columns = array(
'module',
'mib',
'object_type',
'oid',
'syntax',
'description',
'max_access',
'status',
'included_by',
'last_modified',
);
// start of sql definition
$sql = 'SELECT * FROM `mibdefs`';
// all columns are searchable - search across them
if (isset($searchPhrase) && !empty($searchPhrase)) {
$searchsql = implode(' OR ', array_map("search_phrase_column", array_map("mres", $columns)));
$wheresql .= " WHERE ( $searchsql )";
$sql .= $wheresql;
}
// get total
$count_sql = "SELECT COUNT(`object_type`) FROM `mibdefs`".$wheresql;
$total = dbFetchCell($count_sql);
if (empty($total)) {
$total = 0;
}
// sort by first three columns by default
if (!isset($sort) || empty($sort)) {
$sort = implode(', ', array_map("mres", array_slice($columns, 0, 3)));
}
$sql .= " ORDER BY $sort";
// select only the required rows
if (isset($current)) {
$limit_low = (($current * $rowCount) - ($rowCount));
$limit_high = $rowCount;
}
if ($rowCount != -1) {
$sql .= " LIMIT $limit_low,$limit_high";
}
// load data from database into response array
$response = array();
foreach (dbFetchRows($sql) as $mib) {
$mibrow = array();
foreach ($columns as $col) {
$mibrow[$col] = $mib[$col];
}
$response[] = $mibrow;
}
$output = array(
'current' => $current,
'rowCount' => $rowCount,
'rows' => $response,
'total' => $total,
);
echo _json_encode($output);
+13 -1
View File
@@ -57,7 +57,11 @@ if (device_permitted($vars['device']) || $check_device == $vars['device']) {
</a>
</li>';
$health = (dbFetchCell("SELECT COUNT(*) FROM storage WHERE device_id = '".$device['device_id']."'") + dbFetchCell("SELECT COUNT(sensor_id) FROM sensors WHERE device_id = '".$device['device_id']."'") + dbFetchCell("SELECT COUNT(*) FROM mempools WHERE device_id = '".$device['device_id']."'") + dbFetchCell("SELECT COUNT(*) FROM processors WHERE device_id = '".$device['device_id']."'"));
$health = dbFetchCell("SELECT COUNT(*) FROM storage WHERE device_id = '" . $device['device_id'] . "'") +
dbFetchCell("SELECT COUNT(sensor_id) FROM sensors WHERE device_id = '" . $device['device_id'] . "'") +
dbFetchCell("SELECT COUNT(*) FROM mempools WHERE device_id = '" . $device['device_id'] . "'") +
dbFetchCell("SELECT COUNT(*) FROM processors WHERE device_id = '" . $device['device_id'] . "'") +
count_mib_health($device);
if ($health) {
echo '<li class="'.$select['health'].'">
@@ -367,6 +371,14 @@ if (device_permitted($vars['device']) || $check_device == $vars['device']) {
</a>
</li>';
if (device_permitted($device['device_id'])) {
echo '<li class="'.$select['mib'].'">
<a href="'.generate_device_url($device, array('tab' => 'mib')).'">
<i class="fa fa-file-text-o"></i> MIB
</a>
</li>';
}
echo '<li style="float: right;"><a href="https://'.$device['hostname'].'"><img src="images/16/http.png" alt="https" title="Launch browser to https://'.$device['hostname'].'" border="0" width="16" height="16" target="_blank"></a></li>
<li style="float: right;"><a href="ssh://'.$device['hostname'].'"><img src="images/16/ssh.png" alt="ssh" title="SSH to '.$device['hostname'].'" border="0" width="16" height="16"></a></li>
+1 -6
View File
@@ -22,11 +22,7 @@ foreach (dbFetchRows('SELECT * FROM device_graphs WHERE device_id = ? ORDER BY g
}
}
// These are standard graphs we should have for all systems
$graph_enable['poller']['poller_perf'] = 'device_poller_perf';
if (can_ping_device($attribs) === true) {
$graph_enable['poller']['ping_perf'] = 'device_ping_perf';
}
enable_graphs($device, $graph_enable);
$sep = '';
foreach ($graph_enable as $section => $nothing) {
@@ -56,7 +52,6 @@ print_optionbar_end();
$graph_enable = $graph_enable[$vars['group']];
// foreach ($config['graph_types']['device'] as $graph => $entry)
foreach ($graph_enable as $graph => $entry) {
$graph_array = array();
if ($graph_enable[$graph]) {
-8
View File
@@ -1,8 +0,0 @@
<?php
if (is_file($config['rrd_dir'].'/'.$device['hostname'].'/ucd_cpu.rrd')) {
$graph_title = 'Processor Utilisation';
$graph_type = 'device_cpu';
include 'includes/print-device-graph.php';
}
@@ -1,8 +0,0 @@
<?php
if (is_file($config['rrd_dir'].'/'.$device['hostname'].'/hrSystem.rrd')) {
$graph_title = 'Running Processes';
$graph_type = 'device_hrprocesses';
include 'includes/print-device-graph.php';
}
-8
View File
@@ -1,8 +0,0 @@
<?php
if (is_file($config['rrd_dir'].'/'.$device['hostname'].'/hrSystem.rrd')) {
$graph_title = 'Users Logged On';
$graph_type = 'device_hrusers';
include 'includes/print-device-graph.php';
}
-70
View File
@@ -1,70 +0,0 @@
<?php
if (is_file($config['rrd_dir'].'/'.$device['hostname'].'/ipSystemStats-ipv6.rrd')) {
$graph_title = 'IPv6 IP Packet Statistics';
$graph_type = 'device_ipSystemStats_v6';
include 'includes/print-device-graph.php';
$graph_title = 'IPv6 IP Fragmentation Statistics';
$graph_type = 'device_ipSystemStats_v6_frag';
include 'includes/print-device-graph.php';
}
if (is_file($config['rrd_dir'].'/'.$device['hostname'].'/ipSystemStats-ipv4.rrd')) {
$graph_title = 'IPv4 IP Packet Statistics';
$graph_type = 'device_ipSystemStats_v4';
include 'includes/print-device-graph.php';
}
if (is_file($config['rrd_dir'].'/'.$device['hostname'].'/netstats-ip.rrd')) {
$graph_title = 'IP Statistics';
$graph_type = 'device_ip';
include 'includes/print-device-graph.php';
$graph_title = 'IP Fragmented Statistics';
$graph_type = 'device_ip_fragmented';
include 'includes/print-device-graph.php';
}
if (is_file($config['rrd_dir'].'/'.$device['hostname'].'/netstats-tcp.rrd')) {
$graph_title = 'TCP Statistics';
$graph_type = 'device_tcp';
include 'includes/print-device-graph.php';
}
if (is_file($config['rrd_dir'].'/'.$device['hostname'].'/netstats-udp.rrd')) {
$graph_title = 'UDP Statistics';
$graph_type = 'device_udp';
include 'includes/print-device-graph.php';
}
if (is_file($config['rrd_dir'].'/'.$device['hostname'].'/netstats-snmp.rrd')) {
$graph_title = 'SNMP Packets Statistics';
$graph_type = 'device_snmp_packets';
include 'includes/print-device-graph.php';
$graph_title = 'SNMP Message Type Statistics';
$graph_type = 'device_snmp_statistics';
include 'includes/print-device-graph.php';
}
if (is_file($config['rrd_dir'].'/'.$device['hostname'].'/netstats-icmp.rrd')) {
$graph_title = 'ICMP Statistics';
$graph_type = 'device_icmp';
include 'includes/print-device-graph.php';
$graph_title = 'ICMP Informational Statistics';
$graph_type = 'device_icmp_informational';
include 'includes/print-device-graph.php';
}
@@ -1,8 +0,0 @@
<?php
if (is_file($config['rrd_dir'].'/'.$device['hostname'].'/netstats-icmp.rrd')) {
$graph_title = 'ICMP Informational Statistics';
$graph_type = 'device_icmp_informational';
include 'includes/print-device-graph.php';
}
@@ -1,13 +0,0 @@
<?php
if (is_file($config['rrd_dir'].'/'.$device['hostname'].'/netstats-snmp.rrd')) {
$graph_title = 'SNMP Packets Statistics';
$graph_type = 'device_snmp_packets';
include 'includes/print-device-graph.php';
$graph_title = 'SNMP Message Type Statistics';
$graph_type = 'device_snmp_statistics';
include 'includes/print-device-graph.php';
}
-6
View File
@@ -1,6 +0,0 @@
<?php
$graph_title = 'Device Uptime';
$graph_type = 'device_uptime';
require 'includes/print-device-graph.php';
+2 -2
View File
@@ -2,8 +2,8 @@
$storage = dbFetchCell('select count(*) from storage WHERE device_id = ?', array($device['device_id']));
$diskio = dbFetchCell('select count(*) from ucd_diskio WHERE device_id = ?', array($device['device_id']));
$mempools = dbFetchCell('select count(*) from mempools WHERE device_id = ?', array($device['device_id']));
$processor = dbFetchCell('select count(*) from processors WHERE device_id = ?', array($device['device_id']));
$mempools = dbFetchCell('select count(*) from mempools WHERE device_id = ?', array($device['device_id'])) + count_mib_mempools($device);
$processor = dbFetchCell('select count(*) from processors WHERE device_id = ?', array($device['device_id'])) + count_mib_processors($device);
$charge = dbFetchCell("select count(*) from sensors WHERE sensor_class='charge' AND device_id = ?", array($device['device_id']));
$temperatures = dbFetchCell("select count(*) from sensors WHERE sensor_class='temperature' AND device_id = ?", array($device['device_id']));
+36 -9
View File
@@ -4,8 +4,16 @@ $graph_type = 'mempool_usage';
$i = '1';
if (count_mib_mempools($device) > 0) {
$mempools = get_mib_mempools($device);
$graph_type = 'device_mempool';
}
else {
$mempools = dbFetchRows('SELECT * FROM `mempools` WHERE device_id = ?', array($device['device_id']));
}
// FIXME css alternating colours
foreach (dbFetchRows('SELECT * FROM `mempools` WHERE device_id = ?', array($device['device_id'])) as $mempool) {
foreach ($mempools as $mempool) {
if (!is_integer($i / 2)) {
$row_colour = $list_colour_a;
}
@@ -15,30 +23,49 @@ foreach (dbFetchRows('SELECT * FROM `mempools` WHERE device_id = ?', array($devi
$text_descr = rewrite_entity_descr($mempool['mempool_descr']);
$mempool_url = 'graphs/id='.$mempool['mempool_id'].'/type=mempool_usage/';
$mini_url = 'graph.php?id='.$mempool['mempool_id'].'&amp;type='.$graph_type.'&amp;from='.$config['time']['day'].'&amp;to='.$config['time']['now'].'&amp;width=80&amp;height=20&amp;bg=f4f4f4';
if ($graph_type == 'device_mempool') {
$id = 'device';
$val = $device['device_id'];
}
else {
$id = 'id';
$val = $mempool['mempool_id'];
}
$mempool_url = 'graphs/'.$id.'='.$val.'/type='.$graph_type.'/';
$mini_url = 'graph.php?'.$id.'='.$val.'&amp;type='.$graph_type.'&amp;from='.$config['time']['day'].'&amp;to='.$config['time']['now'].'&amp;width=80&amp;height=20&amp;bg=f4f4f4';
$mempool_popup = "onmouseover=\"return overlib('<div class=list-large>".$device['hostname'].' - '.$text_descr;
$mempool_popup .= "</div><img src=\'graph.php?id=".$mempool['mempool_id'].'&amp;type='.$graph_type.'&amp;from='.$config['time']['month'].'&amp;to='.$config['time']['now']."&amp;width=400&amp;height=125\'>";
$mempool_popup .= "</div><img src=\'graph.php?'.$id.'=".$val.'&amp;type='.$graph_type.'&amp;from='.$config['time']['month'].'&amp;to='.$config['time']['now']."&amp;width=400&amp;height=125\'>";
$mempool_popup .= "', RIGHT".$config['overlib_defaults'].');" onmouseout="return nd();"';
$total = formatStorage($mempool['mempool_total']);
$used = formatStorage($mempool['mempool_used']);
$free = formatStorage($mempool['mempool_free']);
$perc = round(($mempool['mempool_used'] / $mempool['mempool_total'] * 100));
// don't bother recalculating if mempools use percentage
if ($mempool['percentage'] === true) {
$perc = round($mempool['mempool_used']);
}
else {
$perc = round(($mempool['mempool_used'] / $mempool['mempool_total'] * 100));
}
$background = get_percentage_colours($percent);
$right_background = $background['right'];
$left_background = $background['left'];
$graph_array['id'] = $mempool['mempool_id'];
$graph_array[$id] = $val;
$graph_array['type'] = $graph_type;
echo "<div class='panel panel-default'>
<div class='panel-heading'>
<h3 class='panel-title'>$text_descr <div class='pull-right'>$used/$total - $perc% used</div></h3>
</div>";
<div class='panel-heading'>";
if ($mempool['percentage'] === true) {
echo " <h3 class='panel-title'>$text_descr <div class='pull-right'>$perc% used</div></h3>";
}
else {
echo " <h3 class='panel-title'>$text_descr <div class='pull-right'>$used/$total - $perc% used</div></h3>";
}
echo " </div>";
echo "<div class='panel-body'>";
include 'includes/print-graphrow.inc.php';
echo "</div></div>";
+23 -8
View File
@@ -3,21 +3,36 @@
$graph_type = 'processor_usage';
$i = '1';
foreach (dbFetchRows('SELECT * FROM `processors` WHERE device_id = ?', array($device['device_id'])) as $proc) {
$proc_url = 'graphs/id='.$proc['processor_id'].'/type=processor_usage/';
$mini_url = 'graph.php?id='.$proc['processor_id'].'&amp;type='.$graph_type.'&amp;from='.$config['time']['day'].'&amp;to='.$config['time']['now'].'&amp;width=80&amp;height=20&amp;bg=f4f4f4';
if (count_mib_processors($device) > 0) {
$processors = get_mib_processors($device);
$graph_type = 'device_processor';
}
else {
$processors = dbFetchRows('SELECT * FROM `processors` WHERE device_id = ?', array($device['device_id']));
}
$text_descr = $proc['processor_descr'];
foreach ($processors as $proc) {
if ($graph_type == 'device_processor') {
$id = 'device';
$val = $device['device_id'];
}
else {
$id = 'id';
$val = $proc['processor_id'];
}
$proc_url = 'graphs/'.$id.'='.$val.'/type='.$graph_type.'/';
$base_url = 'graph.php?'.$id.'='.$val.'&amp;type='.$graph_type.'&amp;from='.$config['time']['day'].'&amp;to='.$config['time']['now'];
$mini_url = $base_url.'&amp;width=80&amp;height=20&amp;bg=f4f4f4';
$text_descr = rewrite_entity_descr($text_descr);
$text_descr = rewrite_entity_descr($proc['processor_descr']);
$proc_popup = "onmouseover=\"return overlib('<div class=list-large>".$device['hostname'].' - '.$text_descr;
$proc_popup .= "</div><img src=\'graph.php?id=".$proc['processor_id'].'&amp;type='.$graph_type.'&amp;from='.$config['time']['month'].'&amp;to='.$config['time']['now']."&amp;width=400&amp;height=125\'>";
$proc_popup .= "</div><img src=\'".$base_url."&amp;width=400&amp;height=125\'>";
$proc_popup .= "', RIGHT".$config['overlib_defaults'].');" onmouseout="return nd();"';
$percent = round($proc['processor_usage']);
$graph_array['id'] = $proc['processor_id'];
$graph_array[$id] = $val;
$graph_array['type'] = $graph_type;
echo "<div class='panel panel-default'>
@@ -27,4 +42,4 @@ foreach (dbFetchRows('SELECT * FROM `processors` WHERE device_id = ?', array($de
echo "<div class='panel-body'>";
include 'includes/print-graphrow.inc.php';
echo "</div></div>";
}//end foreach
}//end foreach
+88
View File
@@ -0,0 +1,88 @@
<?php
/*
* LibreNMS device MIB browser
*
* Copyright (c) 2015 Gear Consulting Pty Ltd <github@libertysys.com.au>
*
* Author: Paul Gear
*
* 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.
*/
if (!isset($vars['section'])) {
$vars['section'] = "mib";
}
?>
<h4><i class="fa fa-file-text-o"></i> Device MIB associations</h4>
<div class="table-responsive">
<table id="mibs" class="table table-hover table-condensed mibs">
<thead>
<tr>
<th data-column-id="module">Module</th>
<th data-column-id="mib">MIB</th>
<th data-column-id="included_by">Included by</th>
<th data-column-id="last_modified">Last Modified</th>
</tr>
</thead>
</table>
</div>
<h4><i class="fa fa-file-text-o"></i> Device MIB values</h4>
<div class="table-responsive">
<table id="oids" class="table table-hover table-condensed mibs">
<thead>
<tr>
<th data-column-id="module">Module</th>
<th data-column-id="mib">MIB</th>
<th data-column-id="object_type">Object type</th>
<th data-column-id="oid">OID</th>
<th data-column-id="value">Value</th>
<th data-column-id="numvalue">Numeric Value</th>
<th data-column-id="last_modified">Last Modified</th>
</tr>
</thead>
</table>
</div>
<script>
var grid = $("#mibs").bootgrid({
ajax: true,
rowCount: [50,100,250,-1],
post: function ()
{
return {
id: "device_mibs",
device_id: '<?php echo htmlspecialchars($device['device_id']); ?>',
};
},
url: "/ajax_table.php",
formatters: {
},
templates: {
}
});
</script>
<script>
var grid2 = $("#oids").bootgrid({
ajax: true,
rowCount: [50,100,250,-1],
post: function ()
{
return {
id: "device_oids",
device_id: '<?php echo htmlspecialchars($device['device_id']); ?>',
};
},
url: "/ajax_table.php",
formatters: {
},
templates: {
}
});
</script>
+49
View File
@@ -0,0 +1,49 @@
<?php
/*
* LibreNMS global MIB association viewer
*
* Copyright (c) 2015 Gear Consulting Pty Ltd <github@libertysys.com.au>
*
* Author: Paul Gear
*
* 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.
*/
?>
<h4>MIB associations for all devices</h4>
<div class="table-responsive">
<table id="mibs" class="table table-hover table-condensed mibs">
<thead>
<tr>
<th data-column-id="hostname">Hostname</th>
<th data-column-id="module">Module</th>
<th data-column-id="mib">MIB</th>
<th data-column-id="included_by">Included by</th>
<th data-column-id="last_modified">Last Modified</th>
</tr>
</thead>
</table>
</div>
<script>
var grid = $("#mibs").bootgrid({
ajax: true,
rowCount: [50,100,250,-1],
post: function ()
{
return {
id: "device_mibs",
};
},
url: "/ajax_table.php",
formatters: {
},
templates: {
}
});
</script>
+54
View File
@@ -0,0 +1,54 @@
<?php
/*
* LibreNMS global MIB viewer
*
* Copyright (c) 2015 Gear Consulting Pty Ltd <github@libertysys.com.au>
*
* Author: Paul Gear
*
* 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.
*/
?>
<h4><i class="fa fa-file-text-o"></i> All MIB definitions</h4>
<div class="table-responsive">
<table id="mibs" class="table table-hover table-condensed mibs">
<thead>
<tr>
<th data-column-id="module">Module</th>
<th data-column-id="mib">MIB</th>
<th data-column-id="object_type">Object Type</th>
<th data-column-id="oid">Object Id</th>
<th data-column-id="syntax">Syntax</th>
<th data-column-id="description">Description</th>
<!-- th data-column-id="max_access">Maximum Access</th>
<th data-column-id="status">Status</th -->
<th data-column-id="included_by">Included by</th>
<th data-column-id="last_modified">Last modified</th>
</tr>
</thead>
</table>
</div>
<script>
var grid = $("#mibs").bootgrid({
ajax: true,
rowCount: [50,100,250,-1],
post: function ()
{
return {
id: "mibs",
view: '<?php echo $vars['view']; ?>'
};
},
url: "/ajax_table.php",
formatters: {
},
templates: {
}
});
</script>
+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
+5
View File
@@ -0,0 +1,5 @@
CREATE TABLE IF NOT EXISTS `mibdefs` ( `module` varchar(255) NOT NULL, `mib` varchar(255) NOT NULL, `object_type` varchar(255) NOT NULL, `oid` varchar(255) NOT NULL, `syntax` varchar(255) NOT NULL, `description` varchar(255), `max_access` varchar(255), `status` varchar(255), `included_by` varchar(255) NOT NULL, `last_modified` timestamp NOT NULL, PRIMARY KEY (`module`, `mib`, `object_type`)) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='MIB definitions';
CREATE TABLE IF NOT EXISTS `device_mibs` ( `device_id` integer(11) NOT NULL, `module` varchar(255) NOT NULL, `mib` varchar(255) NOT NULL, `included_by` varchar(255) NOT NULL, `last_modified` timestamp NOT NULL, PRIMARY KEY (`device_id`, `module`, `mib`)) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Device to MIB mappings';
CREATE TABLE IF NOT EXISTS `device_oids` ( `device_id` int(11) NOT NULL, `oid` varchar(255) NOT NULL, `module` varchar(255) NOT NULL, `mib` varchar(255) NOT NULL, `object_type` varchar(255) NOT NULL, `value` varchar(255), `numvalue` bigint, `last_modified` timestamp NOT NULL, PRIMARY KEY (`device_id`, `oid`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Per-device MIB data';
DELETE FROM `device_graphs`;
ALTER TABLE `device_graphs` CHANGE `graph` `graph` VARCHAR(255);