From 8f4dbb533801a00f2e781cd057ddbd4dd3041ce3 Mon Sep 17 00:00:00 2001 From: Aaron Daniels Date: Thu, 21 Jan 2016 22:04:20 +1000 Subject: [PATCH 01/19] Cisco OTV Implements the CISCO-OTV-MIB to retrieve OTV counters from Cisco devices. This collects information on the configured Overlays and Adjacencies Statistics are collected for the amount of VLAN's on each overlay and the amount of MAC addresses available over each OTV endpoint. OTV alerts are collected and generated if the appropriate alerting rules exist. Data is displayed under routing at both the global and device level. Includes function snmpwalk_array_num, which performs a numeric SNMPWalk and returns an array containing $count indexes One Index: From: 1.3.6.1.4.1.9.9.166.1.15.1.1.27.18.655360 = 0 To: $array['1.3.6.1.4.1.9.9.166.1.15.1.1.27.18']['655360'] = 0 Two Indexes: From: 1.3.6.1.4.1.9.9.166.1.15.1.1.27.18.655360 = 0 To: $array['1.3.6.1.4.1.9.9.166.1.15.1.1.27']['18']['655360'] = 0 And so on... --- doc/Extensions/Component.md | 6 +- .../graphs/device/cisco-otv-mac.inc.php | 62 +++++ .../graphs/device/cisco-otv-vlan.inc.php | 62 +++++ html/includes/print-menubar.php | 18 +- html/pages/device.inc.php | 10 + html/pages/device/routing.inc.php | 1 + html/pages/device/routing/cisco-otv.inc.php | 94 +++++++ html/pages/routing.inc.php | 2 + html/pages/routing/cisco-otv.inc.php | 58 +++++ includes/defaults.inc.php | 2 + includes/discovery/cisco-otv.inc.php | 235 ++++++++++++++++++ includes/polling/cisco-otv.inc.php | 181 ++++++++++++++ includes/snmp.inc.php | 66 +++++ 13 files changed, 793 insertions(+), 4 deletions(-) create mode 100644 html/includes/graphs/device/cisco-otv-mac.inc.php create mode 100644 html/includes/graphs/device/cisco-otv-vlan.inc.php create mode 100644 html/pages/device/routing/cisco-otv.inc.php create mode 100644 html/pages/routing/cisco-otv.inc.php create mode 100644 includes/discovery/cisco-otv.inc.php create mode 100644 includes/polling/cisco-otv.inc.php diff --git a/doc/Extensions/Component.md b/doc/Extensions/Component.md index 235335380..13bef6b4e 100644 --- a/doc/Extensions/Component.md +++ b/doc/Extensions/Component.md @@ -307,11 +307,11 @@ To see an example of how the component module can used, please see the following - Cisco CBQoS - includes/discovery/cisco-cbqos.inc.php - - includes/poller/cisco-cbqos.inc.php + - includes/polling/cisco-cbqos.inc.php - html/includes/graphs/device/cbqos_traffic.inc.php - Cisco OTV - includes/discovery/cisco-otv.inc.php - - includes/poller/applications/cisco-otv.inc.php + - includes/polling/cisco-otv.inc.php - html/includes/graphs/device/cisco-otv-mac.inc.php - - html/pages/device/apps/cisco-otv.inc.php + - html/pages/routing/cisco-otv.inc.php diff --git a/html/includes/graphs/device/cisco-otv-mac.inc.php b/html/includes/graphs/device/cisco-otv-mac.inc.php new file mode 100644 index 000000000..5c616869e --- /dev/null +++ b/html/includes/graphs/device/cisco-otv-mac.inc.php @@ -0,0 +1,62 @@ + + * + * 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['filter']['type'] = array('=','Cisco-OTV'); +$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:'MAC Addresses Now Min Max\\n'"; +$rrd_additions = ""; + +$COUNT = 0; +foreach ($COMPONENTS as $ID => $ARRAY) { + if ($ARRAY['otvtype'] == 'endpoint') { + $rrd_filename = $config['rrd_dir'].'/'.$device['hostname'].'/'.safename("cisco-otv-".$ARRAY['endpoint']."-mac.rrd"); + + if (file_exists($rrd_filename)) { + // Stack the area on the second and subsequent DS's + $STACK = ""; + if ($COUNT != 0) { + $STACK = ":STACK "; + } + + // 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 . ":count:AVERAGE "; + $rrd_additions .= " AREA:DS" . $COUNT . "#" . $COLOR . ":'" . str_pad(substr($COMPONENTS[$ID]['endpoint'],0,15),15) . "'" . $STACK; + $rrd_additions .= " GPRINT:DS" . $COUNT . ":LAST:%4.0lf%s "; + $rrd_additions .= " GPRINT:DS" . $COUNT . ":MIN:%4.0lf%s "; + $rrd_additions .= " GPRINT:DS" . $COUNT . ":MAX:%4.0lf%s\\\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-otv-vlan.inc.php b/html/includes/graphs/device/cisco-otv-vlan.inc.php new file mode 100644 index 000000000..8ee50acf4 --- /dev/null +++ b/html/includes/graphs/device/cisco-otv-vlan.inc.php @@ -0,0 +1,62 @@ + + * + * 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['filter']['type'] = array('=','Cisco-OTV'); +$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:'VLANs Now Min Max\\n'"; +$rrd_additions = ""; + +$COUNT = 0; +foreach ($COMPONENTS as $ID => $ARRAY) { + if ($ARRAY['otvtype'] == 'overlay') { + $rrd_filename = $config['rrd_dir'].'/'.$device['hostname'].'/'.safename("cisco-otv-".$ARRAY['label']."-vlan.rrd"); + + if (file_exists($rrd_filename)) { + // Stack the area on the second and subsequent DS's + $STACK = ""; + if ($COUNT != 0) { + $STACK = ":STACK "; + } + + // 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 . ":count:AVERAGE "; + $rrd_additions .= " AREA:DS" . $COUNT . "#" . $COLOR . ":'" . str_pad(substr($COMPONENTS[$ID]['label'],0,15),15) . "'" . $STACK; + $rrd_additions .= " GPRINT:DS" . $COUNT . ":LAST:%4.0lf%s "; + $rrd_additions .= " GPRINT:DS" . $COUNT . ":MIN:%4.0lf%s "; + $rrd_additions .= " GPRINT:DS" . $COUNT . ":MAX:%4.0lf%s\\\l "; + $COUNT++; + } + } +} + +if ($rrd_additions == "") { + // We didn't add any data points. +} +else { + $rrd_options .= $rrd_additions; +} diff --git a/html/includes/print-menubar.php b/html/includes/print-menubar.php index 74ae6f7a1..859af924f 100644 --- a/html/includes/print-menubar.php +++ b/html/includes/print-menubar.php @@ -420,7 +420,13 @@ $routing_count['ospf'] = dbFetchCell("SELECT COUNT(ospf_instance_id) FROM `ospf_ $routing_count['cef'] = dbFetchCell("SELECT COUNT(cef_switching_id) from `cef_switching`"); $routing_count['vrf'] = dbFetchCell("SELECT COUNT(vrf_id) from `vrfs`"); -if ($_SESSION['userlevel'] >= '5' && ($routing_count['bgp']+$routing_count['ospf']+$routing_count['cef']+$routing_count['vrf']) > "0") { +require_once "../includes/component.php"; +$COMPONENT = new component(); +$options['type'] = 'Cisco-OTV'; +$OTV = $COMPONENT->getComponents(null,$options); +$routing_count['cisco-otv'] = count($OTV); + +if ($_SESSION['userlevel'] >= '5' && ($routing_count['bgp']+$routing_count['ospf']+$routing_count['cef']+$routing_count['vrf']+$routing_count['cisco-otv']) > "0") { ?> '); + $separator = 0; + } + echo('
  • Cisco OTV
  • '); + $separator++; + } + // BGP Sessions if ($_SESSION['userlevel'] >= '5' && $routing_count['bgp']) { if ($separator) { diff --git a/html/pages/device.inc.php b/html/pages/device.inc.php index 94a296822..3de92da54 100644 --- a/html/pages/device.inc.php +++ b/html/pages/device.inc.php @@ -210,6 +210,16 @@ if (device_permitted($vars['device']) || $check_device == $vars['device']) { $routing_tabs[] = 'vrf'; } + require_once "../includes/component.php"; + $COMPONENT = new component(); + $options['type'] = 'Cisco-OTV'; + $options['filter']['device_id'] = array('=',$device['device_id']); + $OTV = $COMPONENT->getComponents(null,$options); + $device_routing_count['cisco-otv'] = count($OTV); + if ($device_routing_count['cisco-otv'] > 0) { + $routing_tabs[] = 'cisco-otv'; + } + if (is_array($routing_tabs)) { echo '
  • diff --git a/html/pages/device/routing.inc.php b/html/pages/device/routing.inc.php index e4be54617..c58fe17a8 100644 --- a/html/pages/device/routing.inc.php +++ b/html/pages/device/routing.inc.php @@ -20,6 +20,7 @@ $type_text['bgp'] = 'BGP'; $type_text['cef'] = 'CEF'; $type_text['ospf'] = 'OSPF'; $type_text['vrf'] = 'VRFs'; +$type_text['cisco-otv'] = 'OTV'; print_optionbar_start(); diff --git a/html/pages/device/routing/cisco-otv.inc.php b/html/pages/device/routing/cisco-otv.inc.php new file mode 100644 index 000000000..f29a9c9ae --- /dev/null +++ b/html/pages/device/routing/cisco-otv.inc.php @@ -0,0 +1,94 @@ +getComponents($device['device_id'],$options); +$COMPONENTS = $COMPONENTS[$device['device_id']]; + +global $config; +?> +
    +
    +

    Overlay's & Adjacencies

    +
    +
    + $OVERLAY) { + if ($OVERLAY['otvtype'] == 'overlay') { + if ($OVERLAY['status'] == 1) { + $OVERLAY_STATUS = "Normal"; + $GLI = ""; + } + else { + $OVERLAY_STATUS = "".$OVERLAY['error']." - Alert"; + $GLI = "list-group-item-danger"; + } +?> + - + + +
    +
    + +
    +
    +

    AED Enabled VLAN's

    +
    +
    + +
    +
    + +
    +
    +

    MAC Addresses

    +
    +
    + +
    +
    diff --git a/html/pages/routing.inc.php b/html/pages/routing.inc.php index 0a7fcb335..848c655e2 100644 --- a/html/pages/routing.inc.php +++ b/html/pages/routing.inc.php @@ -16,6 +16,7 @@ $type_text['bgp'] = 'BGP'; $type_text['cef'] = 'CEF'; $type_text['ospf'] = 'OSPF'; $type_text['vrf'] = 'VRFs'; +$type_text['cisco-otv'] = 'OTV'; print_optionbar_start(); @@ -53,6 +54,7 @@ switch ($vars['protocol']) { case 'vrf': case 'cef': case 'ospf': + case 'cisco-otv': include 'pages/routing/'.$vars['protocol'].'.inc.php'; break; diff --git a/html/pages/routing/cisco-otv.inc.php b/html/pages/routing/cisco-otv.inc.php new file mode 100644 index 000000000..00ca33bdd --- /dev/null +++ b/html/pages/routing/cisco-otv.inc.php @@ -0,0 +1,58 @@ +getComponents(null,$options); + +foreach ($COMPONENTS as $DEVICE_ID => $COMP) { + $LINK = generate_url(array('page' => 'device', 'device' => $DEVICE_ID, 'tab' => 'routing', 'proto' => 'cisco-otv')); +?> +
    + +
    + $OVERLAY) { + if ($OVERLAY['otvtype'] == 'overlay') { + if ($OVERLAY['status'] == 1) { + $OVERLAY_STATUS = "Normal"; + $GLI = ""; + } + else { + $OVERLAY_STATUS = "".$OVERLAY['error']." - Alert"; + $GLI = "list-group-item-danger"; + } + ?> + - + + +
    +
    + + * + * 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') { + + // Define some error messages + $ERROR_VPN[0] = "Other"; + $ERROR_VPN[1] = "Configuration changed"; + $ERROR_VPN[2] = "Control Group information is unavailable"; + $ERROR_VPN[3] = "Data Group range information is unavailable"; + $ERROR_VPN[4] = "Join or Source interface information is unavailable"; + $ERROR_VPN[5] = "VPN name is unavailable"; + $ERROR_VPN[6] = "IP address is missing for Join Interface"; + $ERROR_VPN[7] = "Join Interface is down"; + $ERROR_VPN[8] = "Overlay is administratively shutdown"; + $ERROR_VPN[9] = "Overlay is in delete hold down phase"; + $ERROR_VPN[10] = "VPN is reinitializing"; + $ERROR_VPN[11] = "Site ID information is unavailable"; + $ERROR_VPN[12] = "Site ID mismatch has occurred"; + $ERROR_VPN[13] = "IP address is missing for Source Interface"; + $ERROR_VPN[14] = "Source interface is down"; + $ERROR_VPN[15] = "Changing site identifier"; + $ERROR_VPN[16] = "Changing control group"; + $ERROR_VPN[17] = "Device ID information is unavailable"; + $ERROR_VPN[18] = "Changing device ID"; + $ERROR_VPN[19] = "Cleanup in progress"; + + $ERROR_AED[0] = "Other"; + $ERROR_AED[1] = "Overlay is Down"; + $ERROR_AED[2] = "Site ID is not configured"; + $ERROR_AED[3] = "Site ID mismatch"; + $ERROR_AED[4] = "Version mismatch"; + $ERROR_AED[5] = "Site VLAN is Down"; + $ERROR_AED[6] = "No extended VLAN is operationally up"; + $ERROR_AED[7] = "No Overlay Adjacency is up"; + $ERROR_AED[8] = "LSPDB sync incomplete"; + $ERROR_AED[9] = "Overlay state down event in progress"; + $ERROR_AED[10] = "ISIS control group sync pending"; + + $ERROR_OVERLAY[1] = "active"; + $ERROR_OVERLAY[2] = "notInService"; + $ERROR_OVERLAY[3] = "notReady"; + $ERROR_OVERLAY[4] = "createAndGo"; + $ERROR_OVERLAY[5] = "createAndWait"; + $ERROR_OVERLAY[6] = "destroy"; + + $MODULE = 'Cisco-OTV'; + echo $MODULE.': '; + + 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. + $tblOTV = array(); + $tblEndpoints = array(); + + // Let's gather some data.. + $tblOverlayEntry = snmpwalk_array_num($device, '.1.3.6.1.4.1.9.9.810.1.2.1.1'); + $tblAdjacencyDatabaseEntry = snmpwalk_array_num($device, '.1.3.6.1.4.1.9.9.810.1.3.1.1', 0); + $tblAdjacentDevName = snmpwalk_array_num($device, '.1.3.6.1.4.1.9.9.810.1.3.1.1.4', 0); + + /* + * False == no object found - this is not an error, there is no QOS configured + * null == timeout or something else that caused an error, there may be QOS configured but we couldn't get it. + */ + if ( is_null($tblOverlayEntry) || is_null($tblAdjacencyDatabaseEntry) || is_null($tblAdjacentDevName) ) { + // We have to error here or we will end up deleting all our components. + echo "Error\n"; + } + else { + // No Error, lets process things. + + // Add each overlay to the array. + foreach ($tblOverlayEntry['1.3.6.1.4.1.9.9.810.1.2.1.1.2'] as $index => $name) { + $RESULT = array(); + $message = false; + $RESULT['index'] = $index; + $RESULT['label'] = $name; + if ($tblOverlayEntry['1.3.6.1.4.1.9.9.810.1.2.1.1.15'][$index] == 1) { + $RESULT['transport'] = 'Multicast'; + } + else { + $RESULT['transport'] = 'Unicast'; + } + $RESULT['otvtype'] = 'overlay'; + $RESULT['UID'] = $RESULT['otvtype']."-".$RESULT['index']; + $RESULT['vpn_state'] = $tblOverlayEntry['1.3.6.1.4.1.9.9.810.1.2.1.1.3'][$index]; + if ($RESULT['vpn_state'] != 2) { + $message .= "VPN Down: ".$ERROR_VPN[$tblOverlayEntry['1.3.6.1.4.1.9.9.810.1.2.1.1.4'][$index]]."\n"; + } + $RESULT['aed_state'] = $tblOverlayEntry['1.3.6.1.4.1.9.9.810.1.2.1.1.13'][$index]; + if ($RESULT['aed_state'] == 2) { + $message .= "AED Down: ".$ERROR_AED[$tblOverlayEntry['1.3.6.1.4.1.9.9.810.1.2.1.1.14'][$index]]."\n"; + } + $RESULT['overlay_state'] = $tblOverlayEntry['1.3.6.1.4.1.9.9.810.1.2.1.1.23'][$index]; + if ($RESULT['overlay_state'] == 2) { + $message .= "Overlay Down: ".$ERROR_OVERLAY[$tblOverlayEntry['1.3.6.1.4.1.9.9.810.1.2.1.1.24'][$index]]."\n"; + } + + // If we have set a message, we have an error, activate alert. + if ($message !== false) { + $RESULT['error'] = $message; + $RESULT['status'] = 0; + } + else { + $RESULT['error'] = ""; + $RESULT['status'] = 1; + } + + // Add the result to the parent array. + $tblOTV[] = $RESULT; + } + + // Add each adjacency to the array. + foreach ($tblAdjacentDevName as $key => $value) { + preg_match('/^1.3.6.1.4.1.9.9.810.1.3.1.1.4.(\d+).1.4.(\d+.\d+.\d+.\d+)$/', $key, $MATCHES); + $RESULT = array(); + $RESULT['index'] = $MATCHES[1]; + $RESULT['endpoint'] = $MATCHES[2]; + $tblEndpoints[$value] = true; + $RESULT['otvtype'] = 'adjacency'; + $RESULT['UID'] = $RESULT['otvtype']."-".$RESULT['index']."-".str_replace(' ', '', $tblAdjacencyDatabaseEntry['1.3.6.1.4.1.9.9.810.1.3.1.1.3.'.$RESULT['index'].'.1.4.'.$RESULT['endpoint']]); + $RESULT['uptime'] = $tblAdjacencyDatabaseEntry['1.3.6.1.4.1.9.9.810.1.3.1.1.6.'.$RESULT['index'].'.1.4.'.$RESULT['endpoint']]; + $message = false; + if ($tblAdjacencyDatabaseEntry['1.3.6.1.4.1.9.9.810.1.3.1.1.5.'.$RESULT['index'].'.1.4.'.$RESULT['endpoint']] != 1) { + $message .= "Adjacency is Down\n"; + } + + // If we have set a message, we have an error, activate alert. + if ($message !== false) { + $RESULT['error'] = $message; + $RESULT['status'] = 0; + } + else { + $RESULT['error'] = ""; + $RESULT['status'] = 1; + } + + // Set a default name, if for some unknown reason we cant find the parent VPN. + $RESULT['label'] = "Unknown (".$RESULT['index'].") - ".$value; + // We need to search the existing array to build the name + foreach ($tblOTV as $ITEM) { + if (($ITEM['otvtype'] == 'overlay') && ($ITEM['index'] == $RESULT['index'])) { + $RESULT['label'] = $ITEM['label']." - ".$value; + } + } + + // Add the result to the parent array. + $tblOTV[] = $RESULT; + } + + // We retain a list of all endpoints to tie the RRD to. + foreach ($tblEndpoints as $K => $V) { + $RESULT['label'] = "Endpoint: ".$K; + $RESULT['otvtype'] = 'endpoint'; + $RESULT['endpoint'] = $K; + $RESULT['UID'] = $RESULT['otvtype']."-".$K; + + // Add the result to the parent array. + $tblOTV[] = $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 ($tblOTV 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 ($tblOTV 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 + +} diff --git a/includes/polling/cisco-otv.inc.php b/includes/polling/cisco-otv.inc.php new file mode 100644 index 000000000..47839fa31 --- /dev/null +++ b/includes/polling/cisco-otv.inc.php @@ -0,0 +1,181 @@ + + * + * 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") { + + // Define some error messages + $ERROR_VPN[0] = "Other"; + $ERROR_VPN[1] = "Configuration changed"; + $ERROR_VPN[2] = "Control Group information is unavailable"; + $ERROR_VPN[3] = "Data Group range information is unavailable"; + $ERROR_VPN[4] = "Join or Source interface information is unavailable"; + $ERROR_VPN[5] = "VPN name is unavailable"; + $ERROR_VPN[6] = "IP address is missing for Join Interface"; + $ERROR_VPN[7] = "Join Interface is down"; + $ERROR_VPN[8] = "Overlay is administratively shutdown"; + $ERROR_VPN[9] = "Overlay is in delete hold down phase"; + $ERROR_VPN[10] = "VPN is reinitializing"; + $ERROR_VPN[11] = "Site ID information is unavailable"; + $ERROR_VPN[12] = "Site ID mismatch has occurred"; + $ERROR_VPN[13] = "IP address is missing for Source Interface"; + $ERROR_VPN[14] = "Source interface is down"; + $ERROR_VPN[15] = "Changing site identifier"; + $ERROR_VPN[16] = "Changing control group"; + $ERROR_VPN[17] = "Device ID information is unavailable"; + $ERROR_VPN[18] = "Changing device ID"; + $ERROR_VPN[19] = "Cleanup in progress"; + + $ERROR_AED[0] = "Other"; + $ERROR_AED[1] = "Overlay is Down"; + $ERROR_AED[2] = "Site ID is not configured"; + $ERROR_AED[3] = "Site ID mismatch"; + $ERROR_AED[4] = "Version mismatch"; + $ERROR_AED[5] = "Site VLAN is Down"; + $ERROR_AED[6] = "No extended VLAN is operationally up"; + $ERROR_AED[7] = "No Overlay Adjacency is up"; + $ERROR_AED[8] = "LSPDB sync incomplete"; + $ERROR_AED[9] = "Overlay state down event in progress"; + $ERROR_AED[10] = "ISIS control group sync pending"; + + $ERROR_OVERLAY[1] = "active"; + $ERROR_OVERLAY[2] = "notInService"; + $ERROR_OVERLAY[3] = "notReady"; + $ERROR_OVERLAY[4] = "createAndGo"; + $ERROR_OVERLAY[5] = "createAndWait"; + $ERROR_OVERLAY[6] = "destroy"; + + $MODULE = 'Cisco-OTV'; + + require_once 'includes/component.php'; + $COMPONENT = new component(); + $options['filter']['type'] = array('=',$MODULE); + $options['filter']['disabled'] = 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.. + $tblOverlayEntry = snmpwalk_array_num($device, '.1.3.6.1.4.1.9.9.810.1.2.1.1'); + $tblAdjacencyDatabaseEntry = snmpwalk_array_num($device, '.1.3.6.1.4.1.9.9.810.1.3.1.1', 0); + $tblRouteNextHopAddr = snmpwalk_array_num($device, '.1.3.6.1.4.1.9.9.810.1.5.1.1.8', 0); + $tblVlanEdgeDevIsAed = snmpwalk_array_num($device, '.1.3.6.1.4.1.9.9.810.1.2.2.1.6', 2); + + // Let's create an array of each remote OTV endpoint and the count of MAC addresses that are reachable via. + $COUNT_MAC = array(); + foreach ($tblRouteNextHopAddr as $k => $v) { + $COUNT_MAC[$v]++; + } + + // Loop through the components and extract the data. + foreach ($COMPONENTS as $KEY => &$ARRAY) { + + if ($ARRAY['otvtype'] == 'overlay') { + // Let's check the varius status' of the overlay + $message = false; + $vpn_state = $tblOverlayEntry['1.3.6.1.4.1.9.9.810.1.2.1.1.3'][$ARRAY['index']]; + if ($vpn_state != 2) { + $message .= "VPN Down: ".$ERROR_VPN[$tblOverlayEntry['1.3.6.1.4.1.9.9.810.1.2.1.1.4'][$ARRAY['index']]]; + } + $aed_state = $tblOverlayEntry['1.3.6.1.4.1.9.9.810.1.2.1.1.13'][$ARRAY['index']]; + if ($aed_state == 2) { + $message .= "AED Down: ".$ERROR_AED[$tblOverlayEntry['1.3.6.1.4.1.9.9.810.1.2.1.1.14'][$ARRAY['index']]]; + } + $overlay_state = $tblOverlayEntry['1.3.6.1.4.1.9.9.810.1.2.1.1.23'][$ARRAY['index']]; + if ($overlay_state == 2) { + $message .= "Overlay Down: ".$ERROR_OVERLAY[$tblOverlayEntry['1.3.6.1.4.1.9.9.810.1.2.1.1.24'][$ARRAY['index']]]; + } + + // If we have set a message, we have an error, activate alert. + if ($message !== false) { + $ARRAY['error'] = $message; + $ARRAY['status'] = 0; + } + else { + $ARRAY['error'] = ""; + $ARRAY['status'] = 1; + } + + // Time to graph the count of the active VLAN's on this overlay. + $COUNT_VLAN = 0; + foreach ($tblVlanEdgeDevIsAed['1.3.6.1.4.1.9.9.810.1.2.2.1.6'][$ARRAY['index']] as $v) { + if ($v == 1) { + $COUNT_VLAN++; + } + } + + $filename = "cisco-otv-".$ARRAY['label']."-vlan.rrd"; + $rrd_filename = $config['rrd_dir'] . "/" . $device['hostname'] . "/" . safename ($filename); + + if (!file_exists ($rrd_filename)) { + rrdtool_create ($rrd_filename, " DS:count:GAUGE:600:0:U" . $config['rrd_rra']); + } + $RRD['count'] = $COUNT_VLAN; + + // Update RRD + rrdtool_update ($rrd_filename, $RRD); + + } + elseif ($ARRAY['otvtype'] == 'adjacency') { + $ARRAY['uptime'] = $tblAdjacencyDatabaseEntry['1.3.6.1.4.1.9.9.810.1.3.1.1.6.'.$ARRAY['index'].'.1.4.'.$ARRAY['endpoint']]; + $message = false; + if ($tblAdjacencyDatabaseEntry['1.3.6.1.4.1.9.9.810.1.3.1.1.5.'.$ARRAY['index'].'.1.4.'.$ARRAY['endpoint']] != 1) { + $message .= "Adjacency is Down\n"; + } + if ($tblAdjacencyDatabaseEntry['1.3.6.1.4.1.9.9.810.1.3.1.1.6.'.$ARRAY['index'].'.1.4.'.$ARRAY['endpoint']] < $ARRAY['uptime']) { + $message .= "Adjacency has been reset\n"; + } + + // If we have set a message, we have an error, activate alert. + if ($message !== false) { + $ARRAY['error'] = $message; + $ARRAY['status'] = 0; + } + else { + $ARRAY['error'] = ""; + $ARRAY['status'] = 1; + } + } + elseif ($ARRAY['otvtype'] == 'endpoint') { + if (isset($COUNT_MAC[$ARRAY['endpoint']])) { + $RRD['count'] = $COUNT_MAC[$ARRAY['endpoint']]; + } + else { + $RRD['count'] = "0"; + } + + $filename = "cisco-otv-".$ARRAY['endpoint']."-mac.rrd"; + $rrd_filename = $config['rrd_dir'] . "/" . $device['hostname'] . "/" . safename ($filename); + + if (!file_exists ($rrd_filename)) { + rrdtool_create ($rrd_filename, " DS:count:GAUGE:600:0:U" . $config['rrd_rra']); + } + + // Update RRD + rrdtool_update ($rrd_filename, $RRD); + + } // End If + + } // End foreach components + + // Write the Components back to the DB. + $COMPONENT->setComponentPrefs($device['device_id'],$COMPONENTS); + + echo $MODULE." "; + } // end if count components + + // Clean-up after yourself! + unset($COMPONENTS, $COMPONENT, $MODULE); +} \ No newline at end of file diff --git a/includes/snmp.inc.php b/includes/snmp.inc.php index e2d4bac01..cee0032cc 100644 --- a/includes/snmp.inc.php +++ b/includes/snmp.inc.php @@ -1268,4 +1268,70 @@ function register_mibs($device, $mibs, $included_by) } echo "\n"; + } // register_mibs + +/** + * SNMPWalk_array_num - performs a numeric SNMPWalk and returns an array containing $count indexes + * One Index: + * From: 1.3.6.1.4.1.9.9.166.1.15.1.1.27.18.655360 = 0 + * To: $array['1.3.6.1.4.1.9.9.166.1.15.1.1.27.18']['655360'] = 0 + * Two Indexes: + * From: 1.3.6.1.4.1.9.9.166.1.15.1.1.27.18.655360 = 0 + * To: $array['1.3.6.1.4.1.9.9.166.1.15.1.1.27']['18']['655360'] = 0 + * And so on... + * Think snmpwalk_cache_*_oid but for numeric data. + * + * Why is this useful? + * Some SNMP data contains a single index (eg. ifIndex in IF-MIB) and some is dual indexed + * (eg. PolicyIndex/ObjectsIndex in CISCO-CLASS-BASED-QOS-MIB). + * The resulting array allows us to easily access the top level index we want and iterate over the data from there. + * + * @param $device + * @param $OID + * @param int $indexes + * @internal param $string + * @return array + */ +function snmpwalk_array_num($device,$OID,$indexes=1) { + $array = array(); + $string = snmp_walk($device, $OID, '-Osqn'); + + if ( $string === false) { + // False means: No Such Object. + return false; + } + if ($string == "") { + // Empty means SNMP timeout or some such. + return null; + } + + // Let's turn the string into something we can work with. + foreach (explode("\n", $string) as $line) { + if ($line[0] == '.') { + // strip the leading . if it exists. + $line = substr($line,1); + } + list($key, $value) = explode(' ', $line, 2); + $prop_id = explode('.', $key); + $value = trim($value); + + // if we have requested more levels that exist, set to the max. + if ($indexes > count($prop_id)) { + $indexes = count($prop_id)-1; + } + + for ($i=0;$i<$indexes;$i++) { + // Pop the index off. + $index = array_pop($prop_id); + $value = array($index => $value); + } + + // Rebuild our key + $key = implode('.',$prop_id); + + // Add the entry to the master array + $array = array_replace_recursive($array,array($key => $value)); + } + return $array; +} From d96e2216a7137a21f4231ee456b4219458035903 Mon Sep 17 00:00:00 2001 From: Aaron Daniels Date: Thu, 28 Jan 2016 07:04:12 +1000 Subject: [PATCH 02/19] - Changed upper case variables to lower case. --- .../graphs/device/cisco-otv-mac.inc.php | 38 ++-- .../graphs/device/cisco-otv-vlan.inc.php | 38 ++-- html/includes/print-menubar.php | 6 +- html/pages/device.inc.php | 6 +- html/pages/device/routing/cisco-otv.inc.php | 40 ++-- includes/discovery/cisco-otv.inc.php | 205 +++++++++--------- includes/polling/cisco-otv.inc.php | 163 +++++++------- includes/snmp.inc.php | 4 +- 8 files changed, 253 insertions(+), 247 deletions(-) diff --git a/html/includes/graphs/device/cisco-otv-mac.inc.php b/html/includes/graphs/device/cisco-otv-mac.inc.php index 5c616869e..691bfd10d 100644 --- a/html/includes/graphs/device/cisco-otv-mac.inc.php +++ b/html/includes/graphs/device/cisco-otv-mac.inc.php @@ -12,44 +12,44 @@ */ require_once "../includes/component.php"; -$COMPONENT = new component(); +$component = new component(); $options['filter']['type'] = array('=','Cisco-OTV'); -$COMPONENTS = $COMPONENT->getComponents($device['device_id'],$options); +$components = $component->getComponents($device['device_id'],$options); // We only care about our device id. -$COMPONENTS = $COMPONENTS[$device['device_id']]; +$components = $components[$device['device_id']]; include "includes/graphs/common.inc.php"; $rrd_options .= " -l 0 -E "; $rrd_options .= " COMMENT:'MAC Addresses Now Min Max\\n'"; $rrd_additions = ""; -$COUNT = 0; -foreach ($COMPONENTS as $ID => $ARRAY) { - if ($ARRAY['otvtype'] == 'endpoint') { - $rrd_filename = $config['rrd_dir'].'/'.$device['hostname'].'/'.safename("cisco-otv-".$ARRAY['endpoint']."-mac.rrd"); +$count = 0; +foreach ($components as $id => $array) { + if ($array['otvtype'] == 'endpoint') { + $rrd_filename = $config['rrd_dir'].'/'.$device['hostname'].'/'.safename("cisco-otv-".$array['endpoint']."-mac.rrd"); if (file_exists($rrd_filename)) { // Stack the area on the second and subsequent DS's - $STACK = ""; - if ($COUNT != 0) { - $STACK = ":STACK "; + $stack = ""; + if ($count != 0) { + $stack = ":STACK "; } // Grab a color from the array. - if ( isset($config['graph_colours']['mixed'][$COUNT]) ) { - $COLOR = $config['graph_colours']['mixed'][$COUNT]; + if ( isset($config['graph_colours']['mixed'][$count]) ) { + $color = $config['graph_colours']['mixed'][$count]; } else { - $COLOR = $config['graph_colours']['oranges'][$COUNT-7]; + $color = $config['graph_colours']['oranges'][$count-7]; } - $rrd_additions .= " DEF:DS" . $COUNT . "=" . $rrd_filename . ":count:AVERAGE "; - $rrd_additions .= " AREA:DS" . $COUNT . "#" . $COLOR . ":'" . str_pad(substr($COMPONENTS[$ID]['endpoint'],0,15),15) . "'" . $STACK; - $rrd_additions .= " GPRINT:DS" . $COUNT . ":LAST:%4.0lf%s "; - $rrd_additions .= " GPRINT:DS" . $COUNT . ":MIN:%4.0lf%s "; - $rrd_additions .= " GPRINT:DS" . $COUNT . ":MAX:%4.0lf%s\\\l "; - $COUNT++; + $rrd_additions .= " DEF:DS" . $count . "=" . $rrd_filename . ":count:AVERAGE "; + $rrd_additions .= " AREA:DS" . $count . "#" . $color . ":'" . str_pad(substr($components[$id]['endpoint'],0,15),15) . "'" . $stack; + $rrd_additions .= " GPRINT:DS" . $count . ":LAST:%4.0lf%s "; + $rrd_additions .= " GPRINT:DS" . $count . ":MIN:%4.0lf%s "; + $rrd_additions .= " GPRINT:DS" . $count . ":MAX:%4.0lf%s\\\l "; + $count++; } } } diff --git a/html/includes/graphs/device/cisco-otv-vlan.inc.php b/html/includes/graphs/device/cisco-otv-vlan.inc.php index 8ee50acf4..1116e056c 100644 --- a/html/includes/graphs/device/cisco-otv-vlan.inc.php +++ b/html/includes/graphs/device/cisco-otv-vlan.inc.php @@ -12,44 +12,44 @@ */ require_once "../includes/component.php"; -$COMPONENT = new component(); +$component = new component(); $options['filter']['type'] = array('=','Cisco-OTV'); -$COMPONENTS = $COMPONENT->getComponents($device['device_id'],$options); +$components = $component->getComponents($device['device_id'],$options); // We only care about our device id. -$COMPONENTS = $COMPONENTS[$device['device_id']]; +$components = $components[$device['device_id']]; include "includes/graphs/common.inc.php"; $rrd_options .= " -l 0 -E "; $rrd_options .= " COMMENT:'VLANs Now Min Max\\n'"; $rrd_additions = ""; -$COUNT = 0; -foreach ($COMPONENTS as $ID => $ARRAY) { - if ($ARRAY['otvtype'] == 'overlay') { - $rrd_filename = $config['rrd_dir'].'/'.$device['hostname'].'/'.safename("cisco-otv-".$ARRAY['label']."-vlan.rrd"); +$count = 0; +foreach ($components as $id => $array) { + if ($array['otvtype'] == 'overlay') { + $rrd_filename = $config['rrd_dir'].'/'.$device['hostname'].'/'.safename("cisco-otv-".$array['label']."-vlan.rrd"); if (file_exists($rrd_filename)) { // Stack the area on the second and subsequent DS's - $STACK = ""; - if ($COUNT != 0) { - $STACK = ":STACK "; + $stack = ""; + if ($count != 0) { + $stack = ":STACK "; } // Grab a color from the array. - if ( isset($config['graph_colours']['mixed'][$COUNT]) ) { - $COLOR = $config['graph_colours']['mixed'][$COUNT]; + if ( isset($config['graph_colours']['mixed'][$count]) ) { + $color = $config['graph_colours']['mixed'][$count]; } else { - $COLOR = $config['graph_colours']['oranges'][$COUNT-7]; + $color = $config['graph_colours']['oranges'][$count-7]; } - $rrd_additions .= " DEF:DS" . $COUNT . "=" . $rrd_filename . ":count:AVERAGE "; - $rrd_additions .= " AREA:DS" . $COUNT . "#" . $COLOR . ":'" . str_pad(substr($COMPONENTS[$ID]['label'],0,15),15) . "'" . $STACK; - $rrd_additions .= " GPRINT:DS" . $COUNT . ":LAST:%4.0lf%s "; - $rrd_additions .= " GPRINT:DS" . $COUNT . ":MIN:%4.0lf%s "; - $rrd_additions .= " GPRINT:DS" . $COUNT . ":MAX:%4.0lf%s\\\l "; - $COUNT++; + $rrd_additions .= " DEF:DS" . $count . "=" . $rrd_filename . ":count:AVERAGE "; + $rrd_additions .= " AREA:DS" . $count . "#" . $color . ":'" . str_pad(substr($components[$id]['label'],0,15),15) . "'" . $stack; + $rrd_additions .= " GPRINT:DS" . $count . ":LAST:%4.0lf%s "; + $rrd_additions .= " GPRINT:DS" . $count . ":MIN:%4.0lf%s "; + $rrd_additions .= " GPRINT:DS" . $count . ":MAX:%4.0lf%s\\\l "; + $count++; } } } diff --git a/html/includes/print-menubar.php b/html/includes/print-menubar.php index 859af924f..4c22ad08b 100644 --- a/html/includes/print-menubar.php +++ b/html/includes/print-menubar.php @@ -421,10 +421,10 @@ $routing_count['cef'] = dbFetchCell("SELECT COUNT(cef_switching_id) from `cef_s $routing_count['vrf'] = dbFetchCell("SELECT COUNT(vrf_id) from `vrfs`"); require_once "../includes/component.php"; -$COMPONENT = new component(); +$component = new component(); $options['type'] = 'Cisco-OTV'; -$OTV = $COMPONENT->getComponents(null,$options); -$routing_count['cisco-otv'] = count($OTV); +$otv = $component->getComponents(null,$options); +$routing_count['cisco-otv'] = count($otv); if ($_SESSION['userlevel'] >= '5' && ($routing_count['bgp']+$routing_count['ospf']+$routing_count['cef']+$routing_count['vrf']+$routing_count['cisco-otv']) > "0") { diff --git a/html/pages/device.inc.php b/html/pages/device.inc.php index 3de92da54..fd5900401 100644 --- a/html/pages/device.inc.php +++ b/html/pages/device.inc.php @@ -211,11 +211,11 @@ if (device_permitted($vars['device']) || $check_device == $vars['device']) { } require_once "../includes/component.php"; - $COMPONENT = new component(); + $component = new component(); $options['type'] = 'Cisco-OTV'; $options['filter']['device_id'] = array('=',$device['device_id']); - $OTV = $COMPONENT->getComponents(null,$options); - $device_routing_count['cisco-otv'] = count($OTV); + $otv = $component->getComponents(null,$options); + $device_routing_count['cisco-otv'] = count($otv); if ($device_routing_count['cisco-otv'] > 0) { $routing_tabs[] = 'cisco-otv'; } diff --git a/html/pages/device/routing/cisco-otv.inc.php b/html/pages/device/routing/cisco-otv.inc.php index f29a9c9ae..602f67abd 100644 --- a/html/pages/device/routing/cisco-otv.inc.php +++ b/html/pages/device/routing/cisco-otv.inc.php @@ -1,12 +1,12 @@ getComponents($device['device_id'],$options); -$COMPONENTS = $COMPONENTS[$device['device_id']]; +$components = $component->getComponents($device['device_id'],$options); +$components = $components[$device['device_id']]; global $config; ?> @@ -17,32 +17,32 @@ global $config;
    $OVERLAY) { - if ($OVERLAY['otvtype'] == 'overlay') { - if ($OVERLAY['status'] == 1) { - $OVERLAY_STATUS = "Normal"; - $GLI = ""; +foreach ($components as $oid => $overlay) { + if ($overlay['otvtype'] == 'overlay') { + if ($overlay['status'] == 1) { + $overlay_status = "Normal"; + $gli = ""; } else { - $OVERLAY_STATUS = "".$OVERLAY['error']." - Alert"; - $GLI = "list-group-item-danger"; + $overlay_status = "".$overlay['error']." - Alert"; + $gli = "list-group-item-danger"; } ?> - - -
  • https
  • -
  • ssh
  • -
  • telnet
  • '; - - if ($_SESSION['userlevel'] >= '7') { - echo '
  • + echo ''; echo ''; + }//end if if (device_permitted($device['device_id']) || $check_device == $vars['device']) { From 9cd082044525498d51a20139306b28f3b298ef92 Mon Sep 17 00:00:00 2001 From: Arjit Chaudhary Date: Mon, 8 Feb 2016 22:55:18 +0530 Subject: [PATCH 05/19] use bootstraps own pull-right so that the dropdown draws inside the page width --- html/pages/device.inc.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/html/pages/device.inc.php b/html/pages/device.inc.php index 2d6b4db36..b7583ed67 100644 --- a/html/pages/device.inc.php +++ b/html/pages/device.inc.php @@ -388,7 +388,7 @@ if (device_permitted($vars['device']) || $check_device == $vars['device']) { } - echo '