Changes of Revision 19
[-] | Changed | check_openmanage.spec |
x 1
2 Summary: A Nagios plugin to check hardware health on Dell servers 3 Name: check_openmanage 4 -Version: 3.6.1 5 +Version: 3.6.2 6 Release: 1%{?dist} 7 License: GPL 8 Group: Applications/System 9
10 %attr(0755, root, root) %{_mandir}/man8/%{name}.8* 11 12 %changelog 13 +* Thu Nov 25 2010 Carsten Schoene <cs@linux-administrator.com> - 3.6.2-1 14 +- update to version 3.6.2 15 + - Added support for IPv6 when checking via SNMP. IPv6 can be turned on with the option -6 or --ipv6. 16 + The default is IPv4 if the option is not present. 17 + - Added support for TCP when checking vis SNMP. The option --tcp can be used to turn on TCP. 18 + The default transport protocol is UDP if the option is not present. 19 + - The mode of operation (local or SNMP) is shown in the debug output. If SNMP is used, 20 + the debug output will also show the SNMP protocol version, IP version and transport protocol (UDP or TCP). 21 + - Amperage probe status via SNMP is of type "probe status", not regular status. This has been fixed. 22 + - Massive overall robustness improvements to handle OMSA bugs where some information from OMSA is missing. 23 + - Memory module enumeration via SNMP changed somewhat to reflect enumeration provided by omreport. 24 + This ensures that the plugin's output is identical in SNMP or local mode wrt. dimms IDs. 25 + - Fan enumeration via SNMP changed somewhat to reflect enumeration provided by omreport. 26 + This ensures that the plugin's output is identical in SNMP or local mode wrt. fan IDs. 27 + 28 * Tue Nov 02 2010 Carsten Schoene <cs@linux-administrator.com> - 3.6.1-1 29 - update to version 3.6.1 30 - Minor feature enhancements, Minor bugfixes 31
32 The SD card check is on by default. A new blacklisting keyword "sd" has been added. The SD card check can be turned off with "--check sdcard=0". 33 - Handle special cases where power monitoring capability is disabled due to non-redundant and/or non-instrumented power supplies. 34 - For physical disks probed via SNMP, check that values for vendor, product ID and capacity is available before attempting to display those values. 35 - - If a physical disk is in sufficiently bad condition, the vendor field reported by OMSA may be empty. The plugin now handles this situation without throwing an internal error. 36 + - If a physical disk is in sufficiently bad condition, the vendor field reported by OMSA may be empty. 37 + The plugin now handles this situation without throwing an internal error. 38 39 * Tue Aug 31 2010 Carsten Schoene <cs@linux-administrator.com> - 3.6.0-1 40 - update to version 3.6.0 41 |
||
Deleted | check_openmanage-3.5.4.tar.gz ^ | |
Deleted | check_openmanage-3.5.5.tar.gz ^ | |
Deleted | check_openmanage-3.5.6.tar.gz ^ | |
Deleted | check_openmanage-3.5.7.tar.gz ^ | |
Deleted | check_openmanage-3.5.9.tar.gz ^ | |
[+] | Changed | check_openmanage-3.6.2.tar.gz/CHANGES ^ |
@@ -1,3 +1,62 @@ +3.6.2 2010-11-25 +------------------ + +* Added support for IPv6 when checking via SNMP. IPv6 can be turned on + with the option '-6' or '--ipv6'. The default is IPv4 if the option + is not present. +* Added support for TCP when checking vis SNMP. The option '--tcp' can + be used to turn on TCP. The default transport protocol is UDP if the + option is not present. +* The mode of operation (local or SNMP) is shown in the debug + output. If SNMP is used, the debug output will also show the SNMP + protocol version, IP version and transport protocol (UDP or TCP). +* Amperage probe status via SNMP is of type "probe status", not + regular status. This has been fixed. +* Massive overall robustness improvements to handle OMSA bugs where + some information from OMSA is missing. +* Memory module enumeration via SNMP changed somewhat to reflect + enumeration provided by omreport. This ensures that the plugin's + output is identical in SNMP or local mode wrt. dimms IDs. +* Fan enumeration via SNMP changed somewhat to reflect enumeration + provided by omreport. This ensures that the plugin's output is + identical in SNMP or local mode wrt. fan IDs. + +3.6.1 2010-11-02 +------------------ + +* Included new check for SD cards. Newer servers such as the R710 can + have SD cards installed, these should be monitored. The SD card + check is on by default. A new blacklisting keyword 'sd' has been + added. The SD card check can be turned off with '--check sdcard=0'. +* Handle special cases where power monitoring capability is disabled + due to non-redundant and/or non-instrumented power supplies. +* For physical disks probed via SNMP, check that values for vendor, + product ID and capacity is available before attempting to display + those values. +* If a physical disk is in sufficiently bad condition, the vendor + field reported by OMSA may be empty. The plugin now handles this + situation without throwing an internal error. + + +3.6.0 2010-08-30 +------------------ + +* Storage is no longer allowed to be absent. If the plugin doesn't + find a storage controller, it will give an alert. For diskless + systems or servers without a Dell controller that OMSA recognizes + you will now have to specify '--no-storage' or '--check storage=0' + to work around this. +* Report the system revision (if applicable) wherever the model name + is printed. E.g. "PowerEdge 2950 III" instead of "PowerEdge 2950". +* Small change in search path for omreport: The new location for OMSA + 6.2.0 and later on Linux will be attempted first. +* Small bugfix for the '--check' parameter, if the argument is a + filename. The file could not contain a linebreak, this has been + fixed. +* Added an option '--no-storage', which is equivalent to the general + option '--check storage=0'. + + 3.5.10 2010-07-14 ------------------ | ||
[+] | Changed | check_openmanage-3.6.2.tar.gz/check_openmanage ^ |
@@ -5,9 +5,9 @@ # Monitor Dell server hardware status using Dell OpenManage Server # Administrator, either locally via NRPE, or remotely via SNMP. # -# $Id: check_openmanage 17959 2010-07-14 11:42:15Z trondham $ +# $Id: check_openmanage 18776 2010-11-25 10:40:36Z trondham $ # -# Copyright (C) 2010 Trond H. Amundsen +# Copyright (C) 2008-2010 Trond H. Amundsen # # 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 @@ -51,7 +51,7 @@ # Version and similar info $NAME = 'check_openmanage'; -$VERSION = '3.5.10'; +$VERSION = '3.6.2'; $AUTHOR = 'Trond H. Amundsen'; $CONTACT = 't.h.amundsen@usit.uio.no'; @@ -74,10 +74,10 @@ GENERAL OPTIONS: - -p, --perfdata Output performance data - -t, --timeout Plugin timeout in seconds - -c, --critical Customise temperature critical limits - -w, --warning Customise temperature warning limits + -p, --perfdata Output performance data [default=no] + -t, --timeout Plugin timeout in seconds [default=30] + -c, --critical Custom temperature critical limits + -w, --warning Custom temperature warning limits -d, --debug Debug output, reports everything -h, --help Display this help text -V, --version Display version info @@ -85,16 +85,18 @@ SNMP OPTIONS: -H, --hostname Hostname or IP (required for SNMP) - -C, --community SNMP community string - -P, --protocol SNMP protocol version - --port SNMP port number + -C, --community SNMP community string [default=public] + -P, --protocol SNMP protocol version [default=2] + --port SNMP port number [default=161] + -6, --ipv6 Use IPv6 instead of IPv4 [default=no] + --tcp Use TCP instead of UDP [default=no] OUTPUT OPTIONS: -i, --info Prefix any alerts with the service tag -e, --extinfo Append system info to alerts -s, --state Prefix alerts with alert state - -S, --short-state Prefix alerts with alert state (abbreviated) + -S, --short-state Prefix alerts with alert state abbreviated -o, --okinfo Verbosity when check result is OK -I, --htmlinfo HTML output with clickable links @@ -104,6 +106,7 @@ -b, --blacklist Blacklist missing and/or failed components --only Only check a certain component or alert type --check Fine-tune which components are checked + --no-storage Don't check storage For more information and advanced options, see the manual page or URL: http://folk.uio.no/trondham/software/check_openmanage.html @@ -112,7 +115,7 @@ # Version and license text $LICENSE = <<"END_LICENSE"; $NAME $VERSION -Copyright (C) 2010 $AUTHOR +Copyright (C) 2008-2010 $AUTHOR License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. @@ -140,11 +143,14 @@ 'version' => 0, # plugin version info 'all' => 0, # check everything 'only' => undef, # only one component + 'no_storage' => 0, # don't check storage 'omreport' => undef, # omreport path 'port' => 161, # default SNMP port 'hostname' => undef, # hostname or IP 'community' => 'public', # SMNP v1 or v2c 'protocol' => 2, # default SNMP protocol 2c + 'ipv6' => 0, # default is IPv4 + 'tcp' => 0, # default is UDP 'username' => undef, # SMNP v3 'authpassword' => undef, # SMNP v3 'authkey' => undef, # SMNP v3 @@ -175,11 +181,14 @@ 'linebreak=s' => \$opt{linebreak}, 'a|all' => \$opt{all}, 'only=s' => \$opt{only}, + 'no-storage' => \$opt{no_storage}, 'omreport=s' => \$opt{omreport}, 'port=i' => \$opt{port}, 'H|hostname=s' => \$opt{hostname}, 'C|community=s' => \$opt{community}, 'P|protocol=i' => \$opt{protocol}, + '6|ipv6' => \$opt{ipv6}, + 'tcp' => \$opt{tcp}, 'U|username=s' => \$opt{username}, 'authpassword=s' => \$opt{authpassword}, 'authkey=s' => \$opt{authkey}, @@ -230,6 +239,7 @@ 'batteries' => 1, # check battery probes 'amperage' => 1, # check power consumption 'intrusion' => 1, # check intrusion detection + 'sdcard' => 1, # check removable flash media (SD cards) 'alertlog' => 0, # check the alert log 'esmlog' => 0, # check the ESM log (hardware log) 'esmhealth' => 1, # check the ESM log overall health @@ -282,6 +292,7 @@ 'cpu' => 0, # number of CPUs 'bat' => 0, # number of batteries 'power' => 0, # number of power supplies + 'sd' => 0, # number of SD cards 'esm' => { 'Critical' => 0, # critical entries in ESM log 'Non-Critical' => 0, # warning entries in ESM log @@ -369,6 +380,7 @@ 'biosdate' => 'N/A', # BIOS release date 'serial' => 'N/A', # serial number (service tag) 'model' => 'N/A', # system model + 'rev' => q{}, # system revision 'osname' => 'N/A', # OS name 'osver' => 'N/A', # OS version 'om' => 'N/A', # OMSA version @@ -482,6 +494,11 @@ '-version' => $opt{protocol}, ); + # Setting the domain (IP version and transport protocol) + my $transport = $opt{tcp} ? 'tcp' : 'udp'; + my $ipversion = $opt{ipv6} ? 'ipv6' : 'ipv4'; + $param{'-domain'} = "$transport/$ipversion"; + # Parameters for SNMP v3 if ($opt{protocol} == 3) { @@ -613,8 +630,8 @@ # Possible full paths for omreport my @omreport_paths = ( - '/usr/bin/omreport', # default on Linux - '/opt/dell/srvadmin/bin/omreport', # default on Linux with OMSA 6.2.0 + '/opt/dell/srvadmin/bin/omreport', # default on Linux with OMSA >= 6.2.0 + '/usr/bin/omreport', # default on Linux with OMSA < 6.2.0 '/opt/dell/srvadmin/oma/bin/omreport.sh', # alternate on Linux '/opt/dell/srvadmin/oma/bin/omreport', # alternate on Linux 'C:\Program Files (x86)\Dell\SysMgt\oma\bin\omreport.exe', # default on Windows x64 @@ -682,9 +699,8 @@ open my $BL, '<', $black or do { report('other', "Couldn't open blacklist file $black: $!", $E_UNKNOWN) and return {} }; - $tmp = <$BL>; + chomp($tmp = <$BL>); close $BL; - chomp $tmp; } else { $tmp = $black; @@ -716,6 +732,11 @@ sub adjust_checks { my @cl = (); + # First, take the '--no-storage' option + if ($opt{no_storage}) { + $check{storage} = 0; + } + # Adjust checking based on the '--all' option if ($opt{all}) { # Check option usage @@ -768,7 +789,7 @@ if (-f $check) { open my $CL, '<', $check or do { report('other', "Couldn't open check file $check: $!", $E_UNKNOWN) and return }; - $tmp = <$CL>; + chomp($tmp = <$CL>); close $CL; } else { @@ -822,10 +843,12 @@ = qr{ Intrusion\sinformation\sis\snot\sfound\sfor\sthis\ssystem # No intrusion probe | No\sinstrumented\spower\ssupplies\sfound\son\sthis\ssystem # No instrumented PS (blades/low-end) - | No\scontrollers\sfound # No RAID controller | No\sbattery\sprobes\sfound\son\sthis\ssystem # No battery probes - | Invalid\scommand:\spwrmonitoring # Older OMSAs lack this command(?) + | Invalid\scommand:\spwrmonitoring # Old hardware + | Hardware\sor\sfeature\snot\spresent\. # SD cards + | Invalid\scommand:\sremovableflashmedia # SD cards with old OMSA # | Current\sprobes\snot\sfound # OMSA + RHEL5.4 bug +# | No\scontrollers\sfound # No RAID controller }xms; # Errors that are OK on blade servers @@ -841,6 +864,11 @@ # Workaround for Openmanage BUG introduced in OMSA 5.5.0 $rawtext =~ s{\n;}{;}gxms if $command eq 'storage controller'; + # Report if no controllers found + if ($command eq 'storage controller' and $rawtext =~ m{No\scontrollers\sfound}xms) { + report('storage', 'Storage Error! No controllers found', $E_UNKNOWN); + } + # Openmanage sometimes puts a linebreak between "Error" and the # actual error text $rawtext =~ s{^Error\s*\n}{Error: }xms; @@ -855,7 +883,7 @@ next if !m/(.*?;){2}/xms; # ignore lines with less than 3 fields my @vals = split /;/xms; - if ($vals[0] =~ m/\A (Index|ID|Severity|Processor|Current\sSpeed) \z/xms) { + if ($vals[0] =~ m/\A (Index|ID|Severity|Processor|Current\sSpeed|Connector\sName) \z/xms) { @keys = @vals; } else { @@ -869,7 +897,6 @@ return \@output; } - # # Checks if a component is blacklisted. Returns 1 if the component is # blacklisted, 0 otherwise. Takes two arguments: @@ -1064,9 +1091,32 @@ sub get_hashval { my $key = shift || return undef; my $hash = shift; - return exists $hash->{$key} ? $hash->{$key} : "Undefined value $key"; + return defined $hash->{$key} ? $hash->{$key} : "Undefined value $key"; +} + +# Find component status from hash +sub get_snmp_status { + my $key = shift || return 'Unknown'; + return exists $snmp_status{$key} ? $snmp_status{$key} : 'Unknown'; } +# Find component status from hash +sub get_snmp_probestatus { + my $key = shift || return 'Unknown'; + return exists $snmp_probestatus{$key} ? $snmp_probestatus{$key} : 'Unknown'; +} + +# Check that a hash entry is defined and not an empty string. Return a +# chosen string (parameter) if these conditions are not met +sub get_nonempty_string { + my $key = shift; # key to check + my $hash = shift; # hash where the key belongs + my $alt = shift; # alternate return value + if (defined $hash->{$key} and $hash->{$key} ne q{}) { + return $hash->{$key}; + } + return $alt; +} #--------------------------------------------------------------------- @@ -1089,7 +1139,7 @@ printf "SNMP ERROR [global]: %s\n", $snmp_error; exit $E_UNKNOWN; } - $health = $status2nagios{$snmp_status{$result->{$systemStateGlobalSystemStatus}}}; + $health = $status2nagios{get_snmp_status($result->{$systemStateGlobalSystemStatus})}; } else { # @@ -1116,7 +1166,6 @@ sub check_controllers { return if blacklisted('ctrl', 'all'); - my $id = undef; my $nexus = undef; my $name = undef; my $state = undef; @@ -1151,8 +1200,10 @@ my $controllerTable = '1.3.6.1.4.1.674.10893.1.20.130.1'; my $result = $snmp_session->get_table(-baseoid => $controllerTable); - # No controllers is OK - return if !defined $result; + if (!defined $result) { + report('storage', 'Storage Error! No controllers found', $E_UNKNOWN); + return; + } @output = @{ get_snmp_output($result, \%ctrl_oid) }; } @@ -1173,29 +1224,22 @@ CTRL: foreach my $out (@output) { if ($snmp) { - $name = $out->{controllerName}; + $name = $out->{controllerName} || 'Unknown controller'; $state = get_hashval($out->{controllerState}, \%ctrl_state); - $status = $snmp_status{$out->{controllerComponentStatus}}; - $minfw = exists $out->{controllerMinFWVersion} - ? $out->{controllerMinFWVersion} : undef; - $mindr = exists $out->{controllerMinDriverVersion} - ? $out->{controllerMinDriverVersion} : undef; - $firmware = exists $out->{controllerFWVersion} - ? $out->{controllerFWVersion} : 'N/A'; - $driver = exists $out->{controllerDriverVersion} - ? $out->{controllerDriverVersion} : 'N/A'; - $minstdr = exists $out->{'controllerMinRequiredStorportVer'} - ? $out->{controllerMinRequiredStorportVer} : undef; - $stdr = exists $out->{controllerStorportDriverVersion} - ? $out->{controllerStorportDriverVersion} : undef; - $nexus = convert_nexus($out->{controllerNexusID}); - $id = $nexus; - } - else { - $id = $out->{ID}; - $name = $out->{Name}; - $state = $out->{State}; - $status = $out->{Status}; + $status = get_snmp_status($out->{controllerComponentStatus}); + $minfw = $out->{controllerMinFWVersion} || undef; + $mindr = $out->{controllerMinDriverVersion} || undef; + $firmware = $out->{controllerFWVersion} || 'N/A'; + $driver = $out->{controllerDriverVersion} || 'N/A'; + $minstdr = $out->{'controllerMinRequiredStorportVer'} || undef; + $stdr = $out->{controllerStorportDriverVersion} || undef; + $nexus = convert_nexus(($out->{controllerNexusID} || 9999)); + } + else { + $nexus = get_nonempty_string('ID', $out, '9999'); + $name = get_nonempty_string('Name', $out, 'Unknown controller'); + $state = get_nonempty_string('State', $out, 'Unknown state'); + $status = get_nonempty_string('Status', $out, 'Unknown'); $minfw = $out->{'Minimum Required Firmware Version'} ne 'Not Applicable' ? $out->{'Minimum Required Firmware Version'} : undef; $mindr = $out->{'Minimum Required Driver Version'} ne 'Not Applicable' @@ -1210,18 +1254,17 @@ $stdr = (exists $out->{'Storport Driver Version'} and $out->{'Storport Driver Version'} ne 'Not Applicable') ? $out->{'Storport Driver Version'} : undef; - $nexus = $id; } $name =~ s{\s+\z}{}xms; # remove trailing whitespace - push @controllers, $id; + push @controllers, $nexus; # Collecting some storage info - $sysinfo{'controller'}{$id}{'id'} = $nexus; - $sysinfo{'controller'}{$id}{'name'} = $name; - $sysinfo{'controller'}{$id}{'driver'} = $driver; - $sysinfo{'controller'}{$id}{'firmware'} = $firmware; - $sysinfo{'controller'}{$id}{'storport'} = $stdr; + $sysinfo{'controller'}{$nexus}{'id'} = $nexus; + $sysinfo{'controller'}{$nexus}{'name'} = $name; + $sysinfo{'controller'}{$nexus}{'driver'} = $driver; + $sysinfo{'controller'}{$nexus}{'firmware'} = $firmware; + $sysinfo{'controller'}{$nexus}{'storport'} = $stdr; # Store controller info for future use (SNMP) if ($snmp) { @@ -1231,37 +1274,37 @@ next CTRL if blacklisted('ctrl', $nexus); # Special case: old firmware - if (!blacklisted('ctrl_fw', $id) && defined $minfw) { + if (!blacklisted('ctrl_fw', $nexus) && defined $minfw) { chomp $firmware; my $msg = sprintf q{Controller %d [%s]: Firmware '%s' is out of date}, - $id, $name, $firmware; + $nexus, $name, $firmware; report('storage', $msg, $E_WARNING, $nexus); } # Special case: old driver - if (!blacklisted('ctrl_driver', $id) && defined $mindr) { + if (!blacklisted('ctrl_driver', $nexus) && defined $mindr) { chomp $driver; my $msg = sprintf q{Controller %d [%s]: Driver '%s' is out of date}, - $id, $name, $driver; + $nexus, $name, $driver; report('storage', $msg, $E_WARNING, $nexus); } # Special case: old storport driver - if (!blacklisted('ctrl_stdr', $id) && defined $minstdr) { + if (!blacklisted('ctrl_stdr', $nexus) && defined $minstdr) { chomp $stdr; my $msg = sprintf q{Controller %d [%s]: Storport driver '%s' is out of date}, - $id, $name, $stdr; + $nexus, $name, $stdr; report('storage', $msg, $E_WARNING, $nexus); } # Ok if ($status eq 'Ok' or ($status eq 'Non-Critical' and (defined $minfw or defined $mindr or defined $minstdr))) { my $msg = sprintf 'Controller %d [%s] is %s', - $id, $name, $state; + $nexus, $name, $state; report('storage', $msg, $E_OK, $nexus); } # Default else { my $msg = sprintf 'Controller %d [%s] needs attention: %s', - $id, $name, $state; + $nexus, $name, $state; report('storage', $msg, $status2nagios{$status}, $nexus); } } @@ -1276,7 +1319,6 @@ return if $#controllers == -1; return if blacklisted('pdisk', 'all'); - my $id = undef; my $nexus = undef; my $name = undef; my $state = undef; @@ -1295,7 +1337,6 @@ if ($snmp) { my %pdisk_oid = ( - '1.3.6.1.4.1.674.10893.1.20.130.4.1.1' => 'arrayDiskNumber', '1.3.6.1.4.1.674.10893.1.20.130.4.1.2' => 'arrayDiskName', '1.3.6.1.4.1.674.10893.1.20.130.4.1.3' => 'arrayDiskVendor', '1.3.6.1.4.1.674.10893.1.20.130.4.1.4' => 'arrayDiskState', @@ -1407,28 +1448,22 @@ PDISK: foreach my $out (@output) { if ($snmp) { - $name = $out->{arrayDiskName}; - if (exists $out->{arrayDiskEnclosureID}) { - $id = join q{:}, ($out->{arrayDiskChannel}, $out->{arrayDiskEnclosureID}, - $out->{arrayDiskTargetID}); - } - else { - $id = join q{:}, ($out->{arrayDiskChannel}, $out->{arrayDiskTargetID}); - } + $name = $out->{arrayDiskName} || 'Unknown disk'; $state = get_hashval($out->{arrayDiskState}, \%pdisk_state); - $status = $snmp_status{$out->{arrayDiskComponentStatus}}; - $fpred = exists $out->{arrayDiskSmartAlertIndication} + $status = get_snmp_status($out->{arrayDiskComponentStatus}); + $fpred = defined $out->{arrayDiskSmartAlertIndication} && $out->{arrayDiskSmartAlertIndication} == 2 ? 1 : 0; $progr = q{}; - $nexus = convert_nexus($out->{arrayDiskNexusID}); - $vendor = $out->{arrayDiskVendor}; - $product = $out->{arrayDiskProductID}; + $nexus = convert_nexus(($out->{arrayDiskNexusID} || 9999)); + $vendor = $out->{arrayDiskVendor} || 'Unknown vendor'; + $product = $out->{arrayDiskProductID} || 'Unknown product ID'; $spare = get_hashval($out->{arrayDiskSpareState}, \%spare_state); $bus = exists $out->{arrayDiskBusType} ? get_hashval($out->{arrayDiskBusType}, \%bus_type) : undef; $media = exists $out->{arrayDiskMediaType} ? get_hashval($out->{arrayDiskMediaType}, \%media_type) : undef; - $capacity = $out->{arrayDiskLengthInMB} * 1024**2; + $capacity = exists $out->{arrayDiskLengthInMB} + ? $out->{arrayDiskLengthInMB} * 1024**2 : -1; # try to find the controller where the disk belongs if (exists $out->{arrayDiskEnclosureConnectionControllerNumber}) { @@ -1446,21 +1481,23 @@ } } else { - $id = $out->{'ID'}; - $name = $out->{'Name'}; - $state = $out->{'State'}; - $status = $out->{'Status'}; - $fpred = lc($out->{'Failure Predicted'}) eq 'yes' ? 1 : 0; - $progr = ' [' . $out->{'Progress'} . ']'; - $ctrl = $out->{'ctrl'}; - $nexus = join q{:}, $out->{ctrl}, $id; - $vendor = $out->{'Vendor ID'}; - $product = $out->{'Product ID'}; - $media = $out->{'Media'}; - $spare = $out->{'Hot Spare'}; - $bus = $out->{'Bus Protocol'}; - $capacity = $out->{'Capacity'}; + $name = get_nonempty_string('Name', $out, 'Unknown disk'); + $state = get_nonempty_string('State', $out, 'Unknown state'); + $status = get_nonempty_string('Status', $out, 'Unknown'); + $fpred = lc(get_nonempty_string('Failure Predicted', $out, q{})) eq 'yes' ? 1 : 0; + $progr = ' [' . get_nonempty_string('Progress', $out, q{}) . ']'; + $nexus = join q{:}, $out->{ctrl}, $out->{'ID'}; + $vendor = get_nonempty_string('Vendor ID', $out, 'Unknown Vendor'); + $product = get_nonempty_string('Product ID', $out, 'Unknown Product ID'); + $media = get_nonempty_string('Media', $out, undef); + $bus = get_nonempty_string('Bus Protocol', $out, undef); + $spare = get_nonempty_string('Hot Spare', $out, q{}); + $ctrl = $out->{ctrl}; + $capacity = get_nonempty_string('Capacity', $out, q{}); $capacity =~ s{\A .*? \((\d+) \s bytes\) \z}{$1}xms; + if ($capacity eq 'Unavailable') { + $capacity = -1; + } } next PDISK if blacklisted('pdisk', $nexus); @@ -1469,19 +1506,28 @@ $vendor =~ s{\s+\z}{}xms; # remove trailing whitespace $product =~ s{\s+\z}{}xms; # remove trailing whitespace + # If the disk is bad, the vendor field may be empty + if ($vendor eq q{}) { $vendor = 'Unknown Vendor'; } + # Hot spare stuff if ($spare eq 'Global') { $spare = 'Global HS'; } elsif ($spare eq 'Dedicated') { $spare = 'Dedicated HS'; } elsif ($spare !~ m{\A Global|Dedicated}xms) { $spare = undef; } # Calculate human readable capacity - $capacity = ceil($capacity / 1000**3) >= 1000 - ? sprintf '%.1fTB', ($capacity / 1000**4) - : sprintf '%.0fGB', ($capacity / 1000**3); - $capacity = '450GB' if $capacity eq '449GB'; # quick fix for 450GB disks - $capacity = '300GB' if $capacity eq '299GB'; # quick fix for 300GB disks - $capacity = '146GB' if $capacity eq '147GB'; # quick fix for 146GB disks - $capacity = '100GB' if $capacity eq '99GB'; # quick fix for 100GB disks + if ($capacity == -1) { + # capacity is unknown + $capacity = 'Unknown Size'; + } + else { + $capacity = ceil($capacity / 1000**3) >= 1000 + ? sprintf '%.1fTB', ($capacity / 1000**4) + : sprintf '%.0fGB', ($capacity / 1000**3); + $capacity = '450GB' if $capacity eq '449GB'; # quick fix for 450GB disks + $capacity = '300GB' if $capacity eq '299GB'; # quick fix for 300GB disks + $capacity = '146GB' if $capacity eq '147GB'; # quick fix for 146GB disks + $capacity = '100GB' if $capacity eq '99GB'; # quick fix for 100GB disks + } # Capitalize only the first letter of the vendor name $vendor = (substr $vendor, 0, 1) . lc (substr $vendor, 1, length $vendor); @@ -1534,7 +1580,6 @@ return if $#controllers == -1; return if blacklisted('vdisk', 'all'); - my $id = undef; my $name = undef; my $nexus = undef; my $dev = undef; @@ -1553,7 +1598,6 @@ '1.3.6.1.4.1.674.10893.1.20.140.1.1.4' => 'virtualDiskState', '1.3.6.1.4.1.674.10893.1.20.140.1.1.6' => 'virtualDiskLengthInMB', '1.3.6.1.4.1.674.10893.1.20.140.1.1.13' => 'virtualDiskLayout', - '1.3.6.1.4.1.674.10893.1.20.140.1.1.17' => 'virtualDiskTargetID', '1.3.6.1.4.1.674.10893.1.20.140.1.1.20' => 'virtualDiskComponentStatus', '1.3.6.1.4.1.674.10893.1.20.140.1.1.21' => 'virtualDiskNexusID', ); @@ -1615,26 +1659,24 @@ VDISK: foreach my $out (@output) { if ($snmp) { - $id = $out->{virtualDiskTargetID}; - $dev = $out->{virtualDiskDeviceName}; + $dev = $out->{virtualDiskDeviceName} || 'Unknown device'; $state = get_hashval($out->{virtualDiskState}, \%vdisk_state); $layout = get_hashval($out->{virtualDiskLayout}, \%vdisk_layout); - $status = $snmp_status{$out->{virtualDiskComponentStatus}}; - $size = sprintf '%.2f GB', $out->{virtualDiskLengthInMB} / 1024; - $progr = q{}; # can't get this from SNMP(?) - $nexus = convert_nexus($out->{virtualDiskNexusID}); + $status = get_snmp_status($out->{virtualDiskComponentStatus}); + $size = sprintf '%.2f GB', ($out->{virtualDiskLengthInMB} || 0) / 1024; + $progr = q{}; # not available via SNMP + $nexus = convert_nexus(($out->{virtualDiskNexusID} || 9999)); } else { - $id = $out->{ID}; - $dev = $out->{'Device Name'}; - $state = $out->{State}; - $status = $out->{Status}; - $layout = $out->{Layout}; - $size = $out->{Size}; - $progr = ' [' . $out->{Progress} . ']'; + $dev = get_nonempty_string('Device Name', $out, 'Unknown device'); + $state = get_nonempty_string('State', $out, 'Unknown state'); + $status = get_nonempty_string('Status', $out, 'Unknown'); + $layout = get_nonempty_string('Layout', $out, 'Unknown layout'); + $size = get_nonempty_string('Size', $out, 'Unavailable'); $size =~ s{\A (.*GB).* \z}{$1}xms; - $nexus = join q{:}, $out->{ctrl}, $id; + $progr = ' [' . get_nonempty_string('Progress', $out, q{}) . ']'; $ctrl = $out->{ctrl}; + $nexus = join q{:}, $ctrl, get_nonempty_string('ID', $out, '9999'); } next VDISK if blacklisted('vdisk', $nexus); @@ -1757,21 +1799,21 @@ BATTERY: foreach my $out (@output) { if ($snmp) { - $status = $snmp_status{$out->{batteryComponentStatus}}; + $status = get_snmp_status($out->{batteryComponentStatus}); $state = get_hashval($out->{batteryState}, \%bat_state); $learn = get_hashval($out->{batteryLearnState}, \%bat_learn_state); $pred = get_hashval($out->{batteryPredictedCapacity}, \%bat_pred_cap); - $ctrl = $out->{batteryConnectionControllerNumber} - 1; - $nexus = convert_nexus($out->{batteryNexusID}); + $ctrl = ($out->{batteryConnectionControllerNumber} || 10000) - 1; + $nexus = convert_nexus(($out->{batteryNexusID} || 9999)); $id = $nexus; $id =~ s{\A \d+:(\d+) \z}{$1}xms; } else { - $id = $out->{'ID'}; - $state = $out->{'State'}; - $status = $out->{'Status'}; - $learn = $out->{'Learn State'}; - $pred = $out->{'Predicted Capacity Status'}; + $id = get_nonempty_string('ID', $out, 9999); + $state = get_nonempty_string('State', $out, 'Unknown state'); + $status = get_nonempty_string('Status', $out, 'Unknown'); + $learn = get_nonempty_string('Learn State', $out, 'Unknown learn state'); + $pred = get_nonempty_string('Predicted Capacity Status', $out, 'Unknown predicted capacity status'); $ctrl = $out->{'ctrl'}; $nexus = join q{:}, $out->{ctrl}, $id; } @@ -1844,7 +1886,6 @@ return if $#controllers == -1; return if blacklisted('conn', 'all'); - my $id = undef; my $nexus = undef; my $name = undef; my $state = undef; @@ -1856,7 +1897,6 @@ if ($snmp) { my %conn_oid = ( - '1.3.6.1.4.1.674.10893.1.20.130.2.1.1' => 'channelNumber', '1.3.6.1.4.1.674.10893.1.20.130.2.1.2' => 'channelName', '1.3.6.1.4.1.674.10893.1.20.130.2.1.3' => 'channelState', '1.3.6.1.4.1.674.10893.1.20.130.2.1.8' => 'channelComponentStatus', @@ -1912,25 +1952,21 @@ CHANNEL: foreach my $out (@output) { if ($snmp) { - $id = $out->{channelNumber} - 1; - $name = $out->{channelName}; - $status = $snmp_status{$out->{channelComponentStatus}}; + $name = $out->{channelName} || 'Unknown channel'; + $status = get_snmp_status($out->{channelComponentStatus}); $state = get_hashval($out->{channelState}, \%conn_state); $type = get_hashval($out->{channelBusType}, \%conn_bustype); - $nexus = convert_nexus($out->{channelNexusID}); + $nexus = convert_nexus(($out->{channelNexusID} || 9999)); $ctrl = $nexus; $ctrl =~ s{(\d+):\d+}{$1}xms; - # workaround for ancient OMSA versions - if (! defined $type) { $type = 'n/a'; } } else { - $id = $out->{'ID'}; - $name = $out->{'Name'}; - $state = $out->{'State'}; - $status = $out->{'Status'}; - $type = $out->{'Connector Type'}; + $name = get_nonempty_string('Name', $out, 'Unknown channel'); + $state = get_nonempty_string('State', $out, 'Unknown state'); + $status = get_nonempty_string('Status', $out, 'Unknown'); + $type = get_nonempty_string('Connector Type', $out, 'Unknown type'); $ctrl = $out->{ctrl}; - $nexus = join q{:}, $out->{ctrl}, $id; + $nexus = join q{:}, $out->{ctrl}, $out->{'ID'}; } next CHANNEL if blacklisted('conn', $nexus); @@ -2007,30 +2043,29 @@ ENCLOSURE: foreach my $out (@output) { if ($snmp) { - $id = $out->{enclosureNumber} - 1; - $name = $out->{enclosureName}; + $id = ($out->{enclosureNumber} || 10000) - 1; + $name = $out->{enclosureName} || 'Unknown enclosure'; $state = get_hashval($out->{enclosureState}, \%encl_state); - $status = $snmp_status{$out->{enclosureComponentStatus}}; - $firmware = exists $out->{enclosureFirmwareVersion} - ? $out->{enclosureFirmwareVersion} : 'N/A'; - $nexus = convert_nexus($out->{enclosureNexusID}); + $status = get_snmp_status($out->{enclosureComponentStatus}); + $firmware = $out->{enclosureFirmwareVersion} || 'N/A'; + $nexus = convert_nexus(($out->{enclosureNexusID} || 9999)); $ctrl = $nexus; $ctrl =~ s{\A (\d+):.* \z}{$1}xms; # for the next two, a value of 9999 means feature not available - $occupied_slots = exists $out->{enclosureOccupiedSlotCount} + $occupied_slots = defined $out->{enclosureOccupiedSlotCount} && $out->{enclosureOccupiedSlotCount} != 9999 ? $out->{enclosureOccupiedSlotCount} : undef; - $total_slots = exists $out->{enclosureTotalSlots} + $total_slots = defined $out->{enclosureTotalSlots} && $out->{enclosureTotalSlots} != 9999 ? $out->{enclosureTotalSlots} : undef; } else { - $id = $out->{ID}; - $name = $out->{Name}; - $state = $out->{State}; - $status = $out->{Status}; - $firmware = $out->{'Firmware Version'} ne 'Not Applicable' - ? $out->{'Firmware Version'} : 'N/A'; + $id = get_nonempty_string('ID', $out, 9999); + $name = get_nonempty_string('Name', $out, 'Unknown enclosure'); + $state = get_nonempty_string('State', $out, 'Unknown state'); + $status = get_nonempty_string('Status', $out, 'Unknown'); + $firmware = get_nonempty_string('Firmware Version', $out, 'N/A'); + $firmware =~ s{Not\sApplicable}{N/A}xms; $nexus = join q{:}, $out->{ctrl}, $id; $ctrl = $out->{ctrl}; } @@ -2079,7 +2114,6 @@ return if $#controllers == -1; return if blacklisted('encl_fan', 'all'); - my $id = undef; my $nexus = undef; my $name = undef; my $state = undef; @@ -2092,7 +2126,6 @@ if ($snmp) { my %fan_oid = ( - '1.3.6.1.4.1.674.10893.1.20.130.7.1.1' => 'fanNumber', '1.3.6.1.4.1.674.10893.1.20.130.7.1.2' => 'fanName', '1.3.6.1.4.1.674.10893.1.20.130.7.1.4' => 'fanState', '1.3.6.1.4.1.674.10893.1.20.130.7.1.11' => 'fanProbeCurrValue', @@ -2146,24 +2179,22 @@ FAN: foreach my $out (@output) { if ($snmp) { - $id = $out->{fanNumber} - 1; - $name = $out->{fanName}; + $name = $out->{fanName} || 'Unknown fan'; $state = get_hashval($out->{fanState}, \%fan_state); - $status = $snmp_status{$out->{fanComponentStatus}}; - $speed = $out->{fanProbeCurrValue}; - $encl_name = $out->{fanConnectionEnclosureName}; + $status = get_snmp_status($out->{fanComponentStatus}); + $speed = $out->{fanProbeCurrValue} || 'N/A'; + $encl_name = $out->{fanConnectionEnclosureName} || 'Unknown enclosure'; $encl_id = $snmp_enclosure{$out->{fanConnectionEnclosureNumber}}{nexus}; - $nexus = convert_nexus($out->{fanNexusID}); + $nexus = convert_nexus(($out->{fanNexusID} || 9999)); } else { - $id = $out->{'ID'}; - $name = $out->{'Name'}; - $state = $out->{'State'}; - $status = $out->{'Status'}; - $speed = $out->{'Speed'}; + $name = get_nonempty_string('Name', $out, 'Unknown fan'); + $state = get_nonempty_string('State', $out, 'Unknown state'); + $status = get_nonempty_string('Status', $out, 'Unknown'); + $speed = get_nonempty_string('Speed', $out, 'N/A'); $encl_id = join q{:}, $out->{ctrl}, $out->{'encl_id'}; $encl_name = $out->{encl_name}; - $nexus = join q{:}, $out->{ctrl}, $out->{'encl_id'}, $id; + $nexus = join q{:}, $out->{ctrl}, $out->{'encl_id'}, get_nonempty_string('ID', $out, '9999'); } next FAN if blacklisted('encl_fan', $nexus); @@ -2192,7 +2223,6 @@ return if $#controllers == -1; return if blacklisted('encl_ps', 'all'); - my $id = undef; my $nexus = undef; my $name = undef; my $state = undef; @@ -2204,7 +2234,6 @@ if ($snmp) { my %ps_oid = ( - '1.3.6.1.4.1.674.10893.1.20.130.9.1.1' => 'powerSupplyNumber', '1.3.6.1.4.1.674.10893.1.20.130.9.1.2' => 'powerSupplyName', '1.3.6.1.4.1.674.10893.1.20.130.9.1.4' => 'powerSupplyState', '1.3.6.1.4.1.674.10893.1.20.130.9.1.9' => 'powerSupplyComponentStatus', @@ -2257,22 +2286,20 @@ PS: foreach my $out (@output) { if ($snmp) { - $id = $out->{powerSupplyNumber}; - $name = $out->{powerSupplyName}; + $name = $out->{powerSupplyName} || 'Unknown PSU'; $state = get_hashval($out->{powerSupplyState}, \%ps_state); - $status = $snmp_status{$out->{powerSupplyComponentStatus}}; + $status = get_snmp_status($out->{powerSupplyComponentStatus}); $encl_id = $snmp_enclosure{$out->{powerSupplyConnectionEnclosureNumber}}{nexus}; - $encl_name = $out->{powerSupplyConnectionEnclosureName}; - $nexus = convert_nexus($out->{powerSupplyNexusID}); + $encl_name = $out->{powerSupplyConnectionEnclosureName} || 'Unknown enclosure'; + $nexus = convert_nexus(($out->{powerSupplyNexusID} || 9999)); } else { - $id = $out->{'ID'}; - $name = $out->{'Name'}; - $state = $out->{'State'}; - $status = $out->{'Status'}; + $name = get_nonempty_string('Name', $out, 'Unknown PSU'); + $state = get_nonempty_string('State', $out, 'Unknown state'); + $status = get_nonempty_string('Status', $out, 'Unknown'); $encl_id = join q{:}, $out->{ctrl}, $out->{'encl_id'}; $encl_name = $out->{encl_name}; - $nexus = join q{:}, $out->{ctrl}, $out->{'encl_id'}, $id; + $nexus = join q{:}, $out->{ctrl}, $out->{'encl_id'}, get_nonempty_string('ID', $out, '9999'); } next PS if blacklisted('encl_ps', $nexus); @@ -2301,7 +2328,6 @@ return if $#controllers == -1; return if blacklisted('encl_temp', 'all'); - my $id = undef; my $nexus = undef; my $name = undef; my $state = undef; @@ -2319,7 +2345,6 @@ if ($snmp) { my %temp_oid = ( - '1.3.6.1.4.1.674.10893.1.20.130.11.1.1' => 'temperatureProbeNumber', '1.3.6.1.4.1.674.10893.1.20.130.11.1.2' => 'temperatureProbeName', '1.3.6.1.4.1.674.10893.1.20.130.11.1.4' => 'temperatureProbeState', '1.3.6.1.4.1.674.10893.1.20.130.11.1.6' => 'temperatureProbeUnit', @@ -2378,39 +2403,32 @@ TEMP: foreach my $out (@output) { if ($snmp) { - $id = $out->{temperatureProbeNumber} - 1; - $name = $out->{temperatureProbeName}; + $name = $out->{temperatureProbeName} || 'Unknown temp probe'; $state = get_hashval($out->{temperatureProbeState}, \%temp_state); - $status = $snmp_status{$out->{temperatureProbeComponentStatus}}; - $unit = $out->{temperatureProbeUnit}; - $reading = exists $out->{temperatureProbeCurValue} - ? $out->{temperatureProbeCurValue} : '[N/A]'; - $max_warn = exists $out->{temperatureProbeMaxWarning} - ? $out->{temperatureProbeMaxWarning} : '[N/A]'; - $max_crit = exists $out->{temperatureProbeMaxCritical} - ? $out->{temperatureProbeMaxCritical} : '[N/A]'; - $min_warn = exists $out->{temperatureProbeMinWarning} - ? $out->{temperatureProbeMinWarning} : '[N/A]'; - $min_crit = exists $out->{temperatureProbeMinCritical} - ? $out->{temperatureProbeMinCritical} : '[N/A]'; + $status = get_snmp_probestatus($out->{temperatureProbeComponentStatus}); + $unit = $out->{temperatureProbeUnit} || 'Unknown unit'; + $reading = $out->{temperatureProbeCurValue} || '[N/A]'; + $max_warn = $out->{temperatureProbeMaxWarning} || '[N/A]'; + $max_crit = $out->{temperatureProbeMaxCritical} || '[N/A]'; + $min_warn = $out->{temperatureProbeMinWarning} || '[N/A]'; + $min_crit = $out->{temperatureProbeMinCritical} || '[N/A]'; $encl_id = $snmp_enclosure{$out->{temperatureConnectionEnclosureNumber}}{nexus}; - $encl_name = $out->{temperatureConnectionEnclosureName}; - $nexus = convert_nexus($out->{temperatureProbeNexusID}); + $encl_name = $out->{temperatureConnectionEnclosureName} || 'Unknown enclosure'; + $nexus = convert_nexus(($out->{temperatureProbeNexusID} || 9999)); } else { - $id = $out->{'ID'}; - $name = $out->{'Name'}; - $state = $out->{'State'}; - $status = $out->{'Status'}; + $name = get_nonempty_string('Name', $out, 'Unknown temp probe'); + $state = get_nonempty_string('State', $out, 'Unknown state'); + $status = get_nonempty_string('Status', $out, 'Unknown'); $unit = 'FIXME'; - $reading = $out->{'Reading'}; - $max_warn = $out->{'Maximum Warning Threshold'}; - $max_crit = $out->{'Maximum Failure Threshold'}; - $min_warn = $out->{'Minimum Warning Threshold'}; - $min_crit = $out->{'Minimum Failure Threshold'}; + $reading = get_nonempty_string('Reading', $out, '[N/A]'); + $max_warn = get_nonempty_string('Maximum Warning Threshold', $out, '[N/A]'); + $max_crit = get_nonempty_string('Maximum Failure Threshold', $out, '[N/A]'); + $min_warn = get_nonempty_string('Minimum Warning Threshold', $out, '[N/A]'); + $min_crit = get_nonempty_string('Minimum Failure Threshold', $out, '[N/A]'); $encl_id = join q{:}, $out->{ctrl}, $out->{'encl_id'}; $encl_name = $out->{encl_name}; - $nexus = join q{:}, $out->{ctrl}, $out->{'encl_id'}, $id; + $nexus = join q{:}, $out->{ctrl}, $out->{'encl_id'}, get_nonempty_string('ID', $out, '9999'); } next TEMP if blacklisted('encl_temp', $nexus); @@ -2519,7 +2537,6 @@ return if $#controllers == -1; return if blacklisted('encl_emm', 'all'); - my $id = undef; my $nexus = undef; my $name = undef; my $state = undef; @@ -2531,7 +2548,6 @@ if ($snmp) { my %emms_oid = ( - '1.3.6.1.4.1.674.10893.1.20.130.13.1.1' => 'enclosureManagementModuleNumber', '1.3.6.1.4.1.674.10893.1.20.130.13.1.2' => 'enclosureManagementModuleName', '1.3.6.1.4.1.674.10893.1.20.130.13.1.4' => 'enclosureManagementModuleState', '1.3.6.1.4.1.674.10893.1.20.130.13.1.11' => 'enclosureManagementModuleComponentStatus', @@ -2585,22 +2601,20 @@ EMM: foreach my $out (@output) { if ($snmp) { - $id = $out->{enclosureManagementModuleNumber} - 1; - $name = $out->{enclosureManagementModuleName}; + $name = $out->{enclosureManagementModuleName} || 'Unknown EMM'; $state = get_hashval($out->{enclosureManagementModuleState}, \%emms_state); - $status = $snmp_status{$out->{enclosureManagementModuleComponentStatus}}; + $status = get_snmp_status($out->{enclosureManagementModuleComponentStatus}); $encl_id = $snmp_enclosure{$out->{enclosureManagementModuleConnectionEnclosureNumber}}{nexus}; - $encl_name = $out->{enclosureManagementModuleConnectionEnclosureName}; - $nexus = convert_nexus($out->{enclosureManagementModuleNexusID}); + $encl_name = $out->{enclosureManagementModuleConnectionEnclosureName} || 'Unknown enclosure'; + $nexus = convert_nexus(($out->{enclosureManagementModuleNexusID} || 9999)); } else { - $id = $out->{'ID'}; - $name = $out->{'Name'}; - $state = $out->{'State'}; - $status = $out->{'Status'}; + $name = get_nonempty_string('Name', $out, 'Unknown EMM'); + $state = get_nonempty_string('State', $out, 'Unknown state'); + $status = get_nonempty_string('Status', $out, 'Unknown'); $encl_id = join q{:}, $out->{ctrl}, $out->{'encl_id'}; $encl_name = $out->{encl_name}; - $nexus = join q{:}, $out->{ctrl}, $out->{'encl_id'}, $id; + $nexus = join q{:}, $out->{ctrl}, $out->{'encl_id'}, get_nonempty_string('ID', $out, '9999'); } next EMM if blacklisted('encl_emm', $nexus); @@ -2687,22 +2701,26 @@ foreach my $out (@output) { @failures = (); # Initialize if ($snmp) { - $index = $out->{memoryDeviceIndex}; - $status = $snmp_status{$out->{memoryDeviceStatus}}; - $location = $out->{memoryDeviceLocationName}; - $size = sprintf '%d MB', $out->{memoryDeviceSize}/1024; - $modes = $out->{memoryDeviceFailureModes}; + $index = ($out->{memoryDeviceIndex} || 10000) - 1; + $status = get_snmp_status($out->{memoryDeviceStatus}); + $location = $out->{memoryDeviceLocationName} || 'Unknown location'; + $size = sprintf '%d MB', ($out->{memoryDeviceSize} || 0)/1024; + $modes = $out->{memoryDeviceFailureModes} || -9999; if ($modes > 0) { foreach my $mask (sort keys %failure_mode) { if (($modes & $mask) != 0) { push @failures, $failure_mode{$mask}; } } } + elsif ($modes == -9999) { + push @failures, q{ERROR: Failure modes not available via SNMP}; + } } else { - $index = $out->{'Type'} eq '[Not Occupied]' ? undef : $out->{'Index'}; - $status = $out->{'Status'}; - $location = $out->{'Connector Name'}; - $size = $out->{'Size'}; + my $type = get_nonempty_string('Type', $out, q{}); + $index = $type eq '[Not Occupied]' ? undef : get_nonempty_string('Index', $out, 9999); + $status = get_nonempty_string('Status', $out, 'Unknown'); + $location = get_nonempty_string('Connector Name', $out, 'Unknown location'); + $size = get_nonempty_string('Size', $out, 0); if (defined $size) { $size =~ s{\s\s}{ }gxms; } @@ -2804,24 +2822,22 @@ FAN: foreach my $out (@output) { if ($snmp) { - $index = $out->{coolingDeviceIndex}; - $status = $snmp_probestatus{$out->{coolingDeviceStatus}}; - $reading = $out->{coolingDeviceReading}; - $location = $out->{coolingDeviceLocationName}; - $max_crit = exists $out->{coolingDeviceUpperCriticalThreshold} - ? $out->{coolingDeviceUpperCriticalThreshold} : 0; - $max_warn = exists $out->{coolingDeviceUpperNonCriticalThreshold} - ? $out->{coolingDeviceUpperNonCriticalThreshold} : 0; - } - else { - $index = $out->{'Index'}; - $status = $out->{'Status'}; - $reading = $out->{'Reading'}; - $location = $out->{'Probe Name'}; - $max_crit = $out->{'Maximum Failure Threshold'} ne '[N/A]' - ? $out->{'Maximum Failure Threshold'} : 0; - $max_warn = $out->{'Maximum Warning Threshold'} ne '[N/A]' - ? $out->{'Maximum Warning Threshold'} : 0; + $index = ($out->{coolingDeviceIndex} || 10000) - 1; + $status = get_snmp_probestatus($out->{coolingDeviceStatus}); + $reading = $out->{coolingDeviceReading} || 0; + $location = $out->{coolingDeviceLocationName} || 'Unknown location'; + $max_crit = $out->{coolingDeviceUpperCriticalThreshold} || 0; + $max_warn = $out->{coolingDeviceUpperNonCriticalThreshold} || 0; + } + else { + $index = get_nonempty_string('Index', $out, 9999); + $status = get_nonempty_string('Status', $out, 'Unknown'); + $reading = get_nonempty_string('Reading', $out, 0); + $location = get_nonempty_string('Probe Name', $out, 'Unknown location'); + $max_crit = get_nonempty_string('Maximum Failure Threshold', $out, 0); + $max_warn = get_nonempty_string('Maximum Warning Threshold', $out, 0); + if ($max_crit eq '[N/A]') { $max_crit = 0; } + if ($max_warn eq '[N/A]') { $max_warn = 0; } $reading =~ s{\A (\d+).* \z}{$1}xms; $max_warn =~ s{\A (\d+).* \z}{$1}xms; $max_crit =~ s{\A (\d+).* \z}{$1}xms; @@ -2939,15 +2955,16 @@ if ($snmp) { @states = (); # contains states for the PS - $index = $out->{powerSupplyIndex} - 1; - $status = $snmp_status{$out->{powerSupplyStatus}}; + $index = ($out->{powerSupplyIndex} || 10000) - 1; + $status = get_snmp_status($out->{powerSupplyStatus}); $type = get_hashval($out->{powerSupplyType}, \%ps_type); $err_type = defined $out->{powerSupplyConfigurationErrorType} - ? $ps_config_error_type{$out->{powerSupplyConfigurationErrorType}} : undef; + ? get_hashval($out->{powerSupplyConfigurationErrorType}, \%ps_config_error_type) : undef; # get the combined state from the StatusReading OID + my $raw_state = $out->{powerSupplySensorState} || 0; foreach my $mask (sort keys %ps_state) { - if (($out->{powerSupplySensorState} & $mask) != 0) { + if (($raw_state & $mask) != 0) { push @states, $ps_state{$mask}; } } @@ -2961,10 +2978,10 @@ $state = join q{, }, @states; } else { - $index = $out->{'Index'}; - $status = $out->{'Status'}; - $type = $out->{'Type'}; - $state = $out->{'Online Status'}; + $index = get_nonempty_string('Index', $out, 9999); + $status = get_nonempty_string('Status', $out, 'Unknown'); + $type = get_nonempty_string('Type', $out, 'Unknown type'); + $state = get_nonempty_string('Online Status', $out, 'Unknown state'); } next PS if blacklisted('ps', $index); @@ -3051,36 +3068,46 @@ TEMP: foreach my $out (@output) { if ($snmp) { - $index = $out->{temperatureProbeIndex} - 1; - $status = $snmp_probestatus{$out->{temperatureProbeStatus}}; - $location = $out->{temperatureProbeLocationName}; - $reading = exists $out->{temperatureProbeReading} - ? $out->{temperatureProbeReading} / 10 : '[N/A]'; - $max_crit = exists $out->{temperatureProbeUpperCriticalThreshold} - ? $out->{temperatureProbeUpperCriticalThreshold} / 10 : '[N/A]'; - $max_warn = exists $out->{temperatureProbeUpperNonCriticalThreshold} - ? $out->{temperatureProbeUpperNonCriticalThreshold} / 10 : '[N/A]'; - $min_crit = exists $out->{temperatureProbeLowerCriticalThreshold} - ? $out->{temperatureProbeLowerCriticalThreshold} / 10 : '[N/A]'; - $min_warn = exists $out->{temperatureProbeLowerNonCriticalThreshold} - ? $out->{temperatureProbeLowerNonCriticalThreshold} / 10 : '[N/A]'; + $index = ($out->{temperatureProbeIndex} || 10000) - 1; + $status = get_snmp_probestatus($out->{temperatureProbeStatus}); + $location = $out->{temperatureProbeLocationName} || 'Unknown location'; $type = get_hashval($out->{temperatureProbeType}, \%probe_type); - $discrete = exists $out->{temperatureProbeDiscreteReading} - ? $out->{temperatureProbeDiscreteReading} : '[N/A]'; + $reading = $out->{temperatureProbeReading} || '[N/A]'; + $max_crit = $out->{temperatureProbeUpperCriticalThreshold} || '[N/A]'; + $max_warn = $out->{temperatureProbeUpperNonCriticalThreshold} || '[N/A]'; + $min_crit = $out->{temperatureProbeLowerCriticalThreshold} || '[N/A]'; + $min_warn = $out->{temperatureProbeLowerNonCriticalThreshold} || '[N/A]'; + $discrete = $out->{temperatureProbeDiscreteReading} || '[N/A]'; + + # If numeric values, i.e. not discrete + $reading /= 10 if $reading =~ m{\A \d+ \z}xms; + $max_crit /= 10 if $max_crit =~ m{\A \d+ \z}xms; + $max_warn /= 10 if $max_warn =~ m{\A \d+ \z}xms; + $min_crit /= 10 if $min_crit =~ m{\A \d+ \z}xms; + $min_warn /= 10 if $min_warn =~ m{\A \d+ \z}xms; + # workaround for bad temp probes if ($type eq 'AmbientESM' and $reading !~ m{\A \d+(\.\d+)? \z}xms) { $type = 'Discrete'; } } else { - $index = $out->{'Index'}; - $status = $out->{'Status'}; - $reading = $out->{'Reading'}; $reading =~ s{\.0\s+C}{}xms; - $location = $out->{'Probe Name'}; - $max_crit = $out->{'Maximum Failure Threshold'}; $max_crit =~ s{\.0\s+C}{}xms; - $max_warn = $out->{'Maximum Warning Threshold'}; $max_warn =~ s{\.0\s+C}{}xms; - $min_crit = $out->{'Minimum Failure Threshold'}; $min_crit =~ s{\.0\s+C}{}xms; - $min_warn = $out->{'Minimum Warning Threshold'}; $min_warn =~ s{\.0\s+C}{}xms; + $index = get_nonempty_string('Index', $out, 9999); + $status = get_nonempty_string('Status', $out, 'Unknown'); + $location = get_nonempty_string('Probe Name', $out, 'Unknown location'); + $reading = get_nonempty_string('Reading', $out, '[N/A]'); + $max_crit = get_nonempty_string('Maximum Failure Threshold', $out, '[N/A]'); + $max_warn = get_nonempty_string('Maximum Warning Threshold', $out, '[N/A]'); + $min_crit = get_nonempty_string('Minimum Failure Threshold', $out, '[N/A]'); + $min_warn = get_nonempty_string('Minimum Warning Threshold', $out, '[N/A]'); + + # Cleaning the temp readings + $reading =~ s{\.0\s+C}{}xms; + $max_crit =~ s{\.0\s+C}{}xms; + $max_warn =~ s{\.0\s+C}{}xms; + $min_crit =~ s{\.0\s+C}{}xms; + $min_warn =~ s{\.0\s+C}{}xms; + $type = $reading =~ m{\A\d+\z}xms ? 'AmbientESM' : 'Discrete'; $discrete = $reading; } @@ -3395,12 +3422,12 @@ foreach my $out (@output) { if ($snmp) { $index = exists $out->{processorDeviceStatusIndex} - ? $out->{processorDeviceStatusIndex} - 1 - : $out->{processorDeviceIndex} - 1; + ? ($out->{processorDeviceStatusIndex} || 10000) - 1 + : ($out->{processorDeviceIndex} || 10000) - 1; $status = exists $out->{processorDeviceStatusStatus} - ? $snmp_status{$out->{processorDeviceStatusStatus}} - : $snmp_status{$out->{processorDeviceStatus}}; - if (exists $out->{processorDeviceStatusReading}) { + ? get_snmp_status($out->{processorDeviceStatusStatus}) + : get_snmp_status($out->{processorDeviceStatus}); + if (defined $out->{processorDeviceStatusReading}) { my @states = (); # contains states for the CPU # get the combined state from the StatusReading OID @@ -3416,21 +3443,21 @@ else { $state = get_hashval($out->{processorDeviceStatusState}, \%cpu_state); } - $man = $out->{processorDeviceManufacturerName}; - $family = (exists $out->{processorDeviceFamily} - and exists $cpu_family{$out->{processorDeviceFamily}}) + $man = $out->{processorDeviceManufacturerName} || undef; + $family = (defined $out->{processorDeviceFamily} + and defined $cpu_family{$out->{processorDeviceFamily}}) ? $cpu_family{$out->{processorDeviceFamily}} : undef; - $speed = $out->{processorDeviceCurrentSpeed}; - $brand = $out->{processorDeviceBrandName}; + $speed = $out->{processorDeviceCurrentSpeed} || undef; + $brand = $out->{processorDeviceBrandName} || undef; } else { - $index = $out->{'Index'}; - $status = $out->{'Status'}; - $state = $out->{'State'}; - $brand = exists $out->{'Processor Brand'} ? $out->{'Processor Brand'} : undef; - $family = exists $out->{'Processor Family'} ? $out->{'Processor Family'} : undef; - $man = exists $out->{'Processor Manufacturer'} ? $out->{'Processor Manufacturer'} : undef; - $speed = exists $out->{'Current Speed'} ? $out->{'Current Speed'} : undef; + $index = get_nonempty_string('Index', $out, 9999); + $status = get_nonempty_string('Status', $out, 'Unknown'); + $state = get_nonempty_string('State', $out, 'Unknown state'); + $brand = get_nonempty_string('Processor Brand', $out, undef); + $family = get_nonempty_string('Processor Family', $out, undef); + $man = get_nonempty_string('Processor Manufacturer', $out, undef); + $speed = get_nonempty_string('Current Speed', $out, undef); } next CPU if blacklisted('cpu', $index); @@ -3441,7 +3468,7 @@ or (defined $out->{'Processor Brand'} and $out->{'Processor Brand'} eq '[Not Occupied]'); # Ignore unoccupied CPU slots (snmp) - if ($snmp and exists $out->{processorDeviceStatusReading} + if ($snmp and defined $out->{processorDeviceStatusReading} and $out->{processorDeviceStatusReading} == 0) { next CPU; } @@ -3525,18 +3552,18 @@ VOLT: foreach my $out (@output) { if ($snmp) { - $index = $out->{voltageProbeIndex} - 1; - $status = $snmp_probestatus{$out->{voltageProbeStatus}}; - $reading = exists $out->{voltageProbeReading} + $index = ($out->{voltageProbeIndex} || 10000) - 1; + $status = get_snmp_probestatus($out->{voltageProbeStatus}); + $reading = defined $out->{voltageProbeReading} ? sprintf('%.3f V', $out->{voltageProbeReading}/1000) : get_hashval($out->{voltageProbeDiscreteReading}, \%volt_discrete_reading); - $location = $out->{voltageProbeLocationName}; + $location = $out->{voltageProbeLocationName} || 'Unknown location'; } else { - $index = $out->{'Index'}; - $status = $out->{'Status'}; - $reading = $out->{'Reading'}; - $location = $out->{'Probe Name'}; + $index = get_nonempty_string('Index', $out, 9999); + $status = get_nonempty_string('Status', $out, 'Unknown'); + $reading = get_nonempty_string('Reading', $out, 'Unknown reading'); + $location = get_nonempty_string('Probe Name', $out, 'Unknown location'); } next VOLT if blacklisted('volt', $index); @@ -3599,16 +3626,16 @@ BATTERY: foreach my $out (@output) { if ($snmp) { - $index = $out->{batteryIndex} - 1; - $status = $snmp_status{$out->{batteryStatus}}; + $index = ($out->{batteryIndex} || 10000) - 1; + $status = get_snmp_status($out->{batteryStatus}); $reading = get_hashval($out->{batteryReading}, \%bat_reading); - $location = $out->{batteryLocationName}; + $location = $out->{batteryLocationName} || 'Unknown location'; } else { - $index = $out->{'Index'}; - $status = $out->{'Status'}; - $reading = $out->{'Reading'}; - $location = $out->{'Probe Name'}; + $index = get_nonempty_string('Index', $out, 9999); + $status = get_nonempty_string('Status', $out, 'Unknown'); + $reading = get_nonempty_string('Reading', $out, 'Unknown reading'); + $location = get_nonempty_string('Probe Name', $out, 'Unknown location'); } next BATTERY if blacklisted('bp', $index); @@ -3710,27 +3737,18 @@ AMP: foreach my $out (@output) { if ($snmp) { - $index = $out->{amperageProbeIndex} - 1; - $status = $snmp_status{$out->{amperageProbeStatus}}; + $index = ($out->{amperageProbeIndex} || 10000) - 1; + $status = get_snmp_probestatus($out->{amperageProbeStatus}); $type = get_hashval($out->{amperageProbeType}, \%amp_type); $reading = $type eq 'amperageProbeTypeIsDiscrete' ? get_hashval($out->{amperageProbeDiscreteReading}, \%amp_discrete) - : $out->{amperageProbeReading}; - $location = $out->{amperageProbeLocationName}; - $max_crit = exists $out->{amperageProbeUpperCriticalThreshold} - ? $out->{amperageProbeUpperCriticalThreshold} : 0; - $max_warn = exists $out->{amperageProbeUpperNonCriticalThreshold} - ? $out->{amperageProbeUpperNonCriticalThreshold} : 0; + : ($out->{amperageProbeReading} || 0); + $location = $out->{amperageProbeLocationName} || 'Unknown location'; + $max_crit = $out->{amperageProbeUpperCriticalThreshold} || 0; + $max_warn = $out->{amperageProbeUpperNonCriticalThreshold} || 0; $unit = exists $amp_unit{$amp_type{$out->{amperageProbeType}}} ? $amp_unit{$amp_type{$out->{amperageProbeType}}} : 'mA'; - # workaround for broken probes - if (!defined $reading) { - $type = 'amperageProbeTypeIsDiscrete'; - $reading = '[N/A]'; - $unit = q{}; - } - # calculate proper values and set unit for ampere probes if ($unit eq 'hA' and $type ne 'amperageProbeTypeIsDiscrete') { $reading /= 10; @@ -3740,30 +3758,43 @@ } } else { - $index = $out->{'Index'}; - next AMP if (!defined $index || $index !~ m/^\d+$/x); - $status = $out->{'Status'}; - $reading = $out->{'Reading'}; - $location = $out->{'Probe Name'}; - $max_crit = $out->{'Failure Threshold'} ne '[N/A]' - ? $out->{'Failure Threshold'} : 0; - $max_warn = $out->{'Warning Threshold'} ne '[N/A]' - ? $out->{'Warning Threshold'} : 0; + $index = get_nonempty_string('Index', $out, 9999); + $status = get_nonempty_string('Status', $out, 'Unknown'); + $reading = get_nonempty_string('Reading', $out, 'Unknown reading'); + $location = get_nonempty_string('Probe Name', $out, 'Unknown location'); + $max_crit = get_nonempty_string('Failure Threshold', $out, 0); + $max_warn = get_nonempty_string('Warning Threshold', $out, 0); + + $max_crit = 0 if $max_crit eq '[N/A]'; + $max_warn = 0 if $max_warn eq '[N/A]'; + $reading =~ s{\A (\d+.*?)\s+([a-zA-Z]+) \s*\z}{$1}xms; - $unit = $2; + $unit = $2 || 'unknown'; $max_warn =~ s{\A (\d+.*?)\s+[a-zA-Z]+ \s*\z}{$1}xms; $max_crit =~ s{\A (\d+.*?)\s+[a-zA-Z]+ \s*\z}{$1}xms; } next AMP if blacklisted('amp', $index); next AMP if $index !~ m{\A \d+ \z}xms; + + # Special case: Probe is present but unknown. This happens via + # SNMP on some systems where power monitoring capability is + # disabled due to non-redundant and/or non-instrumented power + # supplies. + # E.g. R410 with newer BMC firmware and 1 power supply + if ($snmp && $status eq 'Unknown' && $reading eq '[N/A]') { + next AMP; + } + $count{amp}++; + # Special case: Discrete reading if (defined $type and $type eq 'amperageProbeTypeIsDiscrete') { my $msg = sprintf 'Amperage probe %d [%s] is %s', $index, $location, $reading; report('chassis', $msg, $status2nagios{$status}, $index); } + # Default else { my $msg = sprintf 'Amperage probe %d [%s] reads %s %s', $index, $location, $reading, $unit; @@ -3773,7 +3804,6 @@ # Collect performance data if (defined $opt{perfdata}) { next AMP if $reading !~ m{\A \d+(\.\d+)? \z}xms; # discrete reading (not number) - #next AMP if $type eq 'amperageProbeTypeIsDiscrete'; my $label = join q{_}, 'pwr_mon', $index, lc $location; $label =~ s{\s}{_}gxms; push @perfdata, { @@ -3882,14 +3912,14 @@ INTRUSION: foreach my $out (@output) { if ($snmp) { - $index = $out->{intrusionIndex} - 1; - $status = $snmp_status{$out->{intrusionStatus}}; + $index = ($out->{intrusionIndex} || 10000) - 1; + $status = get_snmp_status($out->{intrusionStatus}); $reading = get_hashval($out->{intrusionReading}, \%int_reading); } else { - $index = $out->{'Index'}; - $status = $out->{'Status'}; - $reading = $out->{'State'}; + $index = get_nonempty_string('Index', $out, 9999); + $status = get_nonempty_string('Status', $out, 'Unknown'); + $reading = get_nonempty_string('State', $out, 'Unknown state'); } next INTRUSION if blacklisted('intr', $index); @@ -3912,6 +3942,128 @@ #----------------------------------------- +# CHASSIS: Check SD Card Device +#----------------------------------------- +sub check_sdcard { + return if blacklisted('sdcard', 'all'); + + my $index = undef; + my $status = undef; + my $state = undef; + my $location = undef; + my $capacity = undef; + my $setting = undef; + my @output = (); + + if ($snmp) { + my %sd_oid + = ( + '1.3.6.1.4.1.674.10892.1.1100.112.1.2.1' => 'sdCardDeviceIndex', + '1.3.6.1.4.1.674.10892.1.1100.112.1.3.1' => 'sdCardDeviceStatus', + '1.3.6.1.4.1.674.10892.1.1100.112.1.4.1' => 'sdCardDeviceType', + '1.3.6.1.4.1.674.10892.1.1100.112.1.7.1' => 'sdCardDeviceLocationName', + '1.3.6.1.4.1.674.10892.1.1100.112.1.8.1' => 'sdCardDeviceCardPresent', + '1.3.6.1.4.1.674.10892.1.1100.112.1.9.1' => 'sdCardDeviceCardState', + '1.3.6.1.4.1.674.10892.1.1100.112.1.10.1' => 'sdCardDeviceCardStorageSize', + ); + my $result = undef; + if ($opt{use_get_table}) { + my $sdCardDeviceTable = '1.3.6.1.4.1.674.10892.1.1100.112.1'; + $result = $snmp_session->get_table(-baseoid => $sdCardDeviceTable); + } + else { + $result = $snmp_session->get_entries(-columns => [keys %sd_oid]); + } + + # No SD cards is OK + return 0 if !defined $result; + + @output = @{ get_snmp_output($result, \%sd_oid) }; + } + else { + @output = @{ run_omreport("$omopt_chassis removableflashmedia") }; + } + + # Note: These values are bit fields, so combination values are possible. + my %sd_state + = ( + 0 => 'None', # state is none of the following: + 1 => 'Present', # device is present + 2 => 'IPMI-ready', # device is IPMI ready + 4 => 'Full-ready', # device is full ready + 8 => 'Offline', # device is offline + 16 => 'Failed', # device is failed + 32 => 'Active', # device is active + 64 => 'Bootable', # device is bootable + 128 => 'Write-protected', # device is write-protected + 256 => 'Standby', # device is in standby mode + ); + + my $c = 0; + SDCARD: + foreach my $out (@output) { + if ($snmp) { + $index = ($out->{sdCardDeviceIndex} || 10000) - 1; + $status = get_snmp_status($out->{sdCardDeviceStatus}); + + if (defined $out->{sdCardDeviceCardState}) { + my @states = (); # contains states SD card + + # get the combined state from the Device Status OID + foreach my $mask (sort keys %sd_state) { + if (($out->{sdCardDeviceCardState} & $mask) != 0) { + push @states, $sd_state{$mask}; + } + } + + # Finally, create the state string + $state = join q{, }, @states; + + # special case: absent + if ($out->{sdCardDeviceCardState} % 2 == 0) { + $state = 'Absent'; + } + } + + $location = $out->{sdCardDeviceLocationName} || 'Unknown location'; + $capacity = sprintf '%s MB', ($out->{sdCardDeviceCardStorageSize} || 'Unknown size'); + } + else { + $index = $c++; + $status = get_nonempty_string('Status', $out, 'Ok'); + $state = get_nonempty_string('State', $out, 'Unknown state'); + $location = get_nonempty_string('Connector Name', $out, 'Unknown location'); + $capacity = get_nonempty_string('Storage Size', $out, 'Unknown size'); + + $capacity =~ s{\[Not Available\]}{Unknown Size}; + } + + next SDCARD if blacklisted('sd', $index); + $count{sd}++ if $state ne 'Absent'; + + if ($status ne 'Ok') { + my $msg = sprintf 'SD Card %d needs attention: %s', + $index, $state; + report('chassis', $msg, $E_WARNING, $index); + } + # Special case: Not Present + elsif ($status eq 'Ok' and $state eq 'Absent') { + my $msg = sprintf 'SD Card %d [%s] is %s', + $index, $location, $state; + report('chassis', $msg, $E_OK, $index); + } + # Ok + else { + my $msg = sprintf 'SD Card %d [%s, %s] is %s', + $index, $location, $capacity, $state; + report('chassis', $msg, $E_OK, $index); + } + } + return; +} + + +#----------------------------------------- # CHASSIS: Check alert log #----------------------------------------- sub check_alertlog { @@ -3948,7 +4100,7 @@ $snmp_session->error; report('other', $msg, $E_UNKNOWN); } - $health = $snmp_status{$result->{$systemStateEventLogStatus}}; + $health = get_snmp_status($result->{$systemStateEventLogStatus}); } else { foreach (@{ run_command("$omreport $omopt_system esmlog -fmt ssv") }) { @@ -4050,7 +4202,7 @@ my @lines = <$INFO>; close $INFO; foreach (@lines) { - next if !m/\A (Chassis\sModel|Chassis\sService\sTag|Model|Service\sTag)/xms; + next if !m/\A (Chassis\sModel|Chassis\sService\sTag|Model|Service\sTag|System\sRevision)/xms; my ($key, $val) = split /;/xms; $key =~ s{\s+\z}{}xms; # remove trailing whitespace $val =~ s{\s+\z}{}xms; # remove trailing whitespace @@ -4060,6 +4212,9 @@ if ($key eq 'Chassis Service Tag' or $key eq 'Service Tag') { $sysinfo{serial} = $val; } + if ($key eq 'System Revision') { + $sysinfo{rev} = q{ } . $val; + } } } return; @@ -4132,6 +4287,7 @@ = ( '1.3.6.1.4.1.674.10892.1.300.10.1.9.1' => 'chassisModelName', '1.3.6.1.4.1.674.10892.1.300.10.1.11.1' => 'chassisServiceTagName', + '1.3.6.1.4.1.674.10892.1.300.10.1.48.1' => 'chassisSystemRevisionName', ); my $chassisInformationTable = '1.3.6.1.4.1.674.10892.1.300.10.1'; @@ -4146,6 +4302,9 @@ elsif (exists $chassis_oid{$oid} and $chassis_oid{$oid} eq 'chassisServiceTagName') { $sysinfo{serial} = $result->{$oid}; } + elsif (exists $chassis_oid{$oid} and $chassis_oid{$oid} eq 'chassisSystemRevisionName') { + $sysinfo{rev} = q{ } . $result->{$oid}; + } } } else { @@ -4400,6 +4559,7 @@ if ($check{batteries}) { check_batteries(); } if ($check{amperage}) { check_pwrmonitoring(); } if ($check{intrusion}) { check_intrusion(); } +if ($check{sdcard}) { check_sdcard(); } if ($check{alertlog}) { check_alertlog(); } if ($check{esmlog}) { check_esmlog(); } if ($check{esmhealth}) { check_esmlog_health(); } @@ -4433,11 +4593,21 @@ # Print messages if ($opt{debug}) { - print " System: $sysinfo{model}\n"; + # finding the mode of operation + my $mode = 'local'; + if ($snmp) { + # Setting the domain (IP version and transport protocol) + my $transport = $opt{tcp} ? 'TCP' : 'UDP'; + my $ipversion = $opt{ipv6} ? 'IPv6' : 'IPv4'; + $mode = "SNMPv$opt{protocol} $transport/$ipversion"; + } + + print " System: $sysinfo{model}$sysinfo{rev}"; + print q{ } x (25 - length "$sysinfo{model}$sysinfo{rev}"), "OMSA version: $sysinfo{om}\n"; print " ServiceTag: $sysinfo{serial}"; - print q{ } x (25 - length $sysinfo{serial}), "OMSA version: $sysinfo{om}\n"; + print q{ } x (25 - length $sysinfo{serial}), "Plugin version: $VERSION\n"; print " BIOS/date: $sysinfo{bios} $sysinfo{biosdate}"; - print q{ } x (25 - length "$sysinfo{bios} $sysinfo{biosdate}"), "Plugin version: $VERSION\n"; + print q{ } x (25 - length "$sysinfo{bios} $sysinfo{biosdate}"), "Operation mode: $mode\n"; if ($#report_storage >= 0) { print "-----------------------------------------------------------------------------\n"; print " Storage Components \n"; @@ -4548,19 +4718,20 @@ 'alertlog' => $snmp ? 'OK - not supported via snmp' : "OK - Alert Log content: $count{alert}{Ok} ok, $count{alert}{'Non-Critical'} warning and $count{alert}{Critical} critical", 'esmlog' => "OK - ESM Log content: $count{esm}{Ok} ok, $count{esm}{'Non-Critical'} warning and $count{esm}{Critical} critical", 'esmhealth' => "ESM LOG OK - less than 80% used", + 'sdcard' => "SD CARDS OK - $count{sd} SD cards installed", ); print $okmsg{$opt{only}}; } elsif ($exit_code == $E_OK && !$opt{debug}) { if (defined $opt{htmlinfo}) { - printf q{OK - System: '<a href="%s">%s</a>', SN: '<a href="%s">%s</a>'}, - documentation_url($sysinfo{model}), $sysinfo{model}, + printf q{OK - System: '<a href="%s">%s%s</a>', SN: '<a href="%s">%s</a>'}, + documentation_url($sysinfo{model}), $sysinfo{model}, $sysinfo{rev}, warranty_url($sysinfo{serial}), $sysinfo{serial}; } else { - printf q{OK - System: '%s', SN: '%s'}, - $sysinfo{model}, $sysinfo{serial}; + printf q{OK - System: '%s%s', SN: '%s'}, + $sysinfo{model}, $sysinfo{rev}, $sysinfo{serial}; } if ($check{memory}) { @@ -4630,13 +4801,13 @@ if ($opt{extinfo}) { print $linebreak; if (defined $opt{htmlinfo}) { - printf '------ SYSTEM: <a href="%s">%s</a>, SN: <a href="%s">%s</a>', - documentation_url($sysinfo{model}), $sysinfo{model}, + printf '------ SYSTEM: <a href="%s">%s%s</a>, SN: <a href="%s">%s</a>', + documentation_url($sysinfo{model}), $sysinfo{model}, $sysinfo{rev}, warranty_url($sysinfo{serial}), $sysinfo{serial}; } else { - printf '------ SYSTEM: %s, SN: %s', - $sysinfo{model}, $sysinfo{serial}; + printf '------ SYSTEM: %s%s, SN: %s', + $sysinfo{model}, $sysinfo{rev}, $sysinfo{serial}; } } if (defined $opt{postmsg}) { @@ -4656,7 +4827,7 @@ if (defined $post) { print $linebreak; $post =~ s{[%]s}{$sysinfo{serial}}gxms; - $post =~ s{[%]m}{$sysinfo{model}}gxms; + $post =~ s{[%]m}{$sysinfo{model}$sysinfo{rev}}gxms; $post =~ s{[%]b}{$sysinfo{bios}}gxms; $post =~ s{[%]d}{$sysinfo{biosdate}}gxms; $post =~ s{[%]o}{$sysinfo{osname}}gxms; | ||
[+] | Changed | check_openmanage-3.6.2.tar.gz/check_openmanage.8 ^ |
@@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "CHECK_OPENMANAGE 8" -.TH CHECK_OPENMANAGE 8 "2010-06-29" "check_openmanage 3.5.10" "Nagios plugin" +.TH CHECK_OPENMANAGE 8 "2010-11-11" "check_openmanage 3.6.2" "Nagios plugin" .SH "NAME" check_openmanage \- Nagios plugin for checking the hardware status on Dell servers running OpenManage @@ -361,6 +361,14 @@ .IX Item "--port PORT" \&\s-1SNMP\s0 port of the remote (monitored) system. Defaults to the well-known \&\s-1SNMP\s0 port 161. +.IP "\-6, \-\-ipv6" 4 +.IX Item "-6, --ipv6" +This option will cause the plugin to use IPv6. The default is IPv4 if +the option is not present. +.IP "\-\-tcp" 4 +.IX Item "--tcp" +This option will cause the plugin to use \s-1TCP\s0 as transport +protocol. The default is \s-1UDP\s0 if the option is not present. .IP "\-U, \-\-username \fI\s-1SECURITYNAME\s0\fR" 4 .IX Item "-U, --username SECURITYNAME" [SNMPv3] The User-based Security Model (\s-1USM\s0) used by SNMPv3 requires @@ -534,11 +542,17 @@ .IP "\fBintr\fR" 8 .IX Item "intr" Intrusion sensor +.IP "\fBsd\fR" 8 +.IX Item "sd" +\&\s-1SD\s0 card .RE .RS 4 .RE .SH "CHECK CONTROL" .IX Header "CHECK CONTROL" +.IP "\-\-no\-storage" 4 +.IX Item "--no-storage" +Turn off storage checking. This is an alias for \f(CW\*(C`\-\-check storage=0\*(C'\fR. .IP "\-\-only \fI\s-1KEYWORD\s0\fR" 4 .IX Item "--only KEYWORD" This option can be specifed once and expects a keyword. The different @@ -585,6 +599,9 @@ .IP "\fBintrusion\fR" 4 .IX Item "intrusion" Only check chassis intrusion +.IP "\fBsdcard\fR" 4 +.IX Item "sdcard" +Only check \s-1SD\s0 cards .IP "\fBesmhealth\fR" 4 .IX Item "esmhealth" Only check \s-1ESM\s0 log overall health, i.e. fill grade @@ -644,6 +661,9 @@ .IP "\fBintrusion\fR" 4 .IX Item "intrusion" Check chassis intrusion. Default: \s-1ON\s0 +.IP "\fBsdcard\fR" 4 +.IX Item "sdcard" +Check \s-1SD\s0 cards. Default: \s-1ON\s0 .IP "\fBesmhealth\fR" 4 .IX Item "esmhealth" Check the \s-1ESM\s0 log health, i.e. fill grade. Default: \s-1ON\s0 | ||
Changed | check_openmanage-3.6.2.tar.gz/check_openmanage.exe ^ | |
[+] | Changed | check_openmanage-3.6.2.tar.gz/check_openmanage.pod ^ |
@@ -2,7 +2,7 @@ # # pod2man -s 8 -r "`./check_openmanage -V | head -n 1`" -c 'Nagios plugin' check_openmanage.pod check_openmanage.8 # -# $Id: check_openmanage.pod 17782 2010-06-29 15:04:10Z trondham $ +# $Id: check_openmanage.pod 18673 2010-11-10 23:24:19Z trondham $ =head1 NAME @@ -279,6 +279,16 @@ SNMP port of the remote (monitored) system. Defaults to the well-known SNMP port 161. +=item -6, --ipv6 + +This option will cause the plugin to use IPv6. The default is IPv4 if +the option is not present. + +=item --tcp + +This option will cause the plugin to use TCP as transport +protocol. The default is UDP if the option is not present. + =item -U, --username I<SECURITYNAME> [SNMPv3] The User-based Security Model (USM) used by SNMPv3 requires @@ -492,6 +502,10 @@ Intrusion sensor +=item B<sd> + +SD card + =back =back @@ -500,6 +514,10 @@ =over 4 +=item --no-storage + +Turn off storage checking. This is an alias for C<--check storage=0>. + =item --only I<KEYWORD> This option can be specifed once and expects a keyword. The different @@ -561,6 +579,10 @@ Only check chassis intrusion +=item B<sdcard> + +Only check SD cards + =item B<esmhealth> Only check ESM log overall health, i.e. fill grade @@ -637,6 +659,10 @@ Check chassis intrusion. Default: ON +=item B<sdcard> + +Check SD cards. Default: ON + =item B<esmhealth> Check the ESM log health, i.e. fill grade. Default: ON | ||
[+] | Changed | check_openmanage-3.6.2.tar.gz/check_openmanage.spec ^ |
@@ -1,6 +1,6 @@ Summary: Nagios plugin to monitor hardware health on Dell servers Name: check_openmanage -Version: 3.5.10 +Version: 3.6.2 Release: 1%{?dist} License: GPL Packager: Trond Hasle Amundsen <t.h.amundsen@usit.uio.no> @@ -48,6 +48,15 @@ %changelog +* Thu Nov 25 2010 Trond H. Amundsen <t.h.amundsen@usit.uio.no> - 3.6.2-1 +- Version 3.6.2 + +* Tue Nov 2 2010 Trond H. Amundsen <t.h.amundsen@usit.uio.no> - 3.6.1-1 +- Version 3.6.1 + +* Mon Aug 30 2010 Trond H. Amundsen <t.h.amundsen@usit.uio.no> - 3.6.0-1 +- Version 3.6.0 + * Wed Jul 14 2010 Trond H. Amundsen <t.h.amundsen@usit.uio.no> - 3.5.10-1 - Version 3.5.10 |