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; +}