Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
home:mnhauke:monitoring
monitoring-plugins-snmp_brocade
check_snmp_brocade_3.2.0
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File check_snmp_brocade_3.2.0 of Package monitoring-plugins-snmp_brocade
#!/usr/bin/perl # Author: Martin Fuerstenau, Oce Printing Systems # martin.fuerstenau_at_oce.com or Martin.fuerstenau_at_maerber.de # # Copyright (c) 2011, Martin Fuerstenau <martin.fuerstenau@oce.com> # # This module is free software; you can redistribute it and/or modify it # under the terms of GNU General Public License (GPL) version 3. # # Purpose and features of the program: # # - check_snmp_brocade is a Nagios plugin to monitor the status of # a single fc-port on a Brocade (labeled or original) fibre-channel switch. # # History and Changes: # # - 15 Sep 2011 Version 1 # - First released version. Versions before number 1 were derived from the work # of Christian Heim. But now the complete code was rewritten. # # - 17 Sep 2011 Version 1.1 # - Switched from net-snmp-perl to perl-Net-SNMP. Although the coding is # a little bit more complex we have the abibility to get complete tables # tables with one request which makes getting sensor data (temp, fan, power) # more easy. # - SNMP version no longer hard coded. Default is 1 but 2c can be handeled over. # - If 161 can't be used an alternative port can be given. # # - 22 Sep 2011 Version 1.2 # - Removed subroutine check_port_status because it was only used once. so it # doesn't mad sense. # - Try to get partner WWN if possible # # - 20 Mar 2012 Version 1.3 # - Added an "offset" for the fc port. In GUI and from the commandline port numbering # starts with 0. SNMP starts with 1. Here we have we hava an offset which can lead # to misunderstandings and confusion. Fixed. # - Detects Fabric Watch license. If Fabric Watch is enabled we are able to get # a lot more information. # - Kicked out some subroutines. # - snmpget - This was not effective. Before every get a new session was established. # Data had to be handled over and passed back. Thee effective code where to lines. # It was a nice at a first look but it was more effective to place the code # in the main function # - The same for the perfdata. The routine was only used once. So it doesn't make # sense to have a subroutine. # # - 21 Apr 2012 Version 2.0.0 # - Bugfix: If a SNMP session can't be established the program exits with an error message. # The next line was a session close. this caused un unwanted error message because # there was no session. Fixed. # - The program part for getting port data was part of the main code. Moved to a subroutine. # - The program part checking for an enabled Fabric Watch license was part of the getting # port data code. Moved to a subroutine. # - New flag --multiline. Multiline output in overview. This mean technically that # a multiline output uses a HTML <br> for the GUI instead of the default (\n). Be aware # that your messing connections (email, SMS...) must use a filter to file out the <br>. # A sed oneliner like the following will do the job: # sed 's/<[^<>]*>//g' # - New flag -s|--systeminfo. Get global data like boot date, overall status, reachability etc # - New flags --sfptemp, --sfptemp_warn and --allports. # Checks the temperature of all SFPs. --sfptemp_warn=INT will set the warrning offset to the # critical temperature as delivered by the system. Default is $SPF_TempHighWarn_def in Celsius. # --allports will show all ports. Default is only to show ports which are too hot.--sfptemp_warn # and --allports MUST be used with --sfptemp. # # - 21 May 2012 Version 2.0.1 # - New flag --maxsfptemp. # Little bugfix. The SFP temperatures delivered by the system may be kinda bullshit. So on 5300 # min. is reported around -30 degrees celsius and max. is +90 degrees celsius. Because the lower is # scrap we have used 0 degrees Celsius as the lowest when designing this plugin. But late we # reckognized that 90 degrees is also too high. flexoptics for example say 0 - 70 degrees. Therefore # we changed some things. If $SFP_TempHigh is no set via commandline the temperature from the # system will be taken. # # - 30 May 2012 Version 2.1.0 # - First publically available version # - New flag --sensor # Additional flag to -s. Delivers the values of the onboard sensors for temperature, fans and power. # # - 5 Jun 2013 Version 3.2.0 # - Implemented the changes of Rene Koch, ovido gmbh (r.koch_at_ovido.at) # - 26 April 2013 Version 3.0.0 # - Added support for SNMPv3 (Rene Koch) # - Changed exit code to 3 (UNKNOWN) if input validation fails # - Not implemented because of a possible misunderstanding. Perhaps later. # - 06 May 2013 Version 3.1.0 # - Added warning and critical checks (Rene Koch) # - Changed exit code for failed input validation back to 1. Why? 3 means UNKNOWN. UNKNOWN is a state # returned from the plugin if the plugin receives data (or nothing) from the checked item where it is not # possible to determine a correct error state. But wrong input validation is a minor error. Therefore # WARNING is the correct state. # - Did some cosmetics. Like many people Rene uses the opening curly brace in the same line as the if statement. # I always prefer both curly braces in the same column for better readability. # - Cleaned up the code # - Replaced tabs with blanks in formatting. Why? Different editors -> different tab stops -> rotten format in editor # - Rewritten session establishing section. No need for elsif. use strict; use Getopt::Long; use File::Basename; use Net::SNMP; #--- Start presets and declarations ------------------------------------- # 1. Define variables # General stuff my $version = '3.1'; my $progname = basename($0); my $help; # If some help is wanted.... my $NoA=""; # Number of arguments handled over # the program my $main_option_counter = 0; # Needed to check that there is only one # main option selected # Some SNMP stuff my $result; # Points to result hash my $session; # Point to the SNMP session my $error; # If shit happens.... my $oid; # To store OID my $snmpversion; # SNMP version my $snmpversion_def = 1; # SNMP version default my $snmpport; # SNMP port my $snmpport_def = "161"; # SNMP port default my $hostname; # Contains the target hostname my $community; # Contains SNMP community of the target hostname my $snmpv3seclevel; # SNMPv3 securityLevel my $snmpv3authproto; # SNMPv3 auth proto my $snmpv3privproto; # SNMPv3 priv proto my $snmpv3secname; # SNMPv3 username my $snmpv3authpassword; # SNMPv3 authentication password my $snmpv3privpasswd; # SNMPv3 privacy password my $snmpv3context; # SNMPv3 context name # For the switch my $systeminfo; # If we wanna get the global system information my $fc_port; # Fibre channel port to monitor - 1st port = 0 my $fc_port_snmp; # Fibre channel port to monitor in SNMP - 1st port = 1 # Port numbering in O and in GUI starts with 0 but SNMP # uses 1. This can lead to misunderstandings. my $perf_data; # Switch to detect if performance data is desired my $port_adm_state_key; # Port Admin Status my $port_opr_state_key; # Port Operation Status my $port_phy_state_key; # Port Physical Status my $port_link_state; # Port Link Status 1 - enabled, 2 - disabled, 3 - loopback my $partner_wwn; # Needed to detect the partner my @partner_wwn; # Needed to detect the partner my $FabricWatchLicense; # Fabric Watch licensed? 1 = licensed, 2 0 not licensed # for the output of performance data we need the following stats: my $swFCPortTxWords; # stat_wtx (words out) my $swFCPortRxWords; # stat_wrx (words in) my $swFCPortTxFrames; # stat_ftx (frames out) my $swFCPortRxFrames; # stat_wtx (frames in) my $swFCPortRxEncInFrs; # er_enc_in (encoding err) my $swFCPortRxCrcs; # er_crc my $swFCPortRxTruncs; # er_trunc my $swFCPortRxTooLongs; # er_toolong my $swFCPortRxBadEofs; # er_bad_eof my $swFCPortRxEncOutFrs; # er_enc_eof my $swFCPortC3Discards; # er_c3_timeout my $r_code = 0; # Exitcode for get_out my $r_message; # Message for get_out my $tmp_message = ""; # Temp message for get_out my $multiline; # Multiline output in overview. This mean technically that # a multiline output uses a HTML <br> for the GUI instead of # Be aware that your messing connections (email, SMS...) must use # a filter to file out the <br>. A sed oneliner like the following # will do the job: # sed 's/<[^<>]*>//g' my $multiline_def="\n"; # Default for $multiline; my $global; # Global data like boot date, overall status etc. my $sfp_temp; # SFP transceiver temperature my $SFP_TempHigh; # Transceiver port high temperature. This is the critical limit. # Transceiver port high temperature from the system. # This is the default critical limit. If $SFP_TempHigh is set by the commandline # it will replace the value deliverd by the system. my $SFP_TempHighWarn; # Transceiver port high temperature warning. This is an offset to # $SFP_TempHigh. my $SFP_TempHighWarn_def = 10; # This is the default offset for $SPF_TempHighWarn my $allports; # Default is only to show ports which are too hot. With this flag all # ports will be shown. my $sensorinfo; # # 2. Define arrays and hashes # Assign some strings in a hash. It makes it more comfortable to convert numeric values to strings my %port_adm_state = ( "1" => "online", "2" => "offline", "3" => "testing", "4" => "faulty" ); my %port_opr_state = ( "0" => "unknown", "1" => "online", "2" => "offline", "3" => "testing", "4" => "faulty" ); my %port_phy_state = ( "1" => "noCard", "2" => "noTransceiver", "3" => "LaserFault", "4" => "noLight", "5" => "noSync", "6" => "inSync", "7" => "portFault", "8" => "diagFault", "9" => "lockRef" ); #--- End presets -------------------------------------------------------- # First we have to fix the number of arguments $NoA=$#ARGV; Getopt::Long::Configure('bundling'); GetOptions ("H=s" => \$hostname, "hostname=s" => \$hostname, "C=s" => \$community, "community=s" => \$community, "s" => \$systeminfo, "systeminfo" => \$systeminfo, "sensor" => \$sensorinfo, "sfptemp" => \$sfp_temp, "sfptemp_warn=i" => \$SFP_TempHighWarn, "allports" => \$allports, "P=i" => \$fc_port, "fcport=i" => \$fc_port, "p" => \$perf_data, "performancedata" => \$perf_data, "v=s" => \$snmpversion, "snmpversion=s" => \$snmpversion, "port=s" => \$snmpport, "L=s" => \$snmpv3seclevel, "seclevel=s" => \$snmpv3seclevel, "a=s" => \$snmpv3authproto, "authproto=s" => \$snmpv3authproto, "x=s" => \$snmpv3privproto, "privproto=s" => \$snmpv3privproto, "U=s" => \$snmpv3secname, "secname=s" => \$snmpv3secname, "A=s" => \$snmpv3authpassword, "authpassword=s" => \$snmpv3authpassword, "X=s" => \$snmpv3privpasswd, "privpasswd=s" => \$snmpv3privpasswd, "n=s" => \$snmpv3context, "context=s" => \$snmpv3context, "multiline" => \$multiline, "maxsfptemp=s" => \$SFP_TempHigh, "h" => \$help, "help" => \$help); # Several checks to check parameters if ($help) { help(); exit 0; } # Multiline output in GUI overview? if ($multiline) { $multiline = "<br>"; } else { $multiline = $multiline_def; } # Right number of arguments (therefore NoA :-)) ) if ( $NoA == -1 ) { usage(); exit 1; } if (!$hostname) { print "Host name/address not specified\n\n"; usage(); exit 1; } if (!$community && !$snmpv3secname) { $community = "public"; print "No community string supplied - using public\n"; } # Here we add the offset of 1 to the given port to have the appropriate value for SNMP # You can not test for the variable like if ($fc_port) because a value of 0 also means undefined if (length $fc_port) { $fc_port_snmp = $fc_port + 1; } # One valid category must be selected if (!$systeminfo && !$fc_port_snmp && !$sfp_temp) { print "\nYou must select systeminfo or sfptemp or a port!\n\n"; usage(); exit 1; } if (!$snmpversion) { $snmpversion = $snmpversion_def; } if ($snmpversion ne "1" && $snmpversion ne "2c" && $snmpversion ne "3") { print "SNMP version ($snmpversion) entered is neither 1, 2c nor 3. Only these are supported versions\n\n"; usage(); exit 1; } # SNMPv3 checks if ($snmpversion eq "3") { # securityLevel if (! $snmpv3seclevel) { $snmpv3seclevel = "noAuthNoPriv"; } # username if (! $snmpv3secname) { print "SNMP version 3 requires an username!\n\n"; usage(); exit 1; } if ($snmpv3seclevel ne "noAuthNoPriv" && $snmpv3seclevel ne "authNoPriv" && $snmpv3seclevel ne "authPriv") { print "SNMP version 3 security level ($snmpv3seclevel) invalid!\n\n"; usage(); exit 1; } if ($snmpv3seclevel eq "authNoPriv" || $snmpv3seclevel eq "authPriv") { # authproto if (! $snmpv3authproto) { $snmpv3authproto = "md5"; } else { $snmpv3authproto = lc($snmpv3authproto); } if ($snmpv3authproto ne "md5" && $snmpv3authproto ne "sha") { print "SNMP version 3 auth proto ($snmpv3authproto) invalid!\n\n"; usage(); exit 1; } # auth password if (! $snmpv3authpassword) { print "SNMP version 3 $snmpv3seclevel requires auth password!\n\n"; usage(); exit 1; } } if ($snmpv3seclevel eq "authPriv") { # privproto if (! $snmpv3privproto) { $snmpv3privproto = "3des"; } else { $snmpv3privproto = lc($snmpv3privproto); } if ($snmpv3privproto ne "3des" && $snmpv3privproto ne "aes") { print "SNMP version 3 priv proto ($snmpv3privproto) invalid!\n\n"; usage(); exit 1; } # priv password if (! $snmpv3privpasswd) { print "SNMP version 3 $snmpv3seclevel requires priv password!\n\n"; usage(); exit 1; } } } if (!$snmpport) { $snmpport = $snmpport_def; } if ($fc_port_snmp) { $main_option_counter++; } if ($systeminfo) { $main_option_counter++; } if ($sfp_temp) { $main_option_counter++; } if ($main_option_counter > 1) { print "You have to select either a port to check OR the systeminfo (global info, fan, powersupply etc.) NOT both!\n\n"; usage(); exit 1; } # # So here starts the main section.------------------------------------------------------------------ # # First open a session if ($snmpversion eq "3") { if ($snmpv3seclevel eq "noAuthNoPriv") { ($session, $error) = Net::SNMP->session( -hostname => $hostname, -version => $snmpversion, -port => $snmpport, -retries => 10, -timeout => 10, -username => $snmpv3secname ); } if ($snmpv3seclevel eq "authNoPriv") { ($session, $error) = Net::SNMP->session( -hostname => $hostname, -version => $snmpversion, -port => $snmpport, -retries => 10, -timeout => 10, -username => $snmpv3secname, -authprotocol => $snmpv3authproto, -authpassword => $snmpv3authpassword ); } if ($snmpv3seclevel eq "authPriv") { ($session, $error) = Net::SNMP->session( -hostname => $hostname, -version => $snmpversion, -port => $snmpport, -retries => 10, -timeout => 10, -username => $snmpv3secname, -authprotocol => $snmpv3authproto, -authpassword => $snmpv3authpassword, -privprotocol => $snmpv3privproto, -privpassword => $snmpv3privpasswd ); } } else { ($session, $error) = Net::SNMP->session( -hostname => $hostname, -version => $snmpversion, -community => $community, -port => $snmpport, -retries => 10, -timeout => 10 ); } # If there is something wrong...exit if (!defined($session)) { printf("ERROR: %s.\n", $error); print "Exiting\n"; exit 1; } # If we wanna get the system status here is the starting point if ($systeminfo) { get_system_info(); # If we wanna get sensors like fan, power and onboard temperature # here is the starting point if ($sensorinfo) { get_sensor_info(); } } # If we wanna get port data here is the starting point if ($fc_port_snmp) { get_port_data(); } # If we wanna get SFP temperature here is the starting point if ($sfp_temp) { get_sfp_temp(); } # And now we leave get_out($r_code, "$r_message"); # ---- Subroutines ------------------------------------------------------- sub get_result() { my $tmp_result = undef; # handle snmp v3 context name if ($snmpv3context) { $tmp_result = $session->get_request( -contextname => $snmpv3context, -varbindlist => ["$oid"] ); } else { $tmp_result = $session->get_request( -varbindlist => ["$oid"] ); } return $tmp_result; } sub get_table() { my $tmp_result = undef; # handle snmp v3 context name if ($snmpv3context) { $tmp_result = $session->get_table( -contextname => $snmpv3context, -baseoid => $oid ); } else { $tmp_result = $session->get_table( -baseoid => $oid ); } return $tmp_result; } sub get_request() { my $tmp_result = undef; # handle snmp v3 context name if ($snmpv3context) { $tmp_result = $session->get_request( -contextname => $snmpv3context, -varbindlist => ["$oid"] ); } else { $tmp_result = $session->get_request( -varbindlist => ["$oid"] ); } return $tmp_result; } sub get_system_info() { # Global status data my $tmp_r_message; my $tmp_r_code; # Boot date $oid = ".1.3.6.1.4.1.1588.2.1.1.1.1.2.0"; $result = get_result(); if ($session->error_status() == 0) { $tmp_r_message = $$result{$oid}; chomp $tmp_r_message; $r_message = "Boot date: $tmp_r_message$multiline"; } else { $r_message = "Boot date: Not supported$multiline"; } # Firmware version $oid = ".1.3.6.1.4.1.1588.2.1.1.1.1.6.0"; $result = get_result(); if ($session->error_status() == 0) { $tmp_r_message = $$result{$oid}; chomp $tmp_r_message; $r_message = $r_message . "Firmware version: $tmp_r_message$multiline"; } else { $r_message = "Firmware version: Not supported$multiline"; } # Model $oid = ".1.3.6.1.2.1.47.1.1.1.1.2.1"; $result = get_result(); if ($session->error_status() == 0) { $tmp_r_message = $$result{$oid}; chomp $tmp_r_message; $r_message = $r_message . "Model: $tmp_r_message$multiline"; } else { $r_message = "Model: Not supported$multiline"; } # Serialnumber $oid = ".1.3.6.1.2.1.47.1.1.1.1.11.1"; $result = get_result(); if ($session->error_status() == 0) { $tmp_r_message = $$result{$oid}; chomp $tmp_r_message; $r_message = $r_message . "Serialnumber: $tmp_r_message$multiline"; } else { $r_message = "Serialnumber: Not supported$multiline"; } # Operational Status # The current operational status of the switch. # The states are as follow: # 1 - online means the switch is accessible by an external Fibre Channel port # 2 - offline means the switch is not accessible # 3 - testing means the switch is in a built-in test mode and is not accessible # by an external Fibre Channel port # 4- faulty means the switch is not operational. $oid = ".1.3.6.1.4.1.1588.2.1.1.1.1.7.0"; $result = get_result(); if ($session->error_status() == 0) { $tmp_r_code = $$result{$oid}; chomp $tmp_r_code; if ($tmp_r_code == 1) { $r_message = $r_message . "Operational Status: Online and accessible$multiline"; } if ($tmp_r_code == 2) { $r_code = 2; $r_message = $r_message . "Operational Status: ERROR! Offline not accessible$multiline"; } if ($tmp_r_code == 3) { $r_code = 1; $r_message = $r_message . "Operational Status: Warning! Testing mode not accessible$multiline"; } if ($tmp_r_code == 4) { $r_code = 2; $r_message = $r_message . "Operational Status: ERROR! Faulty not accessible$multiline"; } } else { $r_message = "Operational Status: Not supported$multiline"; } } sub get_sensor_info() { my $key; my $SensorField; my $SensorIndex; my %Sensor2Index; my $SensorType; my %SensorType2Index; my $SensorValue; my $SensorStatus; my $SensorInfo; my $tmp_perf_data; # SENSOR_TYPE = .1.3.6.1.4.1.1588.2.1.1.1.1.22.1.2 # SENSOR_STATUS = .1.3.6.1.4.1.1588.2.1.1.1.1.22.1.3 # SENSOR_VALUE = .1.3.6.1.4.1.1588.2.1.1.1.1.22.1.4 # SENSOR_INFO = .1.3.6.1.4.1.1588.2.1.1.1.1.22.1.5 $oid = ".1.3.6.1.4.1.1588.2.1.1.1.1.22.1"; $result = get_table(); if ($session->error_status() == 0) { # The elements are unsorted. And we do not need the OID as key # We need the index number which is the last digit of the OID # So we build 2 new hashes: # %SensorType2Index contains the mapping for index numbers and sensortypes # %Sensor2Index contains the mapping for status, value and info foreach $key ( keys %$result) { $SensorField = $$result{$key}; $SensorIndex = $key; $SensorIndex =~ s/\.1.3\.6\.1\.4\.1\.1588\.2\.1\.1\.1\.1\.22\.1\.//; if ($SensorIndex !~ m/^1\..*$/ ) { if ($SensorIndex =~ m/^2\..*$/ ) { $SensorIndex =~ s/^2\.//; $SensorType2Index{$SensorIndex} = $SensorField; } else { $Sensor2Index{$SensorIndex} = $SensorField; } } } # Sensor table. Sensor types # 1 - temperature (in degrees celsius) # 2 - fan # 3 - power-supply foreach $key ( sort { $a <=> $b } (keys %SensorType2Index)) { # The current status of the sensor. # Enumerations: # 1 - unknown # 2 - faulty # 3 - below-min # 4 - nominal # 5 - above-max # 6 - absent if ($SensorType2Index{$key} == 1) { $SensorIndex = "3.$key"; $SensorStatus = $Sensor2Index{$SensorIndex}; $SensorIndex = "4.$key"; $SensorValue = $Sensor2Index{$SensorIndex}; $SensorIndex = "5.$key"; $SensorInfo = $Sensor2Index{$SensorIndex}; $SensorInfo =~ s/#//g; $SensorInfo =~ s/ /-/g; $SensorInfo =~ s/:-/\//g; if ($SensorStatus == 1) { $r_message = $r_message . "$SensorInfo: Unknown status$multiline"; if ($r_code < 1) { $r_code = 1; } } if ($SensorStatus == 2) { $r_message = $r_message . "$SensorInfo: Faulty$multiline"; if ($r_code < 2) { $r_code = 2; } } if (($SensorStatus == 3) || ($SensorStatus == 4) || ($SensorStatus == 5)) { if ($SensorStatus == 3) { $r_message = $r_message . "$SensorInfo: $SensorValue Degree Celsius is below-min$multiline"; if ($r_code < 2) { $r_code = 2; } } if ($SensorStatus == 4) { $r_message = $r_message . "$SensorInfo: $SensorValue Degree Celsius$multiline"; } if ($SensorStatus == 5) { $r_message = $r_message . "$SensorInfo: $SensorValue Degree Celsius is above-max$multiline"; if ($r_code < 2) { $r_code = 2; } } # Build the perfdata string if ( $perf_data ) { if ( $perf_data == 1 ) { $perf_data = "$SensorInfo=$SensorValue;;;"; } else { $perf_data = $perf_data . "$SensorInfo=$SensorValue;;;"; } } } if ($SensorStatus == 6) { $r_message = $r_message . "$SensorInfo: Sensor absent$multiline"; if ($r_code < 1) { $r_code = 1; } } } if ($SensorType2Index{$key} == 2) { $SensorIndex = "3.$key"; $SensorStatus = $Sensor2Index{$SensorIndex}; $SensorIndex = "4.$key"; $SensorValue = $Sensor2Index{$SensorIndex}; $SensorIndex = "5.$key"; $SensorInfo = $Sensor2Index{$SensorIndex}; $SensorInfo =~ s/ //g; $SensorInfo =~ s/#/-/g; if ($SensorStatus == 1) { $r_message = $r_message . "$SensorInfo: Unknown status$multiline"; if ($r_code < 1) { $r_code = 1; } } if ($SensorStatus == 2) { $r_message = $r_message . "$SensorInfo: Faulty$multiline"; if ($r_code < 2) { $r_code = 2; } } if (($SensorStatus == 3) || ($SensorStatus == 4) || ($SensorStatus == 5)) { if ($SensorStatus == 3) { $r_message = $r_message . "$SensorInfo: $SensorValue RPM is below-min$multiline"; if ($r_code < 2) { $r_code = 2; } } if ($SensorStatus == 4) { $r_message = $r_message . "$SensorInfo: $SensorValue RPM$multiline"; } if ($SensorStatus == 5) { $r_message = $r_message . "$SensorInfo: $SensorValue RPM is above-max$multiline"; if ($r_code < 2) { $r_code = 2; } } # Build the perfdata string if ( $perf_data ) { if ( $perf_data == 1 ) { $perf_data = "$SensorInfo=$SensorValue;;;"; } else { $perf_data = $perf_data . "$SensorInfo=$SensorValue;;;"; } } } if ($SensorStatus == 6) { $r_message = $r_message . "$SensorInfo: Sensor absent$multiline"; if ($r_code < 1) { $r_code = 1; } } } if ($SensorType2Index{$key} == 3) { $SensorIndex = "3.$key"; $SensorStatus = $Sensor2Index{$SensorIndex}; $SensorIndex = "4.$key"; $SensorValue = $Sensor2Index{$SensorIndex}; $SensorIndex = "5.$key"; $SensorInfo = $Sensor2Index{$SensorIndex}; $SensorInfo =~ s/ //g; $SensorInfo =~ s/#/-/g; if ($SensorStatus == 1) { $r_message = $r_message . "$SensorInfo: Unknown status$multiline"; if ($r_code < 1) { $r_code = 1; } } if ($SensorStatus == 2) { $r_message = $r_message . "$SensorInfo: Faulty$multiline"; if ($r_code < 2) { $r_code = 2; } } if ($SensorStatus == 3) { $r_message = $r_message . "$SensorInfo: below-min$multiline"; if ($r_code < 2) { $r_code = 2; } } if ($SensorStatus == 4) { $r_message = $r_message . "$SensorInfo: OK$multiline"; } if ($SensorStatus == 5) { $r_message = $r_message . "$SensorInfo: above-max$multiline"; if ($r_code < 2) { $r_code = 2; } } if ($SensorStatus == 6) { $r_message = $r_message . "$SensorInfo: Sensor absent$multiline"; if ($r_code < 1) { $r_code = 1; } } } } if ( $perf_data ) { $r_message = $r_message . "|" . $perf_data; } } else { $r_message = $r_message . "Sensor table: Not supported$multiline"; } } sub get_sfp_temp() { my $key; my $TransTemp; my $port; my %port2temp; my $firstrun = 1; my $FailedPort; # Fabric Watch licensed? # 1 - swFwLicensed # 2 - swFwNotLicensed $FabricWatchLicense=FW_Lic(); if ($FabricWatchLicense == 2) { print "No Fabric Watch license enabled. SFP temperature monitoring needs an enabled FW license.\n"; exit 1; } # If it is not handled over via commandline get it from the system if (!$SFP_TempHigh) { $oid = ".1.3.6.1.4.1.1588.2.1.1.1.10.2.1.6.4"; $result = get_request(); $SFP_TempHigh = $$result{$oid}; } # Now we calculate the warning temperature if (!$SFP_TempHighWarn) { $SFP_TempHighWarn = $SFP_TempHigh - $SFP_TempHighWarn_def; } else { $SFP_TempHighWarn = $SFP_TempHigh - $SFP_TempHighWarn; } $oid = ".1.3.6.1.4.1.1588.2.1.1.1.10.3.1.5.4"; $result = get_table(); # The elements are unsorted. And we do not need the OID as key # We need the port number which is the last digit of the OID # So we build a new hash %port2temp foreach $key ( keys %$result) { $TransTemp = $$result{$key}; $port = $key; $port =~ s/\.1.3\.6\.1\.4\.1\.1588\.2\.1\.1\.1\.10\.3\.1\.5\.4\.//; # Here again we have the offset as with port monitoring. The GUI and the # CLI of Brocade starts with port 0. SNMP starts numbering with port 1. # this can be confusing. $port = $port - 1; $port2temp{$port} = $TransTemp; } foreach $key ( sort { $a <=> $b } (keys %port2temp)) { # Show all ports? if ( $allports ) { if ( $firstrun == 1 ) { $firstrun = 0; $r_message = "Port: $key Temp: $port2temp{$key} Celsius$multiline"; } else { $r_message = $r_message . "Port: $key Temp: $port2temp{$key} Celsius$multiline"; } } # Build the perfdata string if ( $perf_data ) { if ( $perf_data == 1 ) { $perf_data = "Port-$key=$port2temp{$key};$SFP_TempHighWarn;$SFP_TempHigh;"; } else { $perf_data = $perf_data . "Port-$key=$port2temp{$key};$SFP_TempHighWarn;$SFP_TempHigh;"; } } if ( $port2temp{$key} >= $SFP_TempHighWarn && $port2temp{$key} <= $SFP_TempHigh) { if ($r_code < 1 ) { $r_code = 1; } $FailedPort = "$FailedPort $port2temp{$key}"; } if ( $port2temp{$key} >= $SFP_TempHigh) { if ($r_code < 2 ) { $r_code = 2; } $FailedPort = "$FailedPort $port2temp{$key}"; } } if ( $perf_data ) { $r_message = $r_message . "|" . $perf_data; } if ( $r_code == 0 ) { $r_message = "Every temperature on every port is ok$multiline" . $r_message; } if ( $r_code == 1 ) { $r_message = "Warning! Temperature on port(s) $FailedPort is too high$multiline" . $r_message; } if ( $r_code == 2 ) { $r_message = "Critical! Temperature on port(s) $FailedPort is too high$multiline" . $r_message; } } sub get_port_data() { # Fabric Watch licensed? # 1 - swFwLicensed # 2 - swFwNotLicensed $FabricWatchLicense=FW_Lic(); # check the operational port status # result values from the switch: # 0: unknown, 1: online, 2: offline # 3: testing, 4: faulty $oid = ".1.3.6.1.4.1.1588.2.1.1.1.6.2.1.4.$fc_port_snmp"; $result = get_request(); $port_opr_state_key = $$result{$oid}; # check the physical port status # result values from the switch: # 1: noCard, 2: noTransceiver, 3: LaserFault # 4: noLight, 5: noSync, 6: inSync, # 7: portFault, 8: diagFault, 9: lockRef $oid = ".1.3.6.1.4.1.1588.2.1.1.1.6.2.1.3.$fc_port_snmp"; $result = get_request(); $port_phy_state_key = $$result{$oid}; # check the link port state # result values from the switch: # 1: enabled - port is allowed to participate in the FC-PH protocol with its # attached port (or ports if it is in a FC-AL loop) # 2: disabled - the port is not allowed to participate in the FC-PH protocol # with its attached port(s) # 3: loopback - the port may transmit frames through an internal path to verify # the health of the transmitter and receiver path $oid = ".1.3.6.1.4.1.1588.2.1.1.1.6.2.1.6.$fc_port_snmp"; $result = get_request(); $port_link_state = $$result{$oid}; # And now we try to get the partner WWN (thats pretty cool I think) $oid = ".1.3.6.1.4.1.1588.2.1.1.1.7.2.1.6.$fc_port_snmp"; $result = get_request(); $partner_wwn = $$result{$oid}; # Now we have the WWN but formatted as (for example) 20000000c9471f3b # but we want 20:00:00:00:c9:47:1f:3b. So the following is a not elegant # but it works. A sophisticated regular exporession would be better $partner_wwn =~ s/^0x//; @partner_wwn = split(//, $partner_wwn ); $partner_wwn = "$partner_wwn[0]$partner_wwn[1]:"; $partner_wwn = "$partner_wwn$partner_wwn[2]$partner_wwn[3]:"; $partner_wwn = "$partner_wwn$partner_wwn[4]$partner_wwn[5]:"; $partner_wwn = "$partner_wwn$partner_wwn[6]$partner_wwn[7]:"; $partner_wwn = "$partner_wwn$partner_wwn[8]$partner_wwn[9]:"; $partner_wwn = "$partner_wwn$partner_wwn[10]$partner_wwn[11]:"; $partner_wwn = "$partner_wwn$partner_wwn[12]$partner_wwn[13]:"; $partner_wwn = "$partner_wwn$partner_wwn[14]$partner_wwn[15]"; if ( $perf_data ) { $oid = ".1.3.6.1.4.1.1588.2.1.1.1.6.2.1.11.$fc_port_snmp"; $result = get_request(); $swFCPortTxWords = $$result{$oid}; $oid = ".1.3.6.1.4.1.1588.2.1.1.1.6.2.1.12.$fc_port_snmp"; $result = get_request(); $swFCPortRxWords = $$result{$oid}; $oid = ".1.3.6.1.4.1.1588.2.1.1.1.6.2.1.13.$fc_port_snmp"; $result = get_request(); $swFCPortTxFrames = $$result{$oid}; $oid = ".1.3.6.1.4.1.1588.2.1.1.1.6.2.1.14.$fc_port_snmp"; $result = get_request(); $swFCPortRxFrames = $$result{$oid}; $oid = ".1.3.6.1.4.1.1588.2.1.1.1.6.2.1.21.$fc_port_snmp"; $result = get_request(); $swFCPortRxEncInFrs = $$result{$oid}; $oid = ".1.3.6.1.4.1.1588.2.1.1.1.6.2.1.22.$fc_port_snmp"; $result = get_request(); $swFCPortRxCrcs = $$result{$oid}; $oid = ".1.3.6.1.4.1.1588.2.1.1.1.6.2.1.23.$fc_port_snmp"; $result = get_request(); $swFCPortRxTruncs = $$result{$oid}; $oid = ".1.3.6.1.4.1.1588.2.1.1.1.6.2.1.24.$fc_port_snmp"; $result = get_request(); $swFCPortRxTooLongs = $$result{$oid}; $oid = ".1.3.6.1.4.1.1588.2.1.1.1.6.2.1.25.$fc_port_snmp"; $result = get_request(); $swFCPortRxBadEofs = $$result{$oid}; $oid = ".1.3.6.1.4.1.1588.2.1.1.1.6.2.1.26.$fc_port_snmp"; $result = get_request(); $swFCPortRxEncOutFrs = $$result{$oid}; $oid = ".1.3.6.1.4.1.1588.2.1.1.1.6.2.1.28.$fc_port_snmp"; $result = get_request(); $swFCPortC3Discards = $$result{$oid}; $perf_data = "stat_wtx=$swFCPortTxWords;0;0;0;0"; $perf_data .= " stat_wrx=$swFCPortRxWords;0;0;0;0"; $perf_data .= " stat_ftx=$swFCPortTxFrames;0;0;0;0"; $perf_data .= " stat_frx=$swFCPortRxFrames;0;0;0;0"; $perf_data .= " er_enc_in=$swFCPortRxEncInFrs;0;0;0;0"; $perf_data .= " er_crc=$swFCPortRxCrcs;0;0;0;0"; $perf_data .= " er_trunc=$swFCPortRxTruncs;0;0;0;0"; $perf_data .= " er_toolong=$swFCPortRxTooLongs;0;0;0;0"; $perf_data .= " er_bad_eof=$swFCPortRxBadEofs;0;0;0;0"; $perf_data .= " er_enc_out=$swFCPortRxEncOutFrs;0;0;0;0"; $perf_data .= " er_c3_timeout=$swFCPortC3Discards;0;0;0;0"; } else { $perf_data = ""; } # Check the port only if it configured 'UP' if ( defined $port_opr_state_key ) { if ( $port_opr_state_key == 0 ) { if ( $port_link_state == 1 ) { $r_code = 2; $r_message = "FC port $fc_port swFCPortPhyState is $port_phy_state{$port_phy_state_key} and NOT disabled. Please disable port."; } if ( $port_link_state == 2 ) { $r_code = 0; $r_message = "FC port $fc_port swFCPortPhyState is $port_phy_state{$port_phy_state_key}"; } } if ( $port_opr_state_key == 1 ) { # If the ports operational status isn't 'UP', check further. if ( $port_opr_state_key != 1 ) { # Check the physical interface status too # makes diagnosing troubles a bit easier. $r_code = 2; $r_message = "Port $fc_port swFCPortPhyState is $port_phy_state{$port_phy_state_key}"; } if ( $port_opr_state_key == 1 && $port_phy_state_key == 6 ) { if ($partner_wwn eq ":::::::" ) { $r_code = 0; $r_message ="FC port $fc_port swFCPortPhyState is $port_phy_state{$port_phy_state_key}. Partner unknown. $tmp_message|$perf_data"; } else { $r_code = 0; $r_message = "FC port $fc_port swFCPortPhyState is $port_phy_state{$port_phy_state_key}. Partner is $partner_wwn. $tmp_message|$perf_data"; } } } if ( $port_opr_state_key == 2 ) { if ( $port_link_state == 1 ) { $r_code =2; $r_message = "FC port $fc_port swFCPortOprStatus is $port_opr_state{$port_opr_state_key} and NOT disabled. Please check cables and partner host"; } if ( $port_link_state == 2 ) { $r_code = 0; $r_message = "FC port $fc_port swFCPortOprStatus is $port_opr_state{$port_opr_state_key} and disabled."; } if ( $port_link_state == 3 ) { $r_code = 0; $r_message = "FC port $fc_port swFCPortOprStatus is $port_opr_state{$port_opr_state_key} and loopback."; } } if ( $port_opr_state_key == 4 ) { $r_code = 2; $r_message = "FC port $fc_port swFCPortOprStatus is $port_opr_state{$port_opr_state_key}"; } } else { $r_code = 2; $r_message = "FC port $fc_port not possible to get operational state of the port."; } } sub FW_Lic() { # Fabric Watch licensed? # 1 - swFwLicensed # 2 - swFwNotLicensed $oid = ".1.3.6.1.4.1.1588.2.1.1.1.10.1.0"; $result = get_request(); return $$result{$oid}; } sub get_out() { my $exitcode; my $msg2nagios; $exitcode = "$_[0]"; $msg2nagios = "$_[1]"; print "$msg2nagios"; # Don't forget to close the session to be clean. $session->close(); exit $exitcode; } sub usage() { print "Usage: "; print "$progname "; print "[ -H <host> ] "; print "[ -C|--community=<community> ] "; print "[ -v|--snmpversion=<1|2c|3> ] "; print "[ -L|--seclevel=<noAuthNoPriv|authNoPriv|authPriv> ] "; print "[ -a|--authproto=<MD5|SHA> ] "; print "[ -x|--privproto=<DES|AES> ] "; print "[ -U|--secname=<username> ] "; print "[ -A|--authpassword=<password> ] "; print "[ -X|--privpasswd=<password> ] "; print "[ -n|--context=<contextname> ] "; print "[--port=<SNMP portnumber>] "; print "[ -P|--fc-port=<fcport-number>] | "; print "[-s|--systeminfo"; print " [ --sensor ]] "; print "| [[ --sfptemp ] "; print "[--sfptemp_warn=<offset>] "; print "[--maxsfptemp=<temperature>] "; print "[--allports]] "; print "[ -p|--performancedata ] "; print "[--multiline]\n\n"; } sub help () { print "This monitoring plugin is free software, and comes with ABSOLUTELY NO WARRANTY.\n"; print "It may be used, redistributed and/or modified under the terms of the GNU\n"; print "General Public Licence (see http://www.fsf.org/licensing/licenses/gpl.txt).\n\n"; usage(); print "This plugin check the selected FC-port of a Brocade (branded or unbranded) fibrechannel switch\n\n"; print "-h, --help Print detailed help screen\n"; print "-V, --version Print version information\n"; print "-H, --hostname=STRING Hostname/IP-Adress to use for the check.\n"; print "-C, --community=STRING SNMP community that should be used to access the switch.\n"; print "-v, --snmpversion=STRING Possible values are 1, 2c or 3.\n"; print "-L, --seclevel=STRING SNMPv3 securityLevel (noAuthNoPriv|authNoPriv|authPriv)\n"; print "-a, --authproto=STRING SNMPv3 auth proto (MD5|SHA)\n"; print "-x, --privproto=STRING SNMPv3 priv proto (DES|AES) (default: DES)\n"; print "-U, --secname=STRING SNMPv3 username\n"; print "-A, --authpassword=STRING SNMPv3 authentication password\n"; print "-X, --privpasswd=STRING SNMPv3 privacy password\n"; print "-n, --context=STRING SNMPv3 context name\n"; print " --port=INTEGER If other than 161 (default) is used)\n"; print "-P, --fc-port=INTEGER Port number as shown in the output of `switchshow`.Can't combine with -s\n\n"; print "-s, --systeminfo Get global data like boot date, overall status, reachability etc.\n"; print " --sensor Additional to -s. Status of powersupply, fans and temp sensors.\n"; print " --global Global data like boot date, overall status etc.\n"; print "\n"; print "-p, --performancedata Print performance data of the selected FC port.\n"; print " --sfptemp Checks the temperature of all SFPs.\n"; print " --sfptemp_warn=INT This is the warning offset the critical temperature as delivered\n"; print " by the system. Default is $SFP_TempHighWarn_def Celsius.\n"; print " MUST be used with --sfptemp.\n"; print " --maxsfttemp Maximum temperature for SFPs. If not set it will be taken from\n"; print " your switch.\n"; print " --allports Default is only to show ports which are too hot. With this flag all ports\n"; print " will be shown. MUST be used with --sfptemp.\n"; print " --multiline Multiline output in overview. This mean technically that a multiline\n"; print " output uses a HTML <br> for the GUI instead of \\n\n"; print " Be aware that your messing connections (email, SMS...) must use\n"; print " a filter to file out the <br>. A sed oneliner will do the job.\n"; }
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor