diff --git a/monitoring/icinga2/conf.d/commands-new.conf b/monitoring/icinga2/conf.d/commands-new.conf index d5c5f23..f838fd0 100644 --- a/monitoring/icinga2/conf.d/commands-new.conf +++ b/monitoring/icinga2/conf.d/commands-new.conf @@ -64,3 +64,9 @@ object CheckCommand "check_operstatus_regex" { vars.value="" timeout = "120" } + +object CheckCommand "cisco-poe-check" { + import "plugin-check-command" + command = SysconfDir + "/icinga2/scripts/check_snmp_cisco_poe.pl -H $host.address$ -C openfest -w $host.vars.poe_watts_warning$ -c $host.vars.poe_watts_critical$" + timeout = "10" +} diff --git a/monitoring/icinga2/conf.d/hosts/switches/coresw.conf b/monitoring/icinga2/conf.d/hosts/switches/coresw.conf index 329a297..c77dfea 100644 --- a/monitoring/icinga2/conf.d/hosts/switches/coresw.conf +++ b/monitoring/icinga2/conf.d/hosts/switches/coresw.conf @@ -249,4 +249,7 @@ object Host "coresw.openfest.org" { OID = "1.3.6.1.2.1.2.2.1.8.14502" value = "2" } + vars.snmp_uptime = "true" + vars.poe_watts_warning = "300" + vars.poe_watts_critical = "100" } diff --git a/monitoring/icinga2/conf.d/hosts/switches/f0sw.conf b/monitoring/icinga2/conf.d/hosts/switches/f0sw.conf index 241a2fd..22f756d 100644 --- a/monitoring/icinga2/conf.d/hosts/switches/f0sw.conf +++ b/monitoring/icinga2/conf.d/hosts/switches/f0sw.conf @@ -216,4 +216,5 @@ vars.snmp_ifaces [ "GigabitEthernet0/48" ] = { value = "2" } + vars.snmp_uptime = "true" } diff --git a/monitoring/icinga2/conf.d/hosts/switches/nocsw.conf b/monitoring/icinga2/conf.d/hosts/switches/nocsw.conf index ed37025..9a6c4cc 100644 --- a/monitoring/icinga2/conf.d/hosts/switches/nocsw.conf +++ b/monitoring/icinga2/conf.d/hosts/switches/nocsw.conf @@ -9,4 +9,5 @@ object Host "nocsw.openfest.org" { # vars.extra_port_check = "" # vars.specification = "vocsw" + vars.snmp_uptime = "true" } diff --git a/monitoring/icinga2/conf.d/hosts/switches/receptionsw.conf b/monitoring/icinga2/conf.d/hosts/switches/receptionsw.conf index abff8f1..6fae843 100644 --- a/monitoring/icinga2/conf.d/hosts/switches/receptionsw.conf +++ b/monitoring/icinga2/conf.d/hosts/switches/receptionsw.conf @@ -61,6 +61,8 @@ object Host "receptionsw.openfest.org" { value = "2" } + vars.snmp_uptime = "true" + vars.notification["slack"] = { groups = [ "icingaadmins" ] } diff --git a/monitoring/icinga2/conf.d/hosts/switches/teamsw.conf b/monitoring/icinga2/conf.d/hosts/switches/teamsw.conf index fd76535..657a974 100644 --- a/monitoring/icinga2/conf.d/hosts/switches/teamsw.conf +++ b/monitoring/icinga2/conf.d/hosts/switches/teamsw.conf @@ -61,6 +61,8 @@ object Host "teamsw.openfest.org" { value = "2" } + vars.snmp_uptime = "true" + vars.notification["slack"] = { groups = [ "icingaadmins" ] } diff --git a/monitoring/icinga2/conf.d/hosts/switches/vocsw-A.conf b/monitoring/icinga2/conf.d/hosts/switches/vocsw-A.conf index c58eaad..ab1f4ba 100644 --- a/monitoring/icinga2/conf.d/hosts/switches/vocsw-A.conf +++ b/monitoring/icinga2/conf.d/hosts/switches/vocsw-A.conf @@ -60,6 +60,8 @@ object Host "vocsw-A.openfest.org" { value = "2" } + vars.snmp_uptime = "true" + vars.notification["slack"] = { groups = [ "icingaadmins" ] } diff --git a/monitoring/icinga2/conf.d/hosts/switches/vocsw-B.conf b/monitoring/icinga2/conf.d/hosts/switches/vocsw-B.conf index 6745064..026f359 100644 --- a/monitoring/icinga2/conf.d/hosts/switches/vocsw-B.conf +++ b/monitoring/icinga2/conf.d/hosts/switches/vocsw-B.conf @@ -60,6 +60,8 @@ object Host "vocsw-B.openfest.org" { value = "2" } + vars.snmp_uptime = "true" + vars.notification["slack"] = { groups = [ "icingaadmins" ] } diff --git a/monitoring/icinga2/conf.d/hosts/switches/vocsw-C.conf b/monitoring/icinga2/conf.d/hosts/switches/vocsw-C.conf index 761b307..83ab4e9 100644 --- a/monitoring/icinga2/conf.d/hosts/switches/vocsw-C.conf +++ b/monitoring/icinga2/conf.d/hosts/switches/vocsw-C.conf @@ -61,6 +61,8 @@ object Host "vocsw-C.openfest.org" { value = "2" } + vars.snmp_uptime = "true" + vars.notification["slack"] = { groups = [ "icingaadmins" ] } diff --git a/monitoring/icinga2/conf.d/hosts/switches/vocsw-D.conf b/monitoring/icinga2/conf.d/hosts/switches/vocsw-D.conf index 59d889c..17f010f 100644 --- a/monitoring/icinga2/conf.d/hosts/switches/vocsw-D.conf +++ b/monitoring/icinga2/conf.d/hosts/switches/vocsw-D.conf @@ -61,6 +61,8 @@ object Host "vocsw-D.openfest.org" { value = "2" } + vars.snmp_uptime = "true" + vars.notification["slack"] = { groups = [ "icingaadmins" ] } diff --git a/monitoring/icinga2/conf.d/services-new.conf b/monitoring/icinga2/conf.d/services-new.conf index 939e858..b7407fe 100644 --- a/monitoring/icinga2/conf.d/services-new.conf +++ b/monitoring/icinga2/conf.d/services-new.conf @@ -49,3 +49,29 @@ apply Service for (iface => config in host.vars.snmp_ifaces) { assign where "vocsw" in host.vars.groups assign where "ciscosw" in host.vars.groups } + +apply Service "uptime-tp" { + display_name = "Uptime" + import "generic-service" + check_command = "snmp" + vars.snmp_oid = "1.3.6.1.2.1.1.3.0" + vars.snmp_community = "openfest" + assign where "vocsw" in host.vars.groups && host.vars.snmp_uptime +} + +apply Service "uptime-cisco" { + display_name = "Uptime" + import "generic-service" + check_command = "snmp" + vars.snmp_oid = "1.3.6.1.6.3.10.2.1.3.0" + vars.snmp_community = "openfest" + vars.snmp_miblist = "SNMP-FRAMEWORK-MIB" + assign where "ciscosw" in host.vars.groups && host.vars.snmp_uptime +} + +apply Service "poe-watts-remaining" { + display_name = "POE - Watts Remaining" + import "generic-service" + check_command = "cisco-poe-check" + assign where host.name == "coresw.openfest.org" +} diff --git a/monitoring/icinga2/conf.d/services.conf b/monitoring/icinga2/conf.d/services.conf index efc987f..665034a 100644 --- a/monitoring/icinga2/conf.d/services.conf +++ b/monitoring/icinga2/conf.d/services.conf @@ -27,7 +27,6 @@ apply Service "ping4" { import "generic-service" check_command = "ping4" - assign where host.address } diff --git a/monitoring/icinga2/scripts/check_snmp_cisco_poe.pl b/monitoring/icinga2/scripts/check_snmp_cisco_poe.pl new file mode 100755 index 0000000..827d540 --- /dev/null +++ b/monitoring/icinga2/scripts/check_snmp_cisco_poe.pl @@ -0,0 +1,477 @@ +#!/usr/bin/perl +# ============================================================================ +# ============================== INFO ======================================== +# ============================================================================ +# Version : 0.3 +# Date : March 6 2019 +# Author : Michiel Timmers ( michiel.timmers AT gmx.net) +Farid Joubbi +# Licence : GPL - summary below +# +# ============================================================================ +# ============================== SUMMARY ===================================== +# ============================================================================ +# +# Check the PoE availability of a Cisco switch +# version 0.3 By farid@joubbi.se: +# - Added performace data +# - Small modifications of output +# +# version 0.2: +# - fix for Cisco bug CSCtl11469. Data is now collected via a snmpwalk +# - added support for stackble switches +# +# Check the http://exchange.nagios.org website for new versions. +# For comments, questions, problems and patches send me an +# e-mail (michiel.timmmers AT gmx.net). +# +# ============================================================================ +# ============================== LICENCE ===================================== +# ============================================================================ +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see +# +# ============================================================================ +# ============================== HELP ======================================== +# ============================================================================ +# Help : ./check_snmp_cisco_poe.pl --help +# +# ============================================================================ + +use warnings; +use strict; +use Net::SNMP; +use Getopt::Long; +use Scalar::Util qw(looks_like_number); +#use lib "/usr/local/nagios/libexec"; +#use utils qw(%ERRORS $TIMEOUT); + + +# ============================================================================ +# ============================== NAGIOS VARIABLES ============================ +# ============================================================================ + +my $TIMEOUT = 15; # This is the global script timeout, not the SNMP timeout +my %ERRORS = ('OK'=>0,'WARNING'=>1,'CRITICAL'=>2,'UNKNOWN'=>3,'DEPENDENT'=>4); +my @Nagios_state = ("UNKNOWN","OK","WARNING","CRITICAL"); # Nagios states coding + + +# ============================================================================ +# ============================== OID VARIABLES =============================== +# ============================================================================ + +# System description +my $cisco_pethMainPseEntry_oid = "1.3.6.1.2.1.105.1.3.1.1"; # pethMainPseEntry +my $cisco_pethMainPsePower_oid = "1.3.6.1.2.1.105.1.3.1.1.2"; # pethMainPsePower +my $cisco_pethMainPseOperStatus_oid = "1.3.6.1.2.1.105.1.3.1.1.3"; # pethMainPseOperStatus +my $cisco_pethMainPseConsumptionPower_oid = "1.3.6.1.2.1.105.1.3.1.1.4"; # pethMainPseConsumptionPower + + +# ============================================================================ +# ============================== GLOBAL VARIABLES ============================ +# ============================================================================ + +my $Version = '0.3'; # Version number of this script +my $o_host = undef; # Hostname +my $o_community = undef; # Community +my $o_port = 161; # Port +my $o_help = undef; # Want some help ? +my $o_verb = undef; # Verbose mode +my $o_version = undef; # Print version +my $o_timeout = undef; # Timeout (Default 5) +my $o_version1 = undef; # Use SNMPv1 +my $o_version2 = undef; # Use SNMPv2c +my $o_domain = undef; # Use IPv6 +my $o_login = undef; # Login for SNMPv3 +my $o_passwd = undef; # Pass for SNMPv3 +my $v3protocols = undef; # V3 protocol list. +my $o_authproto = 'sha'; # Auth protocol +my $o_privproto = 'aes'; # Priv protocol +my $o_privpass = undef; # priv password +my $o_warning = undef; # Warning threshold +my $o_critical = undef; # Critical threshold + + +# ============================================================================ +# ============================== SUBROUTINES (FUNCTIONS) ===================== +# ============================================================================ + +# Subroutine: Print version +sub p_version { + print "check_snmp_cisco_poe version : $Version\n"; +} + +# Subroutine: Print Usage +sub print_usage { + print "Usage: $0 [-v] -H [-6] -C [-2] -w -c | (-l login -x passwd [-X pass -L ,]) [-p ] [-t ] [-V]\n"; +} + +# Subroutine: Check number +sub isnnum { # Return true if arg is not a number + my $num = shift; + if ( $num =~ /^(\d+\.?\d*)|(^\.\d+)$/ ) { return 0 ;} + return 1; +} + +# Subroutine: Set final status +sub set_status { # Return worst status with this order : OK, unknown, warning, critical + my $new_status = shift; + my $cur_status = shift; + if ($new_status == 1 && $cur_status != 2) {$cur_status = $new_status;} + if ($new_status == 2) {$cur_status = $new_status;} + if ($new_status == 3 && $cur_status == 0) {$cur_status = $new_status;} + return $cur_status; +} + +# Subroutine: Check if SNMP table could be retrieved, otherwise give error +sub check_snmp_result { + my $snmp_table = shift; + my $snmp_error_mesg = shift; + + # Check if table is defined and does not contain specified error message. + # Had to do string compare it will not work with a status code + if (!defined($snmp_table) && $snmp_error_mesg !~ /table is empty or does not exist/) { + printf("ERROR: ". $snmp_error_mesg . " : UNKNOWN\n"); + exit $ERRORS{"UNKNOWN"}; + } +} + +# Subroutine: Print complete help +sub help { + print "\nSNMP Cisco SNMP PoE check plugin for Nagios\nVersion: ",$Version,"\n\n"; + print_usage(); + print <, + : Authentication protocol (md5|sha : default sha) + : Priv protocole (des|aes : default aes) +-P, --port=PORT + SNMP port (Default 161) +-t, --timeout=INTEGER + Timeout for SNMP in seconds (Default: 5) +-V, --version + Prints version number + +Notes: +- Check the http://exchange.nagios.org website for new versions. +- For questions, problems and patches send me an e-mail (michiel.timmmers AT gmx.net). + +EOT +} + +# Subroutine: Verbose output +sub verb { + my $t=shift; + print $t,"\n" if defined($o_verb); +} + +# Subroutine: Verbose output +sub check_options { + Getopt::Long::Configure ("bundling"); + GetOptions( + 'v' => \$o_verb, 'verbose' => \$o_verb, + 'h' => \$o_help, 'help' => \$o_help, + 'H:s' => \$o_host, 'hostname:s' => \$o_host, + 'p:i' => \$o_port, 'port:i' => \$o_port, + 'C:s' => \$o_community, 'community:s' => \$o_community, + 'l:s' => \$o_login, 'login:s' => \$o_login, + 'x:s' => \$o_passwd, 'passwd:s' => \$o_passwd, + 'X:s' => \$o_privpass, 'privpass:s' => \$o_privpass, + 'L:s' => \$v3protocols, 'protocols:s' => \$v3protocols, + 't:i' => \$o_timeout, 'timeout:i' => \$o_timeout, + 'V' => \$o_version, 'version' => \$o_version, + '6' => \$o_domain, 'use-ipv6' => \$o_domain, + '1' => \$o_version1, 'v1' => \$o_version1, + '2' => \$o_version2, 'v2c' => \$o_version2, + 'w:i' => \$o_warning, 'warning:i' => \$o_warning, + 'c:i' => \$o_critical, 'critical:i' => \$o_critical + ); + + + # Basic checks + if (defined($o_timeout) && (isnnum($o_timeout) || ($o_timeout < 2) || ($o_timeout > 60))) { + print "Timeout must be >1 and <60 !\n"; + print_usage(); + exit $ERRORS{"UNKNOWN"}; + } + if (!defined($o_timeout)) { + $o_timeout=5; + } + if (defined ($o_help) ) { + help(); + exit $ERRORS{"UNKNOWN"}; + } + + if (defined($o_version)) { + p_version(); + exit $ERRORS{"UNKNOWN"}; + } + + # check host and filter + if ( ! defined($o_host) ) { + print_usage(); + exit $ERRORS{"UNKNOWN"}; + } + + # Check IPv6 + if (defined ($o_domain)) { + $o_domain="udp/ipv6"; + } else { + $o_domain="udp/ipv4"; + } + + # Check SNMP information + if ( !defined($o_community) && (!defined($o_login) || !defined($o_passwd)) ){ + print "Put SNMP login info!\n"; + print_usage(); + exit $ERRORS{"UNKNOWN"}; + } + if ((defined($o_login) || defined($o_passwd)) && (defined($o_community) || defined($o_version2)) ){ + print "Can't mix SNMP v1,v2c,v3 protocols!\n"; + print_usage(); + exit $ERRORS{"UNKNOWN"}; + } + + # Check SNMPv3 information + if (defined ($v3protocols)) { + if (!defined($o_login)) { + print "Put SNMP V3 login info with protocols!\n"; + print_usage(); + exit $ERRORS{"UNKNOWN"}; + } + my @v3proto=split(/,/,$v3protocols); + if ((defined ($v3proto[0])) && ($v3proto[0] ne "")) { + $o_authproto=$v3proto[0]; + } + if (defined ($v3proto[1])) { + $o_privproto=$v3proto[1]; + } + if ((defined ($v3proto[1])) && (!defined($o_privpass))) { + print "Put SNMP v3 priv login info with priv protocols!\n"; + print_usage(); + exit $ERRORS{"UNKNOWN"}; + } + } + + if ( ! defined($o_warning) ) { + print_usage(); + exit $ERRORS{"UNKNOWN"}; + } + + if ( ! defined($o_critical) ) { + print_usage(); + exit $ERRORS{"UNKNOWN"}; + } +} + + +# ============================================================================ +# ============================== MAIN ======================================== +# ============================================================================ + +check_options(); + +# Check gobal timeout if SNMP screws up +if (defined($TIMEOUT)) { + verb("Alarm at ".$TIMEOUT." + ".$o_timeout); + alarm($TIMEOUT+$o_timeout); +} else { + verb("no global timeout defined : ".$o_timeout." + 15"); + alarm ($o_timeout+15); +} + +# Report when the script gets "stuck" in a loop or takes to long +$SIG{'ALRM'} = sub { + print "UNKNOWN: Script timed out\n"; + exit $ERRORS{"UNKNOWN"}; +}; + +# Connect to host +my ($session,$error); +if (defined($o_login) && defined($o_passwd)) { + # SNMPv3 login + verb("SNMPv3 login"); + if (!defined ($o_privpass)) { + # SNMPv3 login (Without encryption) + verb("SNMPv3 AuthNoPriv login : $o_login, $o_authproto"); + ($session, $error) = Net::SNMP->session( + -domain => $o_domain, + -hostname => $o_host, + -version => 3, + -username => $o_login, + -authpassword => $o_passwd, + -authprotocol => $o_authproto, + -timeout => $o_timeout + ); + } else { + # SNMPv3 login (With encryption) + verb("SNMPv3 AuthPriv login : $o_login, $o_authproto, $o_privproto"); + ($session, $error) = Net::SNMP->session( + -domain => $o_domain, + -hostname => $o_host, + -version => 3, + -username => $o_login, + -authpassword => $o_passwd, + -authprotocol => $o_authproto, + -privpassword => $o_privpass, + -privprotocol => $o_privproto, + -timeout => $o_timeout + ); + } +} else { + if ((defined ($o_version2)) || (!defined ($o_version1))) { + # SNMPv2 login + verb("SNMP v2c login"); + ($session, $error) = Net::SNMP->session( + -domain => $o_domain, + -hostname => $o_host, + -version => 2, + -community => $o_community, + -port => $o_port, + -timeout => $o_timeout + ); + } else { + # SNMPv1 login + verb("SNMP v1 login"); + ($session, $error) = Net::SNMP->session( + -domain => $o_domain, + -hostname => $o_host, + -version => 1, + -community => $o_community, + -port => $o_port, + -timeout => $o_timeout + ); + } +} + +# Check if there are any problems with the session +if (!defined($session)) { + printf("ERROR opening session: %s.\n", $error); + exit $ERRORS{"UNKNOWN"}; +} + +my $exit_val=undef; + + +# ============================================================================ +# ============================== Cisco - PoE ================================= +# ============================================================================ + +# Define variables +my $output = ""; +my $output_pd = ""; +my $final_status = 0; +my $result_t; +my $index; +my @temp_oid; +my ($pethMainPsePower,$pethMainPseOperStatus,$pethMainPseConsumptionPower,$module)=(undef,undef,undef,undef); + +# Get SNMP table(s) and check the result +my $cisco_pethMainPseEntry = $session->get_table(Baseoid => $cisco_pethMainPseEntry_oid); +&check_snmp_result($cisco_pethMainPseEntry,$session->error); + +if (defined($cisco_pethMainPseEntry)) { + foreach my $key ( keys %$cisco_pethMainPseEntry) { + if ($key =~ /$cisco_pethMainPseOperStatus_oid/) { + $key =~ s/$cisco_pethMainPseOperStatus_oid//; + + $module = substr $key, 1; + + # Set the Pse variables + $pethMainPsePower = $$cisco_pethMainPseEntry{$cisco_pethMainPsePower_oid.$key}; + $pethMainPseOperStatus = $$cisco_pethMainPseEntry{$cisco_pethMainPseOperStatus_oid.$key}; + $pethMainPseConsumptionPower = $$cisco_pethMainPseEntry{$cisco_pethMainPseConsumptionPower_oid.$key}; + + if (defined($pethMainPsePower) && defined($pethMainPseOperStatus) && defined($pethMainPseConsumptionPower)){ + + if (!looks_like_number($pethMainPsePower) && !looks_like_number($pethMainPseOperStatus) && !looks_like_number($pethMainPseConsumptionPower)) { + $output = "Module:".$module." Device does not have PoE"; + }else{ + if ($pethMainPseOperStatus != 1){ + $final_status = 2; + $output = "Module:".$module." Power Sourcing Equipment (PSE) is not on"; + }else{ + if($pethMainPsePower - $pethMainPseConsumptionPower < $o_warning){ + $final_status = &set_status(1,$final_status); + } + + if($pethMainPsePower - $pethMainPseConsumptionPower < $o_critical){ + $final_status = &set_status(2,$final_status); + } + + if ($output eq ""){ + $output = "Module:".$module." Available:".$pethMainPsePower." W, Used:".$pethMainPseConsumptionPower." W, Remaining:".($pethMainPsePower - $pethMainPseConsumptionPower)." W"; + $output_pd = " | M".$module."_Used=".$pethMainPseConsumptionPower.";".($pethMainPsePower - $o_warning).";".($pethMainPsePower - $o_critical).";0;".$pethMainPsePower; + }else{ + $output.= " - Module:".$module." Available:".$pethMainPsePower." W, Used:".$pethMainPseConsumptionPower." W, Remaining:".($pethMainPsePower - $pethMainPseConsumptionPower)." W"; + $output_pd.= " M".$module."_Used=".$pethMainPseConsumptionPower.";".($pethMainPsePower - $o_warning).";".($pethMainPsePower - $o_critical).";0;".$pethMainPsePower; + } + } + } + } + } + } + +}else{ + $output = "Device does not have PoE"; +} + +if ($final_status == 3) { + print $output," : UNKNOWN\n"; + exit $ERRORS{"UNKNOWN"}; +} + +if ($final_status == 2) { + print $output," : CRITICAL",$output_pd,"\n"; + exit $ERRORS{"CRITICAL"}; +} + +if ($final_status == 1) { + print $output," : WARNING",$output_pd,"\n"; + exit $ERRORS{"WARNING"}; +} + +print $output," : OK",$output_pd,"\n"; +exit $ERRORS{"OK"}; + + +# ============================================================================ +# ============================== NO CHECK DEFINED ============================ +# ============================================================================ + +print "Unknown check type : UNKNOWN\n"; +exit $ERRORS{"UNKNOWN"}; +