Files
librenms-librenms/LibreNMS/OS/CienaSds.php
Tony Murray 9d35fbc6a7 Entity Physical discovery: Rewrite to modern style (#16289)
* Initial entity-physical code

* Split out Entity-MIB trait

* Cisco Cellular inventory

* Fix bad test data

* alfo80hd - we now include all entPhysical entries

* Correct aos7 test data

* Add entPhysicalClass as last resort for label in ui

* aos add previously filtered data

* Fixup arista-eos data

* Update ariast_eos data

* Arris, clean garbage in Rev fields

* Aruba Instant custom inventory ported

* ArubaOS CX add vendor type mib

* aviat-wtm test data refresh

* axos add shelf fix data fields a bit

* ciena-rls

* ciena-sds

* Skip cimc for now... no test data

* Cisco updates

* Comware data update

* Update dnos

* Clean Edgeos garbage, make code from Arris shareable

* Relaxed ifIndex match, some devices cheat and send back static strings instead of formatted OIDs

* Regex refinement and updated edgeos with new clean data

* Update edgeswitch data

* Update eltex-mes21xx data

* eltex-mes23xx

* Guess at eltex-mes24xx since there is no test data

* Update eurostor, fix firmware version

* Apply fixes from StyleCI

* fixes

* Update fortigate data

* Update fortiweb, ftd, and fusion

* Update linux LSI

* Fix hexToAscii null removal with different seperator handling

* icotera add final snmprec data to avoid snmpsim bug

* Update IOS data

* Update mrv-od

* Add junos translation

* Generic data updates n-r

* ruijie workaround snmpsim bug

* Port saf-cfm

* Recode Schleifenbauer, and fix entPhysicalIndex values

* SmartAX fixes

* sm-os and tait-infra93

* timos inventory was not right, fix it up

* ubiquoss-pon

* VRP, has custom data collection on top of normal
adapt port ifIndex lookup to handle it

* VRP exceeded the string length specified in ENTITY-MIB...

* data updates

* Final data update and code cleanup

* Apply fixes from StyleCI

* Lint fixes

* Add missing SnmpResponse->pluck() code

* Update db_schema.yaml

* Fix bad test data

* Another instant-on update

* oops

* Remove some unused code

# Conflicts:
#	includes/html/pages/device/overview.inc.php

---------

Co-authored-by: Tony Murray <murrant@users.noreply.github.com>
2024-08-21 01:12:09 -05:00

207 lines
10 KiB
PHP

<?php
namespace LibreNMS\OS;
use App\Models\EntPhysical;
use Illuminate\Support\Collection;
use LibreNMS\OS;
use SnmpQuery;
class CienaSds extends OS
{
public function discoverEntityPhysical(): Collection
{
$inventory = new Collection;
// Chassis stuff
$chassis_info = SnmpQuery::get([
'CIENA-CES-CHASSIS-MIB::cienaCesChassisPlatformDesc.0',
'CIENA-CES-CHASSIS-MIB::cienaCesChassisPartNumber.0',
'CIENA-CES-CHASSIS-MIB::cienaCesChassisSerialNumber.0',
'CIENA-CES-CHASSIS-MIB::cienaCesChassisIDPModelRevision.0',
])->values();
$inventory->push(new EntPhysical([
'entPhysicalIndex' => 1,
'entPhysicalDescr' => $chassis_info['CIENA-CES-CHASSIS-MIB::cienaCesChassisPlatformDesc.0'] ?? null,
'entPhysicalClass' => 'chassis',
'entPhysicalName' => 'Chassis',
'entPhysicalModelName' => $chassis_info['CIENA-CES-CHASSIS-MIB::cienaCesChassisPartNumber.0'] ?? null,
'entPhysicalSerialNum' => $chassis_info['CIENA-CES-CHASSIS-MIB::cienaCesChassisSerialNumber.0'] ?? null,
'entPhysicalMfgName' => 'Ciena',
'entPhysicalHardwareRev' => $chassis_info['CIENA-CES-CHASSIS-MIB::cienaCesChassisIDPModelRevision.0'] ?? null,
'entPhysicalIsFRU' => 'true',
]));
$inventory->push(new EntPhysical([
'entPhysicalIndex' => 401,
'entPhysicalClass' => 'container',
'entPhysicalName' => 'Modules',
'entPhysicalContainedIn' => 1,
]));
$inventory->push(new EntPhysical([
'entPhysicalIndex' => 411,
'entPhysicalClass' => 'container',
'entPhysicalName' => 'Power Supplies',
'entPhysicalContainedIn' => 1,
]));
$inventory->push(new EntPhysical([
'entPhysicalIndex' => 421,
'entPhysicalClass' => 'container',
'entPhysicalName' => 'Fans',
'entPhysicalContainedIn' => 1,
]));
// PSU Stuff
$cienaCesChassisPowerTable = SnmpQuery::hideMib()->enumStrings()->walk('CIENA-CES-CHASSIS-MIB::cienaCesChassisPowerTable')->table(1);
foreach ($cienaCesChassisPowerTable as $index => $contents) {
$inventory->push(new EntPhysical([
'entPhysicalIndex' => "50$index",
'entPhysicalDescr' => $contents['cienaCesChassisPowerSupplyManufacturer'] ?? null,
'entPhysicalClass' => 'sensor',
'entPhysicalName' => $contents['cienaCesChassisPowerSupplySlotName'] ?? null,
'entPhysicalModelName' => $contents['cienaCesChassisPowerSupplyPartNum'] ?? null,
'entPhysicalSerialNum' => $contents['cienaCesChassisPowerSupplySerialNumber'] ?? null,
'entPhysicalContainedIn' => '41' . ($contents['cienaCesChassisPowerSupplyChassisIndx'] ?? null),
'entPhysicalMfgName' => 'Ciena',
'entPhysicalParentRelPos' => $contents['cienaCesChassisPowerSupplySlotIndx'] ?? null,
'entPhysicalHardwareRev' => $contents['cienaCesChassisPowerSupplyRevInfo'] ?? null,
'entPhysicalIsFRU' => $contents['cienaCesChassisPowerSupplyFRU'] ?? null,
]));
}
// Fan Stuff
$trays = SnmpQuery::hideMib()->walk('CIENA-CES-CHASSIS-MIB::cienaCesChassisFanTrayTable')->table(1);
foreach ($trays as $tray_index => $tray_data) {
$typeString = match ($tray_data['cienaCesChassisFanTrayType']) {
1 => 'Fixed fan tray, ',
2 => 'Hot swappable fan tray, ',
3 => 'Unequipped fan tray, ',
default => '',
};
$modeString = match ($tray_data['cienaCesChassisFanTrayMode']) {
1 => 'Invalid fan configuration!',
2 => 'Fully populated',
3 => 'Auto mode',
default => '',
};
$inventory->push(new EntPhysical([
'entPhysicalIndex' => "53$tray_index",
'entPhysicalClass' => 'sensor',
'entPhysicalName' => $tray_data['cienaCesChassisFanTrayName'],
'entPhysicalModelName' => 'Fan Tray',
'entPhysicalDescr' => "$typeString$modeString",
'entPhysicalSerialNum' => $tray_data['cienaCesChassisFanTraySerialNumber'],
'entPhysicalContainedIn' => '42' . $tray_data['cienaCesChassisFanTrayChassisIndx'],
'entPhysicalMfgName' => 'Ciena',
'entPhysicalParentRelPos' => $tray_data['cienaCesChassisFanTraySlotIndx'],
'entPhysicalIsFRU' => $tray_data['cienaCesChassisFanTrayType'] == '2' ? 'true' : 'false',
]));
}
$fans = SnmpQuery::hideMib()->walk('CIENA-CES-CHASSIS-MIB::cienaCesChassisFanTable')->table(2);
foreach ($fans as $tray_index => $fans_data) {
foreach ($fans_data as $fan_index => $fan_data) {
$inventory->push(new EntPhysical([
'entPhysicalIndex' => "51$fan_index",
'entPhysicalClass' => 'sensor',
'entPhysicalName' => $fan_data['cienaCesChassisFanName'],
'entPhysicalModelName' => 'Fan',
'entPhysicalContainedIn' => isset($trays[$tray_index]) ?
"53$tray_index" : '42' . $fan_data['cienaCesChassisFanChassisIndx'],
'entPhysicalMfgName' => 'Ciena',
'entPhysicalParentRelPos' => $fan_index,
]));
}
}
$fanTemps = SnmpQuery::hideMib()->walk('CIENA-CES-CHASSIS-MIB::cienaCesChassisFanTempTable')->table(2);
foreach ($fanTemps as $tray_index => $temps_data) {
foreach ($temps_data as $temp_index => $temp_data) {
$inventory->push(new EntPhysical([
'entPhysicalIndex' => "52$temp_index",
'entPhysicalClass' => 'sensor',
'entPhysicalName' => $temp_data['cienaCesChassisFanTempName'],
'entPhysicalModelName' => 'Temp Sensor',
'entPhysicalContainedIn' => isset($trays[$tray_index]) ?
"53$tray_index" : '42' . $temp_data['cienaCesChassisFanTempChassisIndx'],
]));
}
}
// Module Stuff
$inventory = $inventory->merge(SnmpQuery::hideMib()->walk([
'CIENA-CES-MODULE-MIB::cienaCesModuleTable',
'CIENA-CES-MODULE-MIB::cienaCesModuleDescriptionTable',
'CIENA-CES-MODULE-MIB::cienaCesModuleSwTable',
])->mapTable(function ($contents, $chassisIndex, $shelfIndex, $slotIndex) {
$descr = $contents['cienaCesModuleDescription'];
$release = $contents['cienaCesModuleSwRunningRelease'] ?? null;
if ($release) {
$descr .= ", $release";
}
return new EntPhysical([
'entPhysicalIndex' => "55$slotIndex",
'entPhysicalDescr' => $descr,
'entPhysicalClass' => 'sensor',
'entPhysicalName' => $contents['cienaCesModuleSlotName'] . ': ' . $contents['cienaCesModuleDescriptionBoardName'],
'entPhysicalModelName' => $contents['cienaCesModuleDescriptionBoardPartNum'],
'entPhysicalSerialNum' => $contents['cienaCesModuleDescriptionBoardSerialNum'],
'entPhysicalContainedIn' => '40' . $chassisIndex,
'entPhysicalMfgName' => 'Ciena',
'entPhysicalParentRelPos' => $slotIndex,
'entPhysicalFirmwareRev' => $release,
'entPhysicalIsFRU' => 'true',
]);
}));
// Interface stuff
$interfaceIndexMapping = SnmpQuery::walk('BRIDGE-MIB::dot1dBasePortIfIndex')->table(1);
$transceivers = SnmpQuery::hideMib()->enumStrings()->walk([
'CIENA-CES-PORT-MIB::cienaCesEttpConfigTable',
'CIENA-CES-PORT-XCVR-MIB::cienaCesPortXcvrTable',
])->table(1);
foreach ($transceivers as $index => $contents) {
$portIndex = $interfaceIndexMapping[$index]['BRIDGE-MIB::dot1dBasePortIfIndex'];
$nameArr = explode('/', $contents['cienaCesEttpConfigName']);
$slotIndex = isset($nameArr[1]) ? $nameArr[0] : 1;
$inventory->push(new EntPhysical([
'entPhysicalIndex' => "56$index",
'entPhysicalDescr' => $contents['cienaCesEttpConfigEttpType'],
'entPhysicalClass' => 'port',
'entPhysicalName' => $contents['cienaCesEttpConfigName'],
'entPhysicalContainedIn' => '55' . $slotIndex,
'entPhysicalParentRelPos' => $index,
'ifIndex' => $portIndex,
]));
if (isset($contents['cienaCesPortXcvrOperState']) && $contents['cienaCesPortXcvrOperState'] != 'notPresent') {
$wavelengthString = ($contents['cienaCesPortXcvrWaveLength'] != 0 ?
$contents['cienaCesPortXcvrWaveLength'] . ' nm ' : '');
$mfgString = ($contents['cienaCesPortXcvrMfgDate'] != '' ?
'manufactured ' . $contents['cienaCesPortXcvrMfgDate'] . ' ' : '');
$inventory->push(new EntPhysical([
'entPhysicalIndex' => $portIndex,
'entPhysicalDescr' => $contents['cienaCesPortXcvrVendorName'] . ' ' . $wavelengthString .
$contents['cienaCesPortXcvrIdentiferType'] . ' transceiver ' . $mfgString,
'entPhysicalClass' => 'sensor',
'entPhysicalModelName' => $contents['cienaCesPortXcvrVendorPartNum'],
'entPhysicalSerialNum' => $contents['cienaCesPortXcvrSerialNum'],
'entPhysicalContainedIn' => "56$index",
'entPhysicalMfgName' => $contents['cienaCesPortXcvrVendorName'],
'entPhysicalParentRelPos' => -1,
'entPhysicalHardwareRev' => $contents['cienaCesPortXcvrRevNum'],
'entPhysicalIsFRU' => 'true',
]));
}
}
return $inventory;
}
}