From b9747b2002cea433a16d4311a26f9d6fda58143d Mon Sep 17 00:00:00 2001 From: Aaron Daniels Date: Tue, 9 Aug 2016 07:14:25 +1000 Subject: [PATCH] CISCO-NTP-MIB A new Discovery/Poller module to collect NTP statistics from devices which support the CISCO-NTP-MIB Discovered peers are stored using components and statistics are displayed using 'applications' A critical alarm is raised when a stratum of 16 is reported. --- .../graphs/device/cisco-ntp_delay.inc.php | 53 ++++++ .../device/cisco-ntp_dispersion.inc.php | 53 ++++++ .../graphs/device/cisco-ntp_offset.inc.php | 53 ++++++ .../graphs/device/cisco-ntp_stratum.inc.php | 53 ++++++ html/pages/apps/cisco-ntp.inc.php | 167 ++++++++++++++++++ html/pages/device/apps/cisco-ntp.inc.php | 129 ++++++++++++++ includes/defaults.inc.php | 2 + includes/discovery/cisco-ntp.inc.php | 135 ++++++++++++++ includes/polling/cisco-ntp.inc.php | 82 +++++++++ 9 files changed, 727 insertions(+) create mode 100644 html/includes/graphs/device/cisco-ntp_delay.inc.php create mode 100644 html/includes/graphs/device/cisco-ntp_dispersion.inc.php create mode 100644 html/includes/graphs/device/cisco-ntp_offset.inc.php create mode 100644 html/includes/graphs/device/cisco-ntp_stratum.inc.php create mode 100644 html/pages/apps/cisco-ntp.inc.php create mode 100644 html/pages/device/apps/cisco-ntp.inc.php create mode 100644 includes/discovery/cisco-ntp.inc.php create mode 100644 includes/polling/cisco-ntp.inc.php diff --git a/html/includes/graphs/device/cisco-ntp_delay.inc.php b/html/includes/graphs/device/cisco-ntp_delay.inc.php new file mode 100644 index 0000000000..7da30204a0 --- /dev/null +++ b/html/includes/graphs/device/cisco-ntp_delay.inc.php @@ -0,0 +1,53 @@ + + * + * 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. + */ + +require_once "../includes/component.php"; +$component = new component(); +$options = array(); +$options['filter']['type'] = array('=','Cisco-NTP'); +$components = $component->getComponents($device['device_id'],$options); + +// We only care about our device id. +$components = $components[$device['device_id']]; + +include "includes/graphs/common.inc.php"; +$rrd_options .= " -l 0 -E "; +$rrd_options .= " COMMENT:'Delay Now Min Max\\n'"; +$rrd_additions = ""; + +$count = 0; +foreach ($components as $id => $array) { + $rrd_filename = $config['rrd_dir'].'/'.$device['hostname'].'/'.safename("ntp-".$array['peer'].".rrd"); + + if (file_exists($rrd_filename)) { + // Grab a color from the array. + if ( isset($config['graph_colours']['mixed'][$count]) ) { + $color = $config['graph_colours']['mixed'][$count]; + } else { + $color = $config['graph_colours']['oranges'][$count-7]; + } + + $rrd_additions .= " DEF:DS" . $count . "=" . $rrd_filename . ":delay:AVERAGE "; + $rrd_additions .= " LINE1.25:DS" . $count . "#" . $color . ":'" . str_pad(substr($array['peer'].' (s)',0,15),15) . "'" . $stack; + $rrd_additions .= " GPRINT:DS" . $count . ":LAST:%7.0lf "; + $rrd_additions .= " GPRINT:DS" . $count . ":MIN:%7.0lf "; + $rrd_additions .= " GPRINT:DS" . $count . ":MAX:%7.0lf\\\l "; + $count++; + } +} + +if ($rrd_additions == "") { + // We didn't add any data points. +} else { + $rrd_options .= $rrd_additions; +} diff --git a/html/includes/graphs/device/cisco-ntp_dispersion.inc.php b/html/includes/graphs/device/cisco-ntp_dispersion.inc.php new file mode 100644 index 0000000000..412e9989f9 --- /dev/null +++ b/html/includes/graphs/device/cisco-ntp_dispersion.inc.php @@ -0,0 +1,53 @@ + + * + * 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. + */ + +require_once "../includes/component.php"; +$component = new component(); +$options = array(); +$options['filter']['type'] = array('=','Cisco-NTP'); +$components = $component->getComponents($device['device_id'],$options); + +// We only care about our device id. +$components = $components[$device['device_id']]; + +include "includes/graphs/common.inc.php"; +$rrd_options .= " -l 0 -E "; +$rrd_options .= " COMMENT:'Dispersion Now Min Max\\n'"; +$rrd_additions = ""; + +$count = 0; +foreach ($components as $id => $array) { + $rrd_filename = $config['rrd_dir'].'/'.$device['hostname'].'/'.safename("ntp-".$array['peer'].".rrd"); + + if (file_exists($rrd_filename)) { + // Grab a color from the array. + if ( isset($config['graph_colours']['mixed'][$count]) ) { + $color = $config['graph_colours']['mixed'][$count]; + } else { + $color = $config['graph_colours']['oranges'][$count-7]; + } + + $rrd_additions .= " DEF:DS" . $count . "=" . $rrd_filename . ":dispersion:AVERAGE "; + $rrd_additions .= " LINE1.25:DS" . $count . "#" . $color . ":'" . str_pad(substr($array['peer'].' (s)',0,15),15) . "'" . $stack; + $rrd_additions .= " GPRINT:DS" . $count . ":LAST:%7.0lf "; + $rrd_additions .= " GPRINT:DS" . $count . ":MIN:%7.0lf "; + $rrd_additions .= " GPRINT:DS" . $count . ":MAX:%7.0lf\\\l "; + $count++; + } +} + +if ($rrd_additions == "") { + // We didn't add any data points. +} else { + $rrd_options .= $rrd_additions; +} diff --git a/html/includes/graphs/device/cisco-ntp_offset.inc.php b/html/includes/graphs/device/cisco-ntp_offset.inc.php new file mode 100644 index 0000000000..4e9281018e --- /dev/null +++ b/html/includes/graphs/device/cisco-ntp_offset.inc.php @@ -0,0 +1,53 @@ + + * + * 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. + */ + +require_once "../includes/component.php"; +$component = new component(); +$options = array(); +$options['filter']['type'] = array('=','Cisco-NTP'); +$components = $component->getComponents($device['device_id'],$options); + +// We only care about our device id. +$components = $components[$device['device_id']]; + +include "includes/graphs/common.inc.php"; +$rrd_options .= " -l 0 -E "; +$rrd_options .= " COMMENT:'Offset Now Min Max\\n'"; +$rrd_additions = ""; + +$count = 0; +foreach ($components as $id => $array) { + $rrd_filename = $config['rrd_dir'].'/'.$device['hostname'].'/'.safename("ntp-".$array['peer'].".rrd"); + + if (file_exists($rrd_filename)) { + // Grab a color from the array. + if ( isset($config['graph_colours']['mixed'][$count]) ) { + $color = $config['graph_colours']['mixed'][$count]; + } else { + $color = $config['graph_colours']['oranges'][$count-7]; + } + + $rrd_additions .= " DEF:DS" . $count . "=" . $rrd_filename . ":offset:AVERAGE "; + $rrd_additions .= " LINE1.25:DS" . $count . "#" . $color . ":'" . str_pad(substr($array['peer'].' (s)',0,15),15) . "'" . $stack; + $rrd_additions .= " GPRINT:DS" . $count . ":LAST:%4.0lf "; + $rrd_additions .= " GPRINT:DS" . $count . ":MIN:%4.0lf "; + $rrd_additions .= " GPRINT:DS" . $count . ":MAX:%4.0lf\\\l "; + $count++; + } +} + +if ($rrd_additions == "") { + // We didn't add any data points. +} else { + $rrd_options .= $rrd_additions; +} diff --git a/html/includes/graphs/device/cisco-ntp_stratum.inc.php b/html/includes/graphs/device/cisco-ntp_stratum.inc.php new file mode 100644 index 0000000000..0ed0945d33 --- /dev/null +++ b/html/includes/graphs/device/cisco-ntp_stratum.inc.php @@ -0,0 +1,53 @@ + + * + * 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. + */ + +require_once "../includes/component.php"; +$component = new component(); +$options = array(); +$options['filter']['type'] = array('=','Cisco-NTP'); +$components = $component->getComponents($device['device_id'],$options); + +// We only care about our device id. +$components = $components[$device['device_id']]; + +include "includes/graphs/common.inc.php"; +$rrd_options .= " -l 0 -E "; +$rrd_options .= " COMMENT:'Stratum Now Min Max\\n'"; +$rrd_additions = ""; + +$count = 0; +foreach ($components as $id => $array) { + $rrd_filename = $config['rrd_dir'].'/'.$device['hostname'].'/'.safename("ntp-".$array['peer'].".rrd"); + + if (file_exists($rrd_filename)) { + // Grab a color from the array. + if ( isset($config['graph_colours']['mixed'][$count]) ) { + $color = $config['graph_colours']['mixed'][$count]; + } else { + $color = $config['graph_colours']['oranges'][$count-7]; + } + + $rrd_additions .= " DEF:DS" . $count . "=" . $rrd_filename . ":stratum:AVERAGE "; + $rrd_additions .= " LINE1.25:DS" . $count . "#" . $color . ":'" . str_pad(substr($array['peer'],0,15),15) . "'" . $stack; + $rrd_additions .= " GPRINT:DS" . $count . ":LAST:%2.0lf "; + $rrd_additions .= " GPRINT:DS" . $count . ":MIN:%2.0lf "; + $rrd_additions .= " GPRINT:DS" . $count . ":MAX:%2.0lf\\\l "; + $count++; + } +} + +if ($rrd_additions == "") { + // We didn't add any data points. +} else { + $rrd_options .= $rrd_additions; +} diff --git a/html/pages/apps/cisco-ntp.inc.php b/html/pages/apps/cisco-ntp.inc.php new file mode 100644 index 0000000000..2567eaa533 --- /dev/null +++ b/html/pages/apps/cisco-ntp.inc.php @@ -0,0 +1,167 @@ + + * + * 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. + */ + +require_once "../includes/component.php"; +$component = new component(); +$options = array(); +$options['filter']['ignore'] = array('=',0); +$options['type'] = 'Cisco-NTP'; +$components = $component->getComponents(null,$options); + +print_optionbar_start(); + +$view_options = array( + 'all' => 'All', + 'error' => 'Error', +); +if (!$vars['view']) { + $vars['view'] = 'all'; +} + +$graph_options = array( + 'none' => 'No Graphs', + 'stratum' => 'Stratum', + 'offset' => 'Offset', + 'delay' => 'Delay', + 'dispersion' => 'Dispersion', +); +if (!$vars['graph']) { + $vars['graph'] = 'none'; +} + +echo 'NTP Peers » '; + +// The menu option - on the left +$sep = ''; +foreach ($view_options as $option => $text) { + if (empty($vars['view'])) { + $vars['view'] = $option; + } + echo $sep; + if ($vars['view'] == $option) { + echo ""; + } + echo generate_link($text, $vars, array('view' => $option)); + if ($vars['view'] == $option) { + echo ''; + } + $sep = ' | '; +} + +// The status option - on the right +echo '
'; +$sep = ''; +foreach ($graph_options as $option => $text) { + if (empty($vars['graph'])) { + $vars['graph'] = $option; + } + echo $sep; + if ($vars['graph'] == $option) { + echo ""; + } + + echo generate_link($text, $vars, array('graph' => $option)); + if ($vars['graph'] == $option) { + echo ''; + } + $sep = ' | '; +} +unset($sep); +echo '
'; +print_optionbar_end(); + +?> + + + + + + + + + + $comp) { + $device = device_by_id_cache($devid); + + // Loop through each component + foreach ($comp as $compid => $array) { + $display = true; + if ($vars['view'] == 'error') { + // Only display peers with errors + if ($array['status'] != 2) { + $display = false; + } + } + if ($array['status'] == 2) { + $status = 'class="danger"'; + } else { + $status = ''; + } + + if ($display === true) { + $link = generate_device_link($device,null,array('tab' => 'apps', 'app' => 'cisco-ntp')); + $count++; +?> + > + + + + + +'; + echo ''; + echo ''; + } + + } // End if display + } // End foreach component + } // End foreach device + + // If there are no results, let the user know. + if ($count == 0) { +?> + + + + +
DevicePeerStratumError
'; + require 'includes/print-graphrow.inc.php'; + echo '
No Matching NTP Peers
diff --git a/html/pages/device/apps/cisco-ntp.inc.php b/html/pages/device/apps/cisco-ntp.inc.php new file mode 100644 index 0000000000..211496ab6f --- /dev/null +++ b/html/pages/device/apps/cisco-ntp.inc.php @@ -0,0 +1,129 @@ + + * + * 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. + */ + +require_once "../includes/component.php"; +$component = new component(); +$options = array(); +$options['filter']['ignore'] = array('=',0); +$options['type'] = 'Cisco-NTP'; +$components = $component->getComponents($device['device_id'],$options); +$components = $components[$device['device_id']]; + +global $config; +?> + + + + + + + + + + + > + + + + + + +
PeerStratumPeer ReferenceStatus
+ +
+
+

NTP Stratum

+
+
+ +
+
+ +
+
+

Offset

+
+
+ +
+
+ +
+
+

Delay

+
+
+ +
+
+ +
+
+

Dispersion

+
+
+ +
+
diff --git a/includes/defaults.inc.php b/includes/defaults.inc.php index a8121ded47..6bcb53db64 100644 --- a/includes/defaults.inc.php +++ b/includes/defaults.inc.php @@ -715,6 +715,7 @@ $config['poller_modules']['cisco-voice'] = 1; $config['poller_modules']['cisco-cbqos'] = 1; $config['poller_modules']['stp'] = 1; $config['poller_modules']['cisco-otv'] = 1; +$config['poller_modules']['cisco-ntp'] = 1; $config['poller_modules']['services'] = 1; // List of discovery modules. Need to be in this array to be @@ -752,6 +753,7 @@ $config['discovery_modules']['charge'] = 1; $config['discovery_modules']['cisco-cbqos'] = 0; $config['discovery_modules']['stp'] = 1; $config['discovery_modules']['cisco-otv'] = 1; +$config['discovery_modules']['cisco-ntp'] = 1; $config['modules_compat']['rfc1628']['liebert'] = 1; $config['modules_compat']['rfc1628']['netmanplus'] = 1; diff --git a/includes/discovery/cisco-ntp.inc.php b/includes/discovery/cisco-ntp.inc.php new file mode 100644 index 0000000000..64ffca2a1a --- /dev/null +++ b/includes/discovery/cisco-ntp.inc.php @@ -0,0 +1,135 @@ + + * + * 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 ($device['os_group'] == 'cisco') { + + $module = 'Cisco-NTP'; + + require_once 'includes/component.php'; + $component = new component(); + $components = $component->getComponents($device['device_id'],array('type'=>$module)); + + // We only care about our device id. + $components = $components[$device['device_id']]; + + // Begin our master array, all other values will be processed into this array. + $tblComponents = array(); + + // Let's gather some data.. + // For Reference: + // http://www.oidview.com/mibs/9/CISCO-NTP-MIB.html + // http://www.cisco.com/c/en/us/support/docs/availability/high-availability/19643-ntpm.html + $cntpPeersVarEntry = snmpwalk_array_num($device, '.1.3.6.1.4.1.9.9.168.1.2.1.1', 2); + + /* + * False == no object found - this is not an error, no objects exist + * null == timeout or something else that caused an error, there may be objects but we couldn't get it. + */ + if ( is_null($cntpPeersVarEntry) ) { + // We have to error here or we will end up deleting all our components. + echo "Error\n"; + } else { + // No Error, lets process things. + d_echo("Objects Found:\n"); + + // Let's grab the index for each NTP peer + foreach ($cntpPeersVarEntry['1.3.6.1.4.1.9.9.168.1.2.1.1'][2] as $index => $value) { + $result = array(); + $result['UID'] = (string)$index; // This is cast as a string so it can be compared with the database value. + $result['peer'] = $cntpPeersVarEntry['1.3.6.1.4.1.9.9.168.1.2.1.1'][3][$index]; + $result['port'] = $cntpPeersVarEntry['1.3.6.1.4.1.9.9.168.1.2.1.1'][4][$index]; + $result['stratum'] = $cntpPeersVarEntry['1.3.6.1.4.1.9.9.168.1.2.1.1'][9][$index]; + $result['peerref'] = hex_to_ip($cntpPeersVarEntry['1.3.6.1.4.1.9.9.168.1.2.1.1'][15][$index]); + $result['label'] = $result['peer'].":".$result['port']; + + // Set the status, 16 = Bad + if ($result['stratum'] == 16) { + $result['status'] = 2; + $result['error'] = 'NTP Stratum is Insane'; + } else { + $result['status'] = 0; + $result['error'] = ''; + } + + d_echo("NTP Peer found: "); + d_echo($result); + $tblComponents[] = $result; + } + + /* + * Ok, we have our 2 array's (Components and SNMP) now we need + * to compare and see what needs to be added/updated. + * + * Let's loop over the SNMP data to see if we need to ADD or UPDATE any components. + */ + foreach ($tblComponents as $key => $array) { + $component_key = false; + + // Loop over our components to determine if the component exists, or we need to add it. + foreach ($components as $compid => $child) { + if ($child['UID'] === $array['UID']) { + $component_key = $compid; + } + } + + if (!$component_key) { + // The component doesn't exist, we need to ADD it - ADD. + $new_component = $component->createComponent($device['device_id'],$module); + $component_key = key($new_component); + $components[$component_key] = array_merge($new_component[$component_key], $array); + echo "+"; + } else { + // The component does exist, merge the details in - UPDATE. + $components[$component_key] = array_merge($components[$component_key], $array); + echo "."; + } + + } + + /* + * Loop over the Component data to see if we need to DELETE any components. + */ + foreach ($components as $key => $array) { + // Guilty until proven innocent + $found = false; + + foreach ($tblComponents as $k => $v) { + if ($array['UID'] == $v['UID']) { + // Yay, we found it... + $found = true; + } + } + + if ($found === false) { + // The component has not been found. we should delete it. + echo "-"; + $component->deleteComponent($key); + } + } + + // Write the Components back to the DB. + $component->setComponentPrefs($device['device_id'],$components); + echo "\n"; + + } // End if not error + + $module = strtolower($module); + if (count($components) > 0) { + if (dbFetchCell('SELECT COUNT(*) FROM `applications` WHERE `device_id` = ? AND `app_type` = ?', array($device['device_id'], $module)) == '0') { + dbInsert(array('device_id' => $device['device_id'], 'app_type' => $module), 'applications'); + } + } else { + dbDelete('applications', '`device_id` = ? AND `app_type` = ?', array($device['device_id'], $module)); + } + +} diff --git a/includes/polling/cisco-ntp.inc.php b/includes/polling/cisco-ntp.inc.php new file mode 100644 index 0000000000..f7c11654a6 --- /dev/null +++ b/includes/polling/cisco-ntp.inc.php @@ -0,0 +1,82 @@ + + * + * 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 ($device['os_group'] == "cisco") { + + $module = 'Cisco-NTP'; + + require_once 'includes/component.php'; + $component = new component(); + $options = array(); + $options['filter']['type'] = array('=',$module); + $options['filter']['disabled'] = array('=',0); + $options['filter']['ignore'] = array('=',0); + $components = $component->getComponents($device['device_id'],$options); + + // We only care about our device id. + $components = $components[$device['device_id']]; + + // Only collect SNMP data if we have enabled components + if (count($components > 0)) { + // Let's gather the stats.. + $cntpPeersVarEntry = snmpwalk_array_num($device, '.1.3.6.1.4.1.9.9.168.1.2.1.1', 2); + + // Loop through the components and extract the data. + foreach ($components as $key => &$array) { + + // Let's make sure the rrd is setup for this class. + $filename = "ntp-".$array['peer'].".rrd"; + $rrd_filename = $config['rrd_dir'] . "/" . $device['hostname'] . "/" . safename ($filename); + + if (!file_exists ($rrd_filename)) { + rrdtool_create ($rrd_filename, " DS:stratum:GAUGE:600:0:U DS:offset:GAUGE:600:0:U DS:delay:GAUGE:600:0:U DS:dispersion:GAUGE:600:0:U" . $config['rrd_rra']); + } + + $array['stratum'] = $cntpPeersVarEntry['1.3.6.1.4.1.9.9.168.1.2.1.1'][9][$array['UID']]; + // Set the status, 16 = Bad + if ($array['stratum'] == 16) { + $array['status'] = 2; + $array['error'] = 'NTP Stratum is Insane'; + } else { + $array['status'] = 0; + $array['error'] = ''; + } + + // Extract the statistics and update rrd + $rrd['stratum'] = $array['stratum']; + $rrd['offset'] = hexdec($cntpPeersVarEntry['1.3.6.1.4.1.9.9.168.1.2.1.1'][23][$array['UID']]); + $rrd['delay'] = hexdec($cntpPeersVarEntry['1.3.6.1.4.1.9.9.168.1.2.1.1'][24][$array['UID']]); + $rrd['dispersion'] = hexdec($cntpPeersVarEntry['1.3.6.1.4.1.9.9.168.1.2.1.1'][25][$array['UID']]); + rrdtool_update ($rrd_filename, $rrd); + + // Let's print some debugging info. + d_echo("\n\nComponent: ".$key."\n"); + d_echo(" Index: ".$array['UID']."\n"); + d_echo(" Peer: ".$array['peer'].":".$array['port']."\n"); + d_echo(" Stratum: 1.3.6.1.4.1.9.9.168.1.2.1.1.9.".$array['UID']." = ".$rrd['stratum']."\n"); + d_echo(" Offset: 1.3.6.1.4.1.9.9.168.1.2.1.1.23.".$array['UID']." = ".$rrd['offset']."\n"); + d_echo(" Delay: 1.3.6.1.4.1.9.9.168.1.2.1.1.24.".$array['UID']." = ".$rrd['delay']."\n"); + d_echo(" Dispersion: 1.3.6.1.4.1.9.9.168.1.2.1.1.25.".$array['UID']." = ".$rrd['dispersion']."\n"); + + // Clean-up after yourself! + unset($filename, $rrd_filename, $rrd); + } // End foreach components + + // Write the Components back to the DB. + $component->setComponentPrefs($device['device_id'],$components); + + } // end if count components + + // Clean-up after yourself! + unset($type, $components, $component, $options, $module); +}