* * 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. */ $comp_module = 'Cisco-CIMC'; $component = new LibreNMS\Component(); $components = $component->getComponents($device['device_id'], array('type'=>$comp_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. $tblCIMC = array(); // Let's gather some data.. $tblUCSObjects = snmpwalk_array_num($device, '.1.3.6.1.4.1.9.9.719.1', 2); /* * False == no object found - this is not an error, there is no QOS configured * null == timeout or something else that caused an error, the OID's may be present but we couldn't get them. */ if (is_null($tblUCSObjects)) { // We have to error here or we will end up deleting all our components. } else { // No Error, lets process things. echo("CIMC Hardware Found: "); // Make sure we have an array before we try to iterate over it if (is_array($tblUCSObjects)) { // Gather entPhysical data $entmax = 0; $entphysical = array(); $dbentphysical = $entries = dbFetchRows('SELECT * FROM entPhysical WHERE device_id=?', array($device['device_id'])); foreach ($dbentphysical as $array) { $entphysical[$array['entPhysicalVendorType']] = $array; if ($array['entPhysicalIndex'] > $entmax) { $entmax = $array['entPhysicalIndex']; } } // Let's extract any active faults, we will use them later. $faults = array(); foreach ($tblUCSObjects['1.3.6.1.4.1.9.9.719.1.1.1.1'][5] as $fid => $fobj) { $fobj = preg_replace('/^\/?sys\//', '', $fobj); $faults[$fobj] = $tblUCSObjects['1.3.6.1.4.1.9.9.719.1.1.1.1'][3][$fid] ." - ". $tblUCSObjects['1.3.6.1.4.1.9.9.719.1.1.1.1'][11][$fid]; } // Unset the faults and stats array so it isn't reported as an error later. unset( $tblUCSObjects['1.3.6.1.4.1.9.9.719.1.1.1.1'], $tblUCSObjects['1.3.6.1.4.1.9.9.719.1.9.14.1'], $tblUCSObjects['1.3.6.1.4.1.9.9.719.1.9.44.1'], $tblUCSObjects['1.3.6.1.4.1.9.9.719.1.30.12.1'], $tblUCSObjects['1.3.6.1.4.1.9.9.719.1.41.2.1'], $tblUCSObjects['1.3.6.1.4.1.9.9.719.1.45.36.1'] ); foreach ($tblUCSObjects as $tbl => $array) { // Remove the leading /sys/ foreach ($array[2] as &$label) { $label = preg_replace('/^\/?sys\//', '', $label); } // Lets Set some defaults. $entPhysicalData = array( 'entPhysicalHardwareRev' => '', 'entPhysicalFirmwareRev' => '', 'entPhysicalSoftwareRev' => '', 'entPhysicalIsFRU' => 'FALSE', ); switch ($tbl) { // Chassis - rack-unit-1 case "1.3.6.1.4.1.9.9.719.1.9.35.1": foreach ($array[3] as $key => $item) { $result = array(); $result['hwtype'] = 'chassis'; $result['id'] = $array[27][$key]; $result['label'] = $array[2][$key]; $result['serial'] = $array[47][$key]; $result['string'] = $array[32][$key] ." - ". ($array[49][$key]/1024) ."G Mem, ". $array[36][$key] ." CPU, ". $array[35][$key] ." core"; $result['statusoid'] = '1.3.6.1.4.1.9.9.719.1.9.35.1.43.'.$key; // What is the Operability, 1 is good, everything else is bad. if ($array[43][$key] != 1) { // Yes, report an error $result['status'] = 2; $result['error'] = "Error Operability Code: ".$array[43][$key]."\n"; } else { // No, unset any errors that may exist. $result['status'] = 0; $result['error'] = ''; } // See if there are any errors on this chassis. foreach ($faults as $id => $value) { if (strpos($id, $result['label']) !== false) { // The fault is on this chassis. $result['status'] = 2; $result['error'] .= $value."\n"; } } // Add the ent Physical entry $entPhysicalData['entPhysicalClass'] = 'chassis'; $entPhysicalData['entPhysicalModelName'] = $array[32][$key]; $entPhysicalData['entPhysicalName'] = 'Chassis'; $entPhysicalData['entPhysicalDescr'] = $result['string']; $entPhysicalData['entPhysicalSerialNum'] = $array[47][$key]; list($result['entPhysical'],$entPhysicalData['entPhysicalIndex']) = setCIMCentPhysical($result['label'], $entPhysicalData, $entphysical, $entmax); $valid[$entPhysicalData['entPhysicalIndex']] = 1; // Add the result to the array. d_echo("Chassis (".$tbl."): ".print_r($result, true)."\n"); $tblCIMC[] = $result; } break; // System Board - rack-unit-1/board case "1.3.6.1.4.1.9.9.719.1.9.6.1": foreach ($array[3] as $key => $item) { $result = array(); $result['hwtype'] = 'board'; $result['id'] = $array[5][$key]; $result['label'] = $array[2][$key]; $result['serial'] = $array[14][$key]; $result['string'] = $array[6][$key]; $result['statusoid'] = '1.3.6.1.4.1.9.9.719.1.9.6.1.9.'.$key; // What is the Operability, 1 is good, everything else is bad. if ($array[9][$key] != 1) { // Yes, report an error $result['status'] = 2; $result['error'] = "Error Operability Code: ".$array[9][$key]; } else { // No, unset any errors that may exist. $result['status'] = 0; $result['error'] = ''; } // Add the ent Physical entry $entPhysicalData['entPhysicalClass'] = 'backplane'; $entPhysicalData['entPhysicalName'] = 'System Board'; $entPhysicalData['entPhysicalDescr'] = $result['string']; $entPhysicalData['entPhysicalSerialNum'] = $array[14][$key]; list($result['entPhysical'],$entPhysicalData['entPhysicalIndex']) = setCIMCentPhysical($result['label'], $entPhysicalData, $entphysical, $entmax); $valid[$entPhysicalData['entPhysicalIndex']] = 1; // Add the result to the array. d_echo("System Board (".$tbl."): ".print_r($result, true)."\n"); $tblCIMC[] = $result; } break; // Memory Modules - rack-unit-1/board/memarray-1/mem-0 case "1.3.6.1.4.1.9.9.719.1.30.11.1": foreach ($array[3] as $key => $item) { $result = array(); // If there is no memory module present, continue. if ($array[17][$key] != 10) { continue; } $result['hwtype'] = 'memory'; $result['id'] = substr($array[3][$key], 4); $result['label'] = $array[2][$key]; $result['serial'] = $array[19][$key]; $result['string'] = $array[11][$key] ." - ". ($array[6][$key]/1024) ."G, ". $array[27][$key] ." Bit, ". $array[7][$key] ." Mhz, ". $array[21][$key] ." MT/s"; $result['statusoid'] = '1.3.6.1.4.1.9.9.719.1.30.11.1.14.'.$key; // What is the Operability, 1 is good, everything else is bad. if ($array[14][$key] != 1) { // Yes, report an error $result['status'] = 2; $result['error'] = "Error Operability Code: ".$array[14][$key]; } else { // No, unset any errors that may exist. $result['status'] = 0; $result['error'] = ''; } // Add the ent Physical entry $entPhysicalData['entPhysicalClass'] = 'module'; $entPhysicalData['entPhysicalModelName'] = $array[11][$key]; $entPhysicalData['entPhysicalName'] = 'Memory'; $entPhysicalData['entPhysicalDescr'] = $result['string']; $entPhysicalData['entPhysicalSerialNum'] = $array[19][$key]; list($result['entPhysical'],$entPhysicalData['entPhysicalIndex']) = setCIMCentPhysical($result['label'], $entPhysicalData, $entphysical, $entmax); $valid[$entPhysicalData['entPhysicalIndex']] = 1; // Add the result to the array. d_echo("Memory (".$tbl."): ".print_r($result, true)."\n"); $tblCIMC[] = $result; } break; // CPU's - rack-unit-1/board/cpu-1 case "1.3.6.1.4.1.9.9.719.1.41.9.1": foreach ($array[3] as $key => $item) { $result = array(); // If there is no cpu present, continue. if ($array[13][$key] != 10) { continue; } $result['hwtype'] = 'cpu'; $result['id'] = substr($array[3][$key], 4); $result['label'] = $array[2][$key]; $result['serial'] = $array[15][$key]; $result['string'] = $array[8][$key] ." - ". $array[5][$key] ." Cores, ". $array[20][$key] ." Threads"; $result['statusoid'] = '1.3.6.1.4.1.9.9.719.1.41.9.1.10.'.$key; // What is the Operability, 1 is good, everything else is bad. if ($array[10][$key] != 1) { // Yes, report an error $result['status'] = 2; $result['error'] = "Error Operability Code: ".$array[10][$key]; } else { // No, unset any errors that may exist. $result['status'] = 0; $result['error'] = ''; } // Add the ent Physical entry $entPhysicalData['entPhysicalClass'] = 'cpu'; $entPhysicalData['entPhysicalModelName'] = $array[8][$key]; $entPhysicalData['entPhysicalName'] = 'Processor'; $entPhysicalData['entPhysicalDescr'] = $result['string']; $entPhysicalData['entPhysicalSerialNum'] = $array[15][$key]; list($result['entPhysical'],$entPhysicalData['entPhysicalIndex']) = setCIMCentPhysical($result['label'], $entPhysicalData, $entphysical, $entmax); $valid[$entPhysicalData['entPhysicalIndex']] = 1; // Add the result to the array. d_echo("CPU (".$tbl."): ".print_r($result, true)."\n"); $tblCIMC[] = $result; } break; // SAS Storage Module - rack-unit-1/board/storage-SAS-2 case "1.3.6.1.4.1.9.9.719.1.45.1.1": foreach ($array[3] as $key => $item) { $result = array(); $result['hwtype'] = 'sas-controller'; $result['id'] = substr($array[3][$key], 12); $result['label'] = $array[2][$key]; $result['serial'] = $array[14][$key]; $result['string'] = $array[5][$key] ." - Rev: ". $array[13][$key] .", ". $array[9][$key] .", RAID Types: ". $array[19][$key]; $result['statusoid'] = '1.3.6.1.4.1.9.9.719.1.45.1.1.7.'.$key; // What is the Operability, 1 is good, everything else is bad. if ($array[7][$key] != 1) { // Yes, report an error $result['status'] = 2; $result['error'] = "Error Operability Code: ".$array[7][$key]; } else { // No, unset any errors that may exist. $result['status'] = 0; $result['error'] = ''; } // Add the ent Physical entry $entPhysicalData['entPhysicalClass'] = 'module'; $entPhysicalData['entPhysicalModelName'] = $array[5][$key]; $entPhysicalData['entPhysicalName'] = 'Storage Module'; $entPhysicalData['entPhysicalDescr'] = $result['string']; $entPhysicalData['entPhysicalSerialNum'] = $array[14][$key]; list($result['entPhysical'],$entPhysicalData['entPhysicalIndex']) = setCIMCentPhysical($result['label'], $entPhysicalData, $entphysical, $entmax); $valid[$entPhysicalData['entPhysicalIndex']] = 1; // Add the result to the array. d_echo("SAS Module (".$tbl."): ".print_r($result, true)."\n"); $tblCIMC[] = $result; } break; // SAS Disks - rack-unit-1/board/storage-SAS-2/disk-1 case "1.3.6.1.4.1.9.9.719.1.45.4.1": foreach ($array[3] as $key => $item) { $result = array(); $result['hwtype'] = 'sas-disk'; $result['id'] = substr($array[3][$key], 5); $result['label'] = $array[2][$key]; $result['serial'] = $array[12][$key]; $result['statusoid'] = '1.3.6.1.4.1.9.9.719.1.45.4.1.9.'.$key; // Old Firmware returns 4294967296 as 1 MB. // The if below assumes we will never have < 1 Gb on old firmware or > 4 Pb on new firmware if (($array[13][$key]) > 4294967296000) { // Old Firmware $result['string'] = $array[14][$key] ." ". $array[7][$key] .", Rev: ". $array[11][$key] .", Size: ". round($array[13][$key]/4294967296000, 2) ." GB"; d_echo("Disk: ".$array[2][$key].", Raw Size: ".$array[13][$key].", converted (old FW): ".round($array[13][$key]/4294967296000, 2)."GB\n"); } else { // New Firmware $result['string'] = $array[14][$key] ." ". $array[7][$key] .", Rev: ". $array[11][$key] .", Size: ". round($array[13][$key]/1000, 2) ." GB"; d_echo("Disk: ".$array[2][$key].", Raw Size: ".$array[13][$key].", converted (New FW): ".round($array[13][$key]/1000, 2)."GB\n"); } // What is the Operability, 1 is good, everything else is bad. if ($array[9][$key] != 1) { // Yes, report an error $result['status'] = 2; $result['error'] = "Error Operability Code: ".$array[9][$key]; } else { // No, unset any errors that may exist. $result['status'] = 0; $result['error'] = ''; } // Add the ent Physical entry $entPhysicalData['entPhysicalClass'] = 'module'; $entPhysicalData['entPhysicalModelName'] = $array[14][$key]; $entPhysicalData['entPhysicalName'] = 'Disk'; $entPhysicalData['entPhysicalDescr'] = $result['string']; $entPhysicalData['entPhysicalSerialNum'] = $array[12][$key]; list($result['entPhysical'],$entPhysicalData['entPhysicalIndex']) = setCIMCentPhysical($result['label'], $entPhysicalData, $entphysical, $entmax); $valid[$entPhysicalData['entPhysicalIndex']] = 1; // Add the result to the array. d_echo("SAS Disk (".$tbl."): ".print_r($result, true)."\n"); $tblCIMC[] = $result; } break; // LUN's - rack-unit-1/board/storage-SAS-2/lun-0 case "1.3.6.1.4.1.9.9.719.1.45.8.1": foreach ($array[3] as $key => $item) { $result = array(); $result['hwtype'] = 'lun'; $result['id'] = substr($array[3][$key], 4); $result['label'] = $array[2][$key]; $result['serial'] = 'N/A'; $result['statusoid'] = '1.3.6.1.4.1.9.9.719.1.45.8.1.9.'.$key; // Old Firmware returns 4294967296 as 1 MB. // The if below assumes we will never have < 1 Gb on old firmware or > 4 Pb on new firmware if (($array[13][$key]) > 4294967296000) { // Old Firmware $result['string'] = $array[3][$key] .", Size: ". round($array[13][$key]/4294967296000, 2) ." GB"; d_echo("LUN: ".$array[2][$key].", Raw Size: ".$array[13][$key].", converted (Old FW): ".round($array[13][$key]/4294967296000, 2)."GB\n"); } else { // New Firmware $result['string'] = $array[3][$key] .", Size: ". round($array[13][$key]/1000, 2) ." GB"; d_echo("LUN: ".$array[2][$key].", Raw Size: ".$array[13][$key].", converted (New FW): ".round($array[13][$key]/1000, 2)."GB\n"); } // What is the Operability, 1 is good, everything else is bad. if ($array[9][$key] != 1) { // Yes, report an error $result['status'] = 2; $result['error'] = "Error Operability Code: ".$array[9][$key]; } else { // No, unset any errors that may exist. $result['status'] = 0; $result['error'] = ''; } // Add the ent Physical entry $entPhysicalData['entPhysicalClass'] = 'module'; $entPhysicalData['entPhysicalModelName'] = $array[3][$key]; $entPhysicalData['entPhysicalName'] = 'LUN'; $entPhysicalData['entPhysicalDescr'] = $result['string']; $entPhysicalData['entPhysicalSerialNum'] = ''; list($result['entPhysical'],$entPhysicalData['entPhysicalIndex']) = setCIMCentPhysical($result['label'], $entPhysicalData, $entphysical, $entmax); $valid[$entPhysicalData['entPhysicalIndex']] = 1; // Add the result to the array. d_echo("LUN (".$tbl."): ".print_r($result, true)."\n"); $tblCIMC[] = $result; } break; // RAID Battery - rack-unit-1/board/storage-SAS-2/raid-battery case "1.3.6.1.4.1.9.9.719.1.45.11.1": foreach ($array[3] as $key => $item) { $result = array(); $result['hwtype'] = 'raid-battery'; $result['id'] = $array[3][$key]; $result['label'] = $array[2][$key]; $result['serial'] = 'N/A'; $result['string'] = $array[3][$key] ." - ". $array[7][$key]; $result['statusoid'] = '1.3.6.1.4.1.9.9.719.1.45.11.1.9.'.$key; // What is the Operability, 1 is good, everything else is bad. if ($array[9][$key] != 1) { // Yes, report an error $result['status'] = 2; $result['error'] = "Error Operability Code: ".$array[9][$key]; } else { // No, unset any errors that may exist. $result['status'] = 0; $result['error'] = ''; } // Add the ent Physical entry $entPhysicalData['entPhysicalClass'] = 'module'; $entPhysicalData['entPhysicalModelName'] = $array[3][$key]; $entPhysicalData['entPhysicalName'] = 'RAID Battery'; $entPhysicalData['entPhysicalDescr'] = $result['string']; $entPhysicalData['entPhysicalSerialNum'] = ''; list($result['entPhysical'],$entPhysicalData['entPhysicalIndex']) = setCIMCentPhysical($result['label'], $entPhysicalData, $entphysical, $entmax); $valid[$entPhysicalData['entPhysicalIndex']] = 1; // Add the result to the array. d_echo("RAID Battery (".$tbl."): ".print_r($result, true)."\n"); $tblCIMC[] = $result; } break; // Fan's - rack-unit-1/fan-module-1-1/fan-1 case "1.3.6.1.4.1.9.9.719.1.15.12.1": foreach ($array[3] as $key => $item) { $result = array(); $result['hwtype'] = 'fan'; $result['id'] = $array[8][$key] ."-". substr($array[3][$key], 4); $result['label'] = $array[2][$key]; $result['serial'] = 'N/A'; $result['string'] = $array[7][$key]; $result['statusoid'] = '1.3.6.1.4.1.9.9.719.1.15.12.1.10.'.$key; // What is the Operability, 1 is good, everything else is bad. if ($array[10][$key] != 1) { // Yes, report an error $result['status'] = 2; $result['error'] = "Error Operability Code: ".$array[10][$key]; } else { // No, unset any errors that may exist. $result['status'] = 0; $result['error'] = ''; } // Add the ent Physical entry $entPhysicalData['entPhysicalClass'] = 'fan'; $entPhysicalData['entPhysicalModelName'] = $array[7][$key]; $entPhysicalData['entPhysicalName'] = 'FAN'; $entPhysicalData['entPhysicalDescr'] = $result['string']; $entPhysicalData['entPhysicalSerialNum'] = ''; list($result['entPhysical'],$entPhysicalData['entPhysicalIndex']) = setCIMCentPhysical($result['label'], $entPhysicalData, $entphysical, $entmax); $valid[$entPhysicalData['entPhysicalIndex']] = 1; // Add the result to the array. d_echo("Fan (".$tbl."): ".print_r($result, true)."\n"); $tblCIMC[] = $result; } break; // PSU's - rack-unit-1/psu-1 case "1.3.6.1.4.1.9.9.719.1.15.56.1": foreach ($array[3] as $key => $item) { $result = array(); $result['hwtype'] = 'psu'; $result['id'] = substr($array[3][$key], 4); $result['label'] = $array[2][$key]; $result['serial'] = $array[13][$key]; $result['string'] = $array[6][$key] ." - Rev: ". $array[12][$key]; $result['statusoid'] = '1.3.6.1.4.1.9.9.719.1.15.56.1.8.'.$key; // What is the Operability, 1 is good, everything else is bad. if ($array[8][$key] != 1) { // Yes, report an error $result['status'] = 2; $result['error'] = "Error Operability Code: ".$array[8][$key]; } else { // No, unset any errors that may exist. $result['status'] = 0; $result['error'] = ''; } // Add the ent Physical entry $entPhysicalData['entPhysicalClass'] = 'powerSupply'; $entPhysicalData['entPhysicalModelName'] = $array[6][$key]; $entPhysicalData['entPhysicalName'] = 'PSU'; $entPhysicalData['entPhysicalDescr'] = $result['string']; $entPhysicalData['entPhysicalSerialNum'] = $array[13][$key]; list($result['entPhysical'],$entPhysicalData['entPhysicalIndex']) = setCIMCentPhysical($result['label'], $entPhysicalData, $entphysical, $entmax); $valid[$entPhysicalData['entPhysicalIndex']] = 1; // Add the result to the array. d_echo("PSU (".$tbl."): ".print_r($result, true)."\n"); $tblCIMC[] = $result; } break; // Adaptors - rack-unit-1/adaptor-1 case "1.3.6.1.4.1.9.9.719.1.3.85.1": foreach ($array[3] as $key => $item) { $result = array(); $result['hwtype'] = 'adaptor'; $result['id'] = substr($array[3][$key], 8); $result['label'] = $array[2][$key]; $result['serial'] = $array[21][$key]; $result['string'] = $array[11][$key] ." - Rev: ". $array[20][$key] ." - Part-No: ". $array[26][$key]; $result['statusoid'] = '1.3.6.1.4.1.9.9.719.1.3.85.1.13.'.$key; // What is the Operability, 1 is good, everything else is bad. if ($array[13][$key] != 1) { // Yes, report an error $result['status'] = 2; $result['error'] = "Error Operability Code: ".$array[13][$key]; } else { // No, unset any errors that may exist. $result['status'] = 0; $result['error'] = ''; } // Add the ent Physical entry $entPhysicalData['entPhysicalClass'] = 'module'; $entPhysicalData['entPhysicalModelName'] = $array[11][$key]; $entPhysicalData['entPhysicalName'] = 'Adaptor'; $entPhysicalData['entPhysicalDescr'] = $result['string']; $entPhysicalData['entPhysicalSerialNum'] = $array[21][$key]; list($result['entPhysical'],$entPhysicalData['entPhysicalIndex']) = setCIMCentPhysical($result['label'], $entPhysicalData, $entphysical, $entmax); $valid[$entPhysicalData['entPhysicalIndex']] = 1; // Add the result to the array. d_echo("Adaptor (".$tbl."): ".print_r($result, true)."\n"); $tblCIMC[] = $result; } break; // Unknown Table, ask the user to log an issue so this can be identified. default: d_echo("Cisco-CIMC Error...\n"); d_echo("Please log an issue on github with the following information:\n"); d_echo("-----------------------------------------------\n"); d_echo("Subject: CIMC Unknown Table: ".$tbl."\n"); d_echo("Description: The entity-physical module discovered an unknown CIMC table.\nA dump of its contents is below:\n"); d_echo($array); d_echo("-----------------------------------------------\n\n"); break; } // End Switch } // End foreach tblUCSObjects } // End is_array /* * 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 ($tblCIMC 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['label'] === $array['label']) { $component_key = $compid; } } if (!$component_key) { // The component doesn't exist, we need to ADD it - ADD. $new_component = $component->createComponent($device['device_id'], $comp_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 ($tblCIMC as $k => $v) { if ($array['label'] == $v['label']) { // Yay, we found it... $found = true; } } if ($found === false) { // The component has not been found. we should delete it and it's entPhysical entry echo "-"; dbDelete('entPhysical', '`entPhysical_id` = ?', array($array['entPhysical'])); $component->deleteComponent($key); } } if (is_array($components)) { // Write the Components back to the DB. $component->setComponentPrefs($device['device_id'], $components); echo "\n"; } } // End if not error