From 470a953fed57145ebb330a868354754054e9a16d Mon Sep 17 00:00:00 2001 From: Ricardo Date: Thu, 10 Aug 2017 11:22:38 +0200 Subject: [PATCH 01/38] Create icinga2_command.conf Added Icinga2 command definition --- examples/icinga2_command.conf | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 examples/icinga2_command.conf diff --git a/examples/icinga2_command.conf b/examples/icinga2_command.conf new file mode 100644 index 0000000..3494fce --- /dev/null +++ b/examples/icinga2_command.conf @@ -0,0 +1,23 @@ +object CheckCommand "netscaler" { + import "plugin-check-command" + + command = [ PluginDir + "/check_netscaler.pl" ] + + arguments = { + "-H" = "$address$" + "-u" = "$netscaler_user$" + "-p" = "$netscaler_password$" + "--ssl" = { + set_if = "$netscaler_ssl$" + } + "-P" = "$netscaler_port$" + "-C" = "$netscaler_command$" + "-o" = "$netscaler_objecttype$" + "-n" = "$netscaler_objectname$" + "-e" = "$netscaler_endpoint$" + "-w" = "$warning$" + "-c" = "$critical$" + "-t" = "$netscaler_timeout$" + } + +} From ae234f8e24191d84d0a4f9dcee0a941cdabf79df Mon Sep 17 00:00:00 2001 From: Ricardo Date: Thu, 10 Aug 2017 11:29:56 +0200 Subject: [PATCH 02/38] added icinga2 service templates --- examples/icinga2_service_emplates.conf | 139 +++++++++++++++++++++++++ 1 file changed, 139 insertions(+) create mode 100644 examples/icinga2_service_emplates.conf diff --git a/examples/icinga2_service_emplates.conf b/examples/icinga2_service_emplates.conf new file mode 100644 index 0000000..27af22f --- /dev/null +++ b/examples/icinga2_service_emplates.conf @@ -0,0 +1,139 @@ +/* + * Service Templates fuer die Ueberwachung einer Citrix Farm + */ + +// Health Checks +template Service "netscaler_cpu_template" { + import "generic-service" + import "perf_enabled" + + check_command = "netscaler" + + vars.netscaler_command = "above" + vars.netscaler_objecttype = "system" + vars.netscaler_objectname = "cpuusagepcnt" + + vars.warning = 75 + vars.critical = 80 +} + +template Service "netscaler_mem_template" { + import "generic-service" + import "perf_enabled" + + check_command = "netscaler" + + vars.netscaler_command = "above" + vars.netscaler_objecttype = "system" + vars.netscaler_objectname = "memusagepcnt" + + vars.warning = 75 + vars.critical = 80 +} + +template Service "netscaler_mgmtcpu_template" { + import "generic-service" + import "perf_enabled" + + check_command = "netscaler" + + vars.netscaler_command = "above" + vars.netscaler_objecttype = "system" + vars.netscaler_objectname = "mgmtcpuusagepcnt" + + vars.warning = 75 + vars.critical = 80 +} + +template Service "netscaler_disk0_template" { + import "generic-service" + import "perf_enabled" + + check_command = "netscaler" + + vars.netscaler_command = "above" + vars.netscaler_objecttype = "system" + vars.netscaler_objectname = "disk0perusage" + + vars.warning = 75 + vars.critical = 80 +} + +template Service "netscaler_disk1_template" { + import "generic-service" + import "perf_enabled" + + check_command = "netscaler" + + vars.netscaler_command = "above" + vars.netscaler_objecttype = "system" + vars.netscaler_objectname = "disk0perusage" + + vars.warning = 75 + vars.critical = 80 +} + +// HA Status +template Service "netscaler_ha_status_template" { + import "generic-service" + + check_command = "netscaler" + + vars.netscaler_command = "string_not" + vars.netscaler_objecttype = "hanode" + vars.netscaler_objectname = "hacurstatus" + + vars.warning = "YES" + vars.critical = "YES" +} + +template Service "netscaler_ha_state_template" { + import "generic-service" + + check_command = "netscaler" + + vars.netscaler_command = "string_not" + vars.netscaler_objecttype = "hanode" + vars.netscaler_objectname = "hacurstate" + + vars.warning = "UP" + vars.critical = "UP" +} + +// Config Changes +template Service "netscaler_config_status_template" { + import "generic-service" + + check_command = "netscaler" + + vars.netscaler_command = "nsconfig" +} + +// Server Status +template Service "netscaler_staserver_template" { + import "generic-service" + + check_command = "netscaler" + + vars.netscaler_command = "staserver" +} + +template Service "netscaler_lbvserver_template" { + import "generic-service" + import "perf_enabled" + + check_command = "netscaler" + + vars.netscaler_command = "state" + vars.netscaler_objecttype = "lbvserver" +} + +template Service "netscaler_vpnvserver_template" { + import "generic-service" + import "perf_enabled" + + check_command = "netscaler" + + vars.netscaler_command = "state" + vars.netscaler_objecttype = "vpnvserver" +} From a1eddd7dfa1bde2ff114c07df56683722878c983 Mon Sep 17 00:00:00 2001 From: Ricardo Date: Thu, 10 Aug 2017 11:30:52 +0200 Subject: [PATCH 03/38] fixed templates description --- examples/icinga2_service_emplates.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/icinga2_service_emplates.conf b/examples/icinga2_service_emplates.conf index 27af22f..9802ce8 100644 --- a/examples/icinga2_service_emplates.conf +++ b/examples/icinga2_service_emplates.conf @@ -1,5 +1,5 @@ /* - * Service Templates fuer die Ueberwachung einer Citrix Farm + * service templates for check_netscaler.pl */ // Health Checks From f4c3bf31aafdc9793689bc311d548c67a40bea21 Mon Sep 17 00:00:00 2001 From: Ricardo Date: Thu, 10 Aug 2017 12:25:15 +0200 Subject: [PATCH 04/38] removing trailing white spaces --- check_netscaler.pl | 114 ++++++++++++++++++++++----------------------- 1 file changed, 57 insertions(+), 57 deletions(-) diff --git a/check_netscaler.pl b/check_netscaler.pl index 3a31e7b..e801ee2 100755 --- a/check_netscaler.pl +++ b/check_netscaler.pl @@ -1,7 +1,7 @@ #!/usr/bin/perl ############################################################################## # check_netscaler.pl -# Nagios Plugin for Citrix NetScaler +# Nagios Plugin for Citrix NetScaler # Simon Lauger # # https://github.com/slauger/check_netscaler @@ -153,7 +153,7 @@ # check the state of the staservers check_staserver($plugin); } elsif ($plugin->opts->command eq 'debug') { - # dump the full response of the nitro api + # dump the full response of the nitro api check_debug($plugin); } else { # error, unkown command given @@ -197,19 +197,19 @@ sub nitro_client { my $plugin = shift; my $params = shift; - + my $lwp = LWP::UserAgent->new( - env_proxy => 1, - keep_alive => 1, - timeout => $plugin->opts->timeout, - ssl_opts => { - verify_hostname => 0, + env_proxy => 1, + keep_alive => 1, + timeout => $plugin->opts->timeout, + ssl_opts => { + verify_hostname => 0, SSL_verify_mode => 0 }, ); - + my $protocol = undef; - + if ($plugin->opts->ssl) { $protocol = 'https://'; } else { @@ -229,58 +229,58 @@ sub nitro_client { if ($params->{'objectname'} && $params->{'objectname'} ne '') { $url = $url . '/' . uri_escape(uri_escape($params->{'objectname'})); } - + if ($params->{'options'} && $params->{'options'} ne '') { $url = $url . '?' . $params->{'options'}; } - + if ($plugin->opts->verbose) { print "debug: target url is " . $url . "\n"; } - + my $request = HTTP::Request->new(GET => $url); - + $request->header('X-NITRO-USER', $plugin->opts->username); $request->header('X-NITRO-PASS', $plugin->opts->password); $request->header('Content-Type', 'application/vnd.com.citrix.netscaler.' . $params->{'objecttype'} . '+json'); - + my $response = $lwp->request($request); - + if ($plugin->opts->verbose) { print "debug: response of request is:\n"; print Dumper($response->content); } - + if (HTTP::Status::is_error($response->code)) { $plugin->nagios_die($response->content); } else { $response = JSON->new->allow_blessed->convert_blessed->decode($response->content); } - + return $response; } sub check_state { my $plugin = shift; - + if (!defined $plugin->opts->objecttype) { $plugin->nagios_die('command requires objecttype parameter'); } - + my %counter; - + $counter{'up'} = 0; $counter{'down'} = 0; $counter{'oos'} = 0; $counter{'unkown'} = 0; my %params; - + my $field_name; my $field_state; - - # well, i guess the citrix api developers were drunk + + # well, i guess the citrix api developers were drunk if ($plugin->opts->objecttype eq 'service') { $params{'endpoint'} = $plugin->opts->endpoint || 'config'; $field_name = 'name'; @@ -294,14 +294,14 @@ sub check_state $field_name = 'name'; $field_state = 'state'; } - + $params{'objecttype'} = $plugin->opts->objecttype; $params{'objectname'} = $plugin->opts->objectname; $params{'options'} = undef; my $response = nitro_client($plugin, \%params); $response = $response->{$plugin->opts->objecttype}; - + foreach my $response (@{$response}) { if ($response->{$field_state} eq 'UP') { $counter{'up'}++; @@ -321,11 +321,11 @@ sub check_state $counter{'unkown'}++; $plugin->add_message(CRITICAL, $response->{$field_name} . ' unknown;'); } - } + } my ($code, $message) = $plugin->check_messages; - + my $stats = ' (' . $counter{'up'} . ' up, ' . $counter{'down'} . ' down, ' . $counter{'oos'} . ' oos, ' . $counter{'unkown'} . ' unkown)'; - + $plugin->add_perfdata( label => 'up', value => $counter{'up'}, @@ -364,11 +364,11 @@ sub check_state sub check_string { my $plugin = shift; - + if (!defined $plugin->opts->objecttype) { $plugin->nagios_die('command requires parameter for objecttype'); } - + if (!defined $plugin->opts->objectname) { $plugin->nagios_die('command requires parameter for objectname'); } @@ -382,7 +382,7 @@ sub check_string $params{'objecttype'} = $plugin->opts->objecttype; $params{'objectname'} = undef; $params{'options'} = undef; - + my $response = nitro_client($plugin, \%params); $response = $response->{$plugin->opts->objecttype}; @@ -398,11 +398,11 @@ sub check_string sub check_string_not { my $plugin = shift; - + if (!defined $plugin->opts->objecttype) { $plugin->nagios_die('command requires parameter for objecttype'); } - + if (!defined $plugin->opts->objectname) { $plugin->nagios_die('command requires parameter for objectname'); } @@ -416,13 +416,13 @@ sub check_string_not $params{'objecttype'} = $plugin->opts->objecttype; $params{'objectname'} = undef; $params{'options'} = undef; - + my $response = nitro_client($plugin, \%params); $response = $response->{$plugin->opts->objecttype}; - + if ($response->{$plugin->opts->objectname} ne $plugin->opts->critical) { $plugin->nagios_exit(CRITICAL, $plugin->opts->objecttype . '::' . $plugin->opts->objectname . ' not matches keyword (current: ' . $response->{$plugin->opts->objectname} . ', critical: ' . $plugin->opts->critical . ')'); - } elsif ($response->{$plugin->opts->objectname} ne $plugin->opts->warning) { + } elsif ($response->{$plugin->opts->objectname} ne $plugin->opts->warning) { $plugin->nagios_exit(WARNING, $plugin->opts->objecttype . '::' . $plugin->opts->objectname . ' not matches keyword (current: ' . $response->{$plugin->opts->objectname} . ', warning: ' . $plugin->opts->warning . ')'); } else { $plugin->nagios_exit(OK, $plugin->opts->objecttype . '::' . $plugin->opts->objectname . ' OK ('.$response->{$plugin->opts->objectname}.')'); @@ -436,7 +436,7 @@ sub check_threshold_above if (!defined $plugin->opts->objecttype) { $plugin->nagios_die('command requires parameter for objecttype'); } - + if (!defined $plugin->opts->objectname) { $plugin->nagios_die('command requires parameter for objectname'); } @@ -450,7 +450,7 @@ sub check_threshold_above $params{'objecttype'} = $plugin->opts->objecttype; $params{'objectname'} = undef; $params{'options'} = undef; - + my $response = nitro_client($plugin, \%params); $response = $response->{$plugin->opts->objecttype}; @@ -476,11 +476,11 @@ sub check_threshold_above sub check_threshold_below { my $plugin = shift; - + if (!defined $plugin->opts->objecttype) { $plugin->nagios_die('command requires parameter for objecttype'); } - + if (!defined $plugin->opts->objectname) { $plugin->nagios_die('command requires parameter for objectname'); } @@ -494,7 +494,7 @@ sub check_threshold_below $params{'objecttype'} = $plugin->opts->objecttype; $params{'objectname'} = undef; $params{'options'} = undef; - + my $response = nitro_client($plugin, \%params); $response = $response->{$plugin->opts->objecttype}; @@ -519,11 +519,11 @@ sub check_threshold_below sub check_sslcert { my $plugin = shift; - + if (!defined $plugin->opts->warning || !defined $plugin->opts->critical) { $plugin->nagios_die('command requires parameter for warning and critical'); } - + my %params; $params{'endpoint'} = $plugin->opts->endpoint || 'config'; $params{'objecttype'} = $plugin->opts->objecttype || 'sslcertkey'; @@ -540,9 +540,9 @@ sub check_sslcert $plugin->add_message(WARNING, $response->{certkey} . ' expires in ' . $response->{daystoexpiration} . ' days;'); } } - + my ($code, $message) = $plugin->check_messages; - + if ($code == OK) { $plugin->nagios_exit($code, 'sslcertkey OK'); } else { @@ -553,7 +553,7 @@ sub check_sslcert sub check_staserver { my $plugin = shift; - + my %params; $params{'endpoint'} = $plugin->opts->endpoint || 'config'; $params{'objectname'} = $plugin->opts->objectname || ''; @@ -564,13 +564,13 @@ sub check_staserver } else { $params{'objecttype'} = $plugin->opts->objecttype || 'vpnvserver_staserver_binding'; } - + my $response = nitro_client($plugin, \%params); $response = $response->{$params{'objecttype'}}; - + # return critical if all staservers are down at once my $critical = 1; - + # check if any stas are in down state foreach $response (@{$response}) { if ($response->{'staauthid'} eq '') { @@ -580,9 +580,9 @@ sub check_staserver $critical = 0; } } - + my ($code, $message) = $plugin->check_messages; - + if ($critical) { $plugin->nagios_exit(CRITICAL, 'staservice ' . $message); } else { @@ -593,7 +593,7 @@ sub check_staserver sub check_nsconfig { my $plugin = shift; - + my %params; $params{'endpoint'} = $plugin->opts->endpoint || 'config'; $params{'objecttype'} = $plugin->opts->objecttype || 'nsconfig'; @@ -602,7 +602,7 @@ sub check_nsconfig my $response = nitro_client($plugin, \%params); $response = $response->{$params{'objecttype'}}; - + if (!defined $response->{'configchanged'} || $response->{'configchanged'}) { $plugin->nagios_exit(WARNING, 'nsconfig::configchanged unsaved configuration changes'); } else { @@ -613,14 +613,14 @@ sub check_nsconfig sub check_debug { my $plugin = shift; - + my %params; $params{'endpoint'} = $plugin->opts->endpoint || 'stat'; $params{'objecttype'} = $plugin->opts->objecttype; $params{'objectname'} = $plugin->opts->objectname; $params{'options'} = undef; - + my $response = nitro_client($plugin, \%params); - + print Dumper($response); } From c6c85a4bdb4ae20c8a5e3145b6bdf6cf510b543f Mon Sep 17 00:00:00 2001 From: Ricardo Date: Thu, 10 Aug 2017 12:32:07 +0200 Subject: [PATCH 05/38] added three new commands to check_netscaler.pl Added following commands: * server -> check status of Load Balancing Servers * hwinfo -> just print information about the Netscaler itself * interfaces -> check state of all interfaces and add performance data for each interface --- check_netscaler.pl | 137 +++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 133 insertions(+), 4 deletions(-) diff --git a/check_netscaler.pl b/check_netscaler.pl index e801ee2..3ee4eb7 100755 --- a/check_netscaler.pl +++ b/check_netscaler.pl @@ -152,6 +152,15 @@ } elsif ($plugin->opts->command eq 'staserver') { # check the state of the staservers check_staserver($plugin); +} elsif ($plugin->opts->command eq 'server') { + # check the state of the servers + check_server($plugin); +} elsif ($plugin->opts->command eq 'hwinfo') { + # print infos about hardware and build version + get_hardware_info($plugin); +} elsif ($plugin->opts->command eq 'interfaces') { + # check the state of all interfaces + check_interfaces($plugin); } elsif ($plugin->opts->command eq 'debug') { # dump the full response of the nitro api check_debug($plugin); @@ -583,11 +592,42 @@ sub check_staserver my ($code, $message) = $plugin->check_messages; - if ($critical) { - $plugin->nagios_exit(CRITICAL, 'staservice ' . $message); - } else { - $plugin->nagios_exit($code, 'staservice ' . $message); + if ( $critical == 1) { $code = CRITICAL ; } + + $plugin->nagios_exit($code, 'server ' . $message); +} + +sub check_server +{ + my $plugin = shift; + + my %params; + $params{'endpoint'} = $plugin->opts->endpoint || 'config'; + $params{'objectname'} = $plugin->opts->objectname || ''; + $params{'options'} = undef; + $params{'objecttype'} = "server"; + + my $response = nitro_client($plugin, \%params); + $response = $response->{$params{'objecttype'}}; + + # return critical if all staservers are down at once + my $critical = 1; + + # check if any stas are in down state + foreach $response (@{$response}) { + if ($response->{'state'} ne 'ENABLED') { + $plugin->add_message(WARNING, $response->{'name'} . ' ' . $response->{'state'} . ' ;'); + } else { + $plugin->add_message(OK, $response->{'name'} . ' ' . $response->{'state'} . ' ;'); + $critical = 0; + } } + + my ($code, $message) = $plugin->check_messages; + + if ( $critical == 1) { $code = CRITICAL ; } + + $plugin->nagios_exit($code, 'server ' . $message); } sub check_nsconfig @@ -610,6 +650,95 @@ sub check_nsconfig } } +sub get_hardware_info +{ + my $plugin = shift; + + my %params; + $params{'endpoint'} = 'config'; + $params{'objecttype'} = 'nshardware'; + $params{'objectname'} = undef; + $params{'options'} = undef; + + my $response = nitro_client($plugin, \%params); + $response = $response->{$params{'objecttype'}}; + + $plugin->add_message(OK, "Platform: " . $response->{'hwdescription'} . ' ' . $response->{'sysid'} . ';'); + $plugin->add_message(OK, "Manufactured on: " . $response->{'manufactureyear'} . '/' . $response->{'manufacturemonth'} . '/' . $response->{'manufactureday'} . ';'); + $plugin->add_message(OK, "CPU: " . $response->{'cpufrequncy'} . 'MHz;'); + $plugin->add_message(OK, "Serial no: " . $response->{'serialno'} . ';'); + + $params{'objecttype'} = 'nsversion'; + + $response = nitro_client($plugin, \%params); + $response = $response->{$params{'objecttype'}}; + + $plugin->add_message(OK, "Build Version: " . $response->{'version'} . ';'); + + my ($code, $message) = $plugin->check_messages; + $plugin->nagios_exit($code, 'INFO: ' . $message); +} + +sub check_interfaces +{ + my $plugin = shift; + my @interface_errors; + + my %params; + $params{'endpoint'} = 'config'; + $params{'objecttype'} = 'interface'; + $params{'objectname'} = undef; + $params{'options'} = undef; + + my $response = nitro_client($plugin, \%params); + + foreach my $interface (@{$response->{'Interface'}}) { + + my $interface_state = OK; + + my $interface_speed = "N/A"; + if ($interface->{'actspeed'}) { $interface_speed = $interface->{'actspeed'}; } + + if ($interface->{'linkstate'} != 1 ) { + push(@interface_errors, "interface " . $interface->{'devicename'} . " has linkstate \"DOWN\""); + $interface_state = CRITICAL; + } + if ($interface->{'intfstate'} != 1 ) { + push(@interface_errors, "interface " . $interface->{'devicename'} . " has intstate \"DOWN\""); + $interface_state = CRITICAL; + } + if ($interface->{'state'} ne "ENABLED" ) { + push(@interface_errors, "interface " . $interface->{'devicename'} . " has state \"".$interface->{'state'}."\""); + $interface_state = CRITICAL; + } + + $plugin->add_message($interface_state, "device: " . $interface->{'devicename'} . ' (speed: ' . $interface_speed . ', MTU: ' . $interface->{'actualmtu'} . ', VLAN: ' . $interface->{'vlan'} . ', type: ' . $interface->{'intftype'} . ') ' . $interface->{'state'} . ';'); + + $plugin->add_perfdata( + label => "\'".$interface->{'devicename'} . "_rxbytes'", + value => $interface->{'rxbytes'}."B" + ); + $plugin->add_perfdata( + label => "\'".$interface->{'devicename'} . "_txbytes'", + value => $interface->{'txbytes'}."B" + ); + $plugin->add_perfdata( + label => "\'".$interface->{'devicename'} . "rxerrors'", + value => $interface->{'rxerrors'}."c" + ); + $plugin->add_perfdata( + label => "\'".$interface->{'devicename'} . "txerrors'", + value => $interface->{'txerrors'}."c" + ); + } + + my ($code, $message) = $plugin->check_messages; + if (scalar @interface_errors != 0 ) { + $message = join(", ",@interface_errors). " - ". $message + } + $plugin->nagios_exit($code, 'Interfaces: ' . $message); +} + sub check_debug { my $plugin = shift; From 33a4c1d9a084444a01034e445ba662ddf6e98e6e Mon Sep 17 00:00:00 2001 From: Ricardo Date: Thu, 10 Aug 2017 12:33:56 +0200 Subject: [PATCH 06/38] Add version information to main script --- check_netscaler.pl | 2 ++ 1 file changed, 2 insertions(+) diff --git a/check_netscaler.pl b/check_netscaler.pl index 3ee4eb7..3f971b4 100755 --- a/check_netscaler.pl +++ b/check_netscaler.pl @@ -6,6 +6,8 @@ # # https://github.com/slauger/check_netscaler # +# Version: 1.2 (2017-XX-XX) +# # Copyright 2015-2017 Simon Lauger # # Licensed under the Apache License, Version 2.0 (the "License"); From 45f36c2387946663afb24ffcc8167b8f22f7935e Mon Sep 17 00:00:00 2001 From: Ricardo Date: Thu, 10 Aug 2017 12:37:16 +0200 Subject: [PATCH 07/38] Changelog Update --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9ad453e..d5a7c0c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +## 1.2.0 (2017-XX-XX) +- added command server to check status of Load Balancing Servers +- added command hwinfo to just print information about the Netscaler itself +- added command interfaces to check state of all interfaces and add performance data for each interface +- added Icinga2 config templates + ## 1.1.1 (2017-06-10) - bugfix for servicegroups in 12.0 (#12) - new option to connect to an alternate port (for CPX instances) From 0fc60939d7943df22019bd5c768aa70726a90780 Mon Sep 17 00:00:00 2001 From: Ricardo Date: Thu, 10 Aug 2017 12:53:11 +0200 Subject: [PATCH 08/38] Added new commands to README --- README.md | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/README.md b/README.md index 27e2e5b..b2d344c 100644 --- a/README.md +++ b/README.md @@ -10,6 +10,9 @@ Currently the plugin has the following subcommands: - **sslcert:** check the lifetime for installed ssl certificates - **nsconfig:** check for configuration changes which are not saved to disk - **staserver:** check if configured STA servers are available +- **server:** check status of Load Balancing Servers +- **hwinfo:** just print information about the Netscaler itself +- **interfaces:** check state of all interfaces and add performance data for each interface - **debug:** debug command, print all data for a endpoint This plugin works with VPX, MPX, SDX and CPX NetScaler Appliances. The api responses may differ by build, appliance type and your installed license. @@ -108,6 +111,21 @@ If you want to connect to your NetScaler with SSL/HTTPS you should also install # NetScaler::STA::vs_vpn_gateway ./check_netscaler.pl -H ${IPADDR} -s -C staserver -n vs_vpn_gateway +## Check if Load Balancer server are working + + # NetScaler::Server + ./check_netscaler.pl -H ${IPADDR} -s -C server + +## Get information about the netscaler + + # NetScaler::Server + ./check_netscaler.pl -H ${IPADDR} -s -C hwinfo + +## Check status of all network interfaces + + # NetScaler::Interfaces + ./check_netscaler.pl -H ${IPADDR} -s -C interfaces + ## Debug command # Print all LB vServers (stat endpoint) ./check_netscaler.pl -H ${IPADDR} -s -C debug -o lbvserver From f56b807f2abbb31e9b88d2fbc915044f487e323f Mon Sep 17 00:00:00 2001 From: Ricardo Date: Thu, 10 Aug 2017 12:54:22 +0200 Subject: [PATCH 09/38] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index b2d344c..6a91317 100644 --- a/README.md +++ b/README.md @@ -118,7 +118,7 @@ If you want to connect to your NetScaler with SSL/HTTPS you should also install ## Get information about the netscaler - # NetScaler::Server + # NetScaler::HWInfo ./check_netscaler.pl -H ${IPADDR} -s -C hwinfo ## Check status of all network interfaces From ec365b097db29cc8cc9b331de9d3baa340b7f56a Mon Sep 17 00:00:00 2001 From: Ricardo Date: Thu, 10 Aug 2017 13:14:00 +0200 Subject: [PATCH 10/38] add IP adresses to server out in check_netscaler --- check_netscaler.pl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/check_netscaler.pl b/check_netscaler.pl index 3f971b4..6a22c11 100755 --- a/check_netscaler.pl +++ b/check_netscaler.pl @@ -6,7 +6,7 @@ # # https://github.com/slauger/check_netscaler # -# Version: 1.2 (2017-XX-XX) +# Version: 1.2.0 (2017-XX-XX) # # Copyright 2015-2017 Simon Lauger # @@ -618,9 +618,9 @@ sub check_server # check if any stas are in down state foreach $response (@{$response}) { if ($response->{'state'} ne 'ENABLED') { - $plugin->add_message(WARNING, $response->{'name'} . ' ' . $response->{'state'} . ' ;'); + $plugin->add_message(WARNING, $response->{'name'} . '('. $response->{'ipaddress'} .') ' . $response->{'state'} . ' ;'); } else { - $plugin->add_message(OK, $response->{'name'} . ' ' . $response->{'state'} . ' ;'); + $plugin->add_message(OK, $response->{'name'} . '('. $response->{'ipaddress'} .') ' . $response->{'state'} . ' ;'); $critical = 0; } } From 2d71db13a55529a12fc91cc433d56b666dea6756 Mon Sep 17 00:00:00 2001 From: Ricardo Date: Thu, 10 Aug 2017 14:13:57 +0200 Subject: [PATCH 11/38] added new option to gather performancedata added option "performancedata" to query stats and counters to forward them to a performance tool of your choice * examples: * cache -C performancedata -o ns -n cachetothits,cachetotmisses * tcp connections -C performancedata -o ns -n tcpcurclientconn,tcpcurclientconnestablished,tcpcurserverconn,tcpcurserverconnestablished * http requests -C performancedata -o ns -n httprxrequestbytesrate,httprxresponsebytesrate,httptotrequests,httptotresponses,httptotrxrequestbytes,httptotrxresponsebytes --- check_netscaler.pl | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/check_netscaler.pl b/check_netscaler.pl index 6a22c11..64583bf 100755 --- a/check_netscaler.pl +++ b/check_netscaler.pl @@ -160,6 +160,9 @@ } elsif ($plugin->opts->command eq 'hwinfo') { # print infos about hardware and build version get_hardware_info($plugin); +} elsif ($plugin->opts->command eq 'performancedata') { + # print performance data of protocol stats + get_performancedata($plugin); } elsif ($plugin->opts->command eq 'interfaces') { # check the state of all interfaces check_interfaces($plugin); @@ -681,6 +684,39 @@ sub get_hardware_info $plugin->nagios_exit($code, 'INFO: ' . $message); } +sub get_performancedata +{ + my $plugin = shift; + + my %params; + $params{'endpoint'} = 'stat'; + $params{'objecttype'} = $plugin->opts->objecttype; + $params{'objectname'} = undef; + $params{'options'} = undef; + + my $response = nitro_client($plugin, \%params); + $response = $response->{$params{'objecttype'}}; + + foreach my $objectname (split(",",$plugin->opts->objectname)) { + if (not defined($response->{$objectname})) { + $plugin->nagios_exit(UNKNOWN, 'performancedata: object name "' . $objectname . '" not found in output.'); + } + $plugin->add_message(OK, $objectname .":", $response->{$objectname}. ","); + + $plugin->add_perfdata( + label => "'".$objectname."'", + value => $response->{$objectname}, + min => undef, + max => undef, + warning => $plugin->opts->warning, + critical => $plugin->opts->critical, + ); + } + + my ($code, $message) = $plugin->check_messages; + $plugin->nagios_exit($code, 'performancedata: ' . $message); +} + sub check_interfaces { my $plugin = shift; From a842b41e3a64dc49b5d8dd995d085fc27c28e1a3 Mon Sep 17 00:00:00 2001 From: Ricardo Date: Thu, 10 Aug 2017 14:15:15 +0200 Subject: [PATCH 12/38] added command performancedata to Changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d5a7c0c..1df4595 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ - added command server to check status of Load Balancing Servers - added command hwinfo to just print information about the Netscaler itself - added command interfaces to check state of all interfaces and add performance data for each interface +- added command to request performance data - added Icinga2 config templates ## 1.1.1 (2017-06-10) From c368613851022a3d245ea29e4a8e1ad2a56773ca Mon Sep 17 00:00:00 2001 From: Ricardo Date: Thu, 10 Aug 2017 14:30:38 +0200 Subject: [PATCH 13/38] added "performancedata" command to README --- README.md | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/README.md b/README.md index 6a91317..1ed24f1 100644 --- a/README.md +++ b/README.md @@ -13,6 +13,7 @@ Currently the plugin has the following subcommands: - **server:** check status of Load Balancing Servers - **hwinfo:** just print information about the Netscaler itself - **interfaces:** check state of all interfaces and add performance data for each interface +- **performancedata:** gather performancedata from all sorts of API endpoints - **debug:** debug command, print all data for a endpoint This plugin works with VPX, MPX, SDX and CPX NetScaler Appliances. The api responses may differ by build, appliance type and your installed license. @@ -126,6 +127,25 @@ If you want to connect to your NetScaler with SSL/HTTPS you should also install # NetScaler::Interfaces ./check_netscaler.pl -H ${IPADDR} -s -C interfaces +## Request performance data +##### all fields must be defined via "-n" option and be seperated with a comma + + # NetScaler::Performancedata on Cache hit/misses + ./check_netscaler.pl -H ${IPADDR} -s -C performancedata -o ns -n cachetothits,cachetotmisses + + # NetScaler::Performancedata on tcp connections + ./check_netscaler.pl -H ${IPADDR} -s -C performancedata -o ns -n tcpcurclientconn,tcpcurclientconnestablished,tcpcurserverconn,tcpcurserverconnestablished + + # find more object names to check out for object type "ns" + /check_netscaler.pl -H ${IPADDR} -s -C debug -o ns + + # more interesting performance data object types + * ns + * cache + * protocolhttp + * protocolip + * protocoltcp + ## Debug command # Print all LB vServers (stat endpoint) ./check_netscaler.pl -H ${IPADDR} -s -C debug -o lbvserver From fb32f29c2306402888a0517097a50b2acd8ec4b9 Mon Sep 17 00:00:00 2001 From: Ricardo Date: Thu, 10 Aug 2017 14:37:26 +0200 Subject: [PATCH 14/38] added a contributers section to README --- README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.md b/README.md index 1ed24f1..9f20c76 100644 --- a/README.md +++ b/README.md @@ -171,6 +171,12 @@ username=nagios password=password ``` +# Contributors +- @slauger +- @macampo +- @Velociraptor85 +- @bb-ricardo + # NITRO API Documentation You will find a full documentation about the NITRO API on your NetScaler Appliance in the "Download" area. From 7fce71ecbffeb31d11d961cb08fbe43dff68ec73 Mon Sep 17 00:00:00 2001 From: Ricardo Date: Thu, 10 Aug 2017 15:43:11 +0200 Subject: [PATCH 15/38] performancedata command van now parse arrays Now it is possible to get performance data from arrays like Interface. * identifier and field name need to be separated by '.' * example Interface endpoint: -C performancedata -o Interface -n id.tottxbytes,id.totrxbytes --- check_netscaler.pl | 62 ++++++++++++++++++++++++++++++++++++---------- 1 file changed, 49 insertions(+), 13 deletions(-) diff --git a/check_netscaler.pl b/check_netscaler.pl index 64583bf..56a3c96 100755 --- a/check_netscaler.pl +++ b/check_netscaler.pl @@ -694,23 +694,59 @@ sub get_performancedata $params{'objectname'} = undef; $params{'options'} = undef; + if (not defined ($plugin->opts->objectname)) { + $plugin->nagios_exit(UNKNOWN, 'performancedata: no object name(s) \"-n\" set'); + } + my $response = nitro_client($plugin, \%params); $response = $response->{$params{'objecttype'}}; - foreach my $objectname (split(",",$plugin->opts->objectname)) { - if (not defined($response->{$objectname})) { - $plugin->nagios_exit(UNKNOWN, 'performancedata: object name "' . $objectname . '" not found in output.'); + if ( ref $response eq "ARRAY" ) { + foreach $response (@{$response}) { + foreach my $objectname (split(",",$plugin->opts->objectname)) { + if (not index($objectname, ".") != -1) { + $plugin->nagios_exit(UNKNOWN, 'performancedata: return data is an array and contains multible objects. You need te seperate id and name with a ".".'); + } + + my ($objectname_id, $objectname_name) = split /\./, $objectname; + + if (not defined($response->{$objectname_id})) { + $plugin->nagios_exit(UNKNOWN, 'performancedata: object id "' . $objectname_id . '" not found in output.'); + } + if (not defined($response->{$objectname_name})) { + $plugin->nagios_exit(UNKNOWN, 'performancedata: object name "' . $objectname_name . '" not found in output.'); + } + + $plugin->add_message(OK, $response->{$objectname_id} .".". $objectname_name .":", $response->{$objectname_name}. ","); + + $plugin->add_perfdata( + label => "'". $response->{$objectname_id} .".". $objectname_name."'", + value => $response->{$objectname_name}, + min => undef, + max => undef, + warning => $plugin->opts->warning, + critical => $plugin->opts->critical, + ); + } } - $plugin->add_message(OK, $objectname .":", $response->{$objectname}. ","); - - $plugin->add_perfdata( - label => "'".$objectname."'", - value => $response->{$objectname}, - min => undef, - max => undef, - warning => $plugin->opts->warning, - critical => $plugin->opts->critical, - ); + } elsif ( ref $response eq "HASH" ) { + foreach my $objectname (split(",",$plugin->opts->objectname)) { + if (not defined($response->{$objectname})) { + $plugin->nagios_exit(UNKNOWN, 'performancedata: object name "' . $objectname . '" not found in output.'); + } + $plugin->add_message(OK, $objectname .":", $response->{$objectname}. ","); + + $plugin->add_perfdata( + label => "'".$objectname."'", + value => $response->{$objectname}, + min => undef, + max => undef, + warning => $plugin->opts->warning, + critical => $plugin->opts->critical, + ); + } + } else { + $plugin->nagios_exit(UNKNOWN, 'performancedata: unable to parse data. Returned data is not a HASH or ARRAY!'); } my ($code, $message) = $plugin->check_messages; From 9c6b9fe546898af4e48a6ca200a090bd85f71150 Mon Sep 17 00:00:00 2001 From: Ricardo Date: Thu, 10 Aug 2017 15:51:00 +0200 Subject: [PATCH 16/38] fixed issue with interfaces perf data output --- check_netscaler.pl | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/check_netscaler.pl b/check_netscaler.pl index 56a3c96..4b67789 100755 --- a/check_netscaler.pl +++ b/check_netscaler.pl @@ -689,7 +689,7 @@ sub get_performancedata my $plugin = shift; my %params; - $params{'endpoint'} = 'stat'; + $params{'endpoint'} = $plugin->opts->endpoint || 'stat'; $params{'objecttype'} = $plugin->opts->objecttype; $params{'objectname'} = undef; $params{'options'} = undef; @@ -789,19 +789,19 @@ sub check_interfaces $plugin->add_message($interface_state, "device: " . $interface->{'devicename'} . ' (speed: ' . $interface_speed . ', MTU: ' . $interface->{'actualmtu'} . ', VLAN: ' . $interface->{'vlan'} . ', type: ' . $interface->{'intftype'} . ') ' . $interface->{'state'} . ';'); $plugin->add_perfdata( - label => "\'".$interface->{'devicename'} . "_rxbytes'", + label => "\'".$interface->{'devicename'} . ".rxbytes'", value => $interface->{'rxbytes'}."B" ); $plugin->add_perfdata( - label => "\'".$interface->{'devicename'} . "_txbytes'", + label => "\'".$interface->{'devicename'} . ".txbytes'", value => $interface->{'txbytes'}."B" ); $plugin->add_perfdata( - label => "\'".$interface->{'devicename'} . "rxerrors'", + label => "\'".$interface->{'devicename'} . ".rxerrors'", value => $interface->{'rxerrors'}."c" ); $plugin->add_perfdata( - label => "\'".$interface->{'devicename'} . "txerrors'", + label => "\'".$interface->{'devicename'} . ".txerrors'", value => $interface->{'txerrors'}."c" ); } From 4f58ef6900374fd94be46a0f070331b282061a55 Mon Sep 17 00:00:00 2001 From: Ricardo Date: Thu, 10 Aug 2017 16:58:27 +0200 Subject: [PATCH 17/38] Added new command servicegroup check the state of a servicegroup and its members --- check_netscaler.pl | 73 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 72 insertions(+), 1 deletion(-) diff --git a/check_netscaler.pl b/check_netscaler.pl index 4b67789..8fc9c01 100755 --- a/check_netscaler.pl +++ b/check_netscaler.pl @@ -166,6 +166,9 @@ } elsif ($plugin->opts->command eq 'interfaces') { # check the state of all interfaces check_interfaces($plugin); +} elsif ($plugin->opts->command eq 'servicegroup') { + # check the state of a servicegroup and its members + check_servicegroup($plugin); } elsif ($plugin->opts->command eq 'debug') { # dump the full response of the nitro api check_debug($plugin); @@ -695,7 +698,7 @@ sub get_performancedata $params{'options'} = undef; if (not defined ($plugin->opts->objectname)) { - $plugin->nagios_exit(UNKNOWN, 'performancedata: no object name(s) \"-n\" set'); + $plugin->nagios_exit(UNKNOWN, 'performancedata: no object name(s) "-n" set'); } my $response = nitro_client($plugin, \%params); @@ -813,6 +816,74 @@ sub check_interfaces $plugin->nagios_exit($code, 'Interfaces: ' . $message); } +sub check_servicegroup +{ + my $plugin = shift; + my @servicegroup_errors; + + my %params; + $params{'endpoint'} = 'config'; + $params{'objecttype'} = 'servicegroup'; + $params{'objectname'} = $plugin->opts->objectname; + $params{'options'} = undef; + + if (not defined ($plugin->opts->objectname)) { + $plugin->nagios_exit(UNKNOWN, 'servicegroup: no object name "-n" set'); + } + + my %servicegroup_states; + $servicegroup_states{"state"} = "ENABLED"; + $servicegroup_states{"servicegroupeffectivestate"} = "UP"; + $servicegroup_states{"monstate"} = "ENABLED"; + $servicegroup_states{"healthmonitor"} = "YES"; + + my %servicegroup_member_states; + $servicegroup_member_states{"state"} = "ENABLED"; + $servicegroup_member_states{"svrstate"} = "UP"; + + my $response = nitro_client($plugin, \%params); + my $servicegroup_response = $response->{$params{'objecttype'}}; + my $servicegroup_state = OK; + + # check servicegroup health status + foreach my $servicegroup_response (@{$servicegroup_response}) { + + foreach my $servicegroup_check_key ( keys %servicegroup_states ) { + + if ($servicegroup_response->{$servicegroup_check_key} ne $servicegroup_states{$servicegroup_check_key}) { + push(@servicegroup_errors, 'servicegroup ' . $servicegroup_response->{"servicegroupname"} . ' "'. $servicegroup_check_key . '" is: '. $servicegroup_states{$servicegroup_check_key}); + $servicegroup_state = CRITICAL; + } + } + $plugin->add_message(OK, $servicegroup_response->{'servicegroupname'} . ' (' . $servicegroup_response->{'servicetype'} . ') - state: ' . $servicegroup_response->{'servicegroupeffectivestate'} . ' -'); + } + + # get servicegroup members status + $params{'objecttype'} = 'servicegroup_servicegroupmember_binding'; + + $response = nitro_client($plugin, \%params); + my $servicegroup_members_response = $response->{$params{'objecttype'}}; + + # check servicegroup members health status + foreach my $servicegroup_members_response (@{$servicegroup_members_response}) { + + foreach my $servicegroup_members_check_key ( keys %servicegroup_member_states ) { + + if ($servicegroup_members_response->{$servicegroup_members_check_key} ne $servicegroup_member_states{$servicegroup_members_check_key}) { + push(@servicegroup_errors, 'servicegroup member ' . $servicegroup_members_response->{"servername"} . ' "'. $servicegroup_members_check_key . '" is: '. $servicegroup_member_states{$servicegroup_members_check_key}); + $servicegroup_state = CRITICAL; + } + } + $plugin->add_message(OK, $servicegroup_members_response->{'servername'} . ' (' . $servicegroup_members_response->{'ip'}.':'. $servicegroup_members_response->{'port'} . ') - state: ' . $servicegroup_members_response->{'svrstate'} .','); + } + + my ($code, $message) = $plugin->check_messages; + if (scalar @servicegroup_errors != 0 ) { + $message = join(", ",@servicegroup_errors). " - ". $message + } + $plugin->nagios_exit($servicegroup_state, 'servicegroup: ' . $message); +} + sub check_debug { my $plugin = shift; From 8bc0dd246eb60b1072cb967dade2213deb106a0c Mon Sep 17 00:00:00 2001 From: Ricardo Date: Thu, 10 Aug 2017 16:59:33 +0200 Subject: [PATCH 18/38] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1df4595..fcbe25d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ - added command hwinfo to just print information about the Netscaler itself - added command interfaces to check state of all interfaces and add performance data for each interface - added command to request performance data +- added command to check the state of a servicegroup and its members - added Icinga2 config templates ## 1.1.1 (2017-06-10) From f55647856cb057fdabe1d5779d088a36a09e5aff Mon Sep 17 00:00:00 2001 From: Ricardo Date: Thu, 10 Aug 2017 17:01:45 +0200 Subject: [PATCH 19/38] added command servicegroup to README --- README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.md b/README.md index 9f20c76..b0e8c4e 100644 --- a/README.md +++ b/README.md @@ -11,6 +11,7 @@ Currently the plugin has the following subcommands: - **nsconfig:** check for configuration changes which are not saved to disk - **staserver:** check if configured STA servers are available - **server:** check status of Load Balancing Servers +- **servicegroup:** check the state of a servicegroup and its members - **hwinfo:** just print information about the Netscaler itself - **interfaces:** check state of all interfaces and add performance data for each interface - **performancedata:** gather performancedata from all sorts of API endpoints @@ -117,6 +118,11 @@ If you want to connect to your NetScaler with SSL/HTTPS you should also install # NetScaler::Server ./check_netscaler.pl -H ${IPADDR} -s -C server +## Check status of a service group + + # NetScaler::Servicegroup::vs_vpn_gateway + ./check_netscaler.pl -H ${IPADDR} -s -C servicegroup -n vs_vpn_gateway + ## Get information about the netscaler # NetScaler::HWInfo From 61ef37c84b87c43f5bbd1bd0c954060dcaef2d8e Mon Sep 17 00:00:00 2001 From: Ricardo Date: Thu, 10 Aug 2017 21:29:15 +0200 Subject: [PATCH 20/38] unified threshold functions to check_threshold --- check_netscaler.pl | 66 ++++++++++------------------------------------ 1 file changed, 14 insertions(+), 52 deletions(-) diff --git a/check_netscaler.pl b/check_netscaler.pl index 8fc9c01..5c3812e 100755 --- a/check_netscaler.pl +++ b/check_netscaler.pl @@ -135,10 +135,10 @@ check_state($plugin); } elsif ($plugin->opts->command eq 'above') { # check if a response is above a threshold - check_threshold_above($plugin); + check_threshold($plugin, $plugin->opts->command); } elsif ($plugin->opts->command eq 'below') { # check if a response is below a threshold - check_threshold_below($plugin); + check_threshold($plugin, $plugin->opts->command); } elsif ($plugin->opts->command eq 'string') { # check if a response does contains a specific string check_string($plugin); @@ -446,9 +446,10 @@ sub check_string_not } } -sub check_threshold_above +sub check_threshold { my $plugin = shift; + my $direction = shift; if (!defined $plugin->opts->objecttype) { $plugin->nagios_die('command requires parameter for objecttype'); @@ -462,48 +463,8 @@ sub check_threshold_above $plugin->nagios_die('command requires parameter for warning and critical'); } - my %params; - $params{'endpoint'} = $plugin->opts->endpoint || 'stat'; - $params{'objecttype'} = $plugin->opts->objecttype; - $params{'objectname'} = undef; - $params{'options'} = undef; - - my $response = nitro_client($plugin, \%params); - $response = $response->{$plugin->opts->objecttype}; - - - $plugin->add_perfdata( - label => $plugin->opts->objecttype . '::' . $plugin->opts->objectname, - value => $response->{$plugin->opts->objectname}, - min => 0, - max => undef, - warning => $plugin->opts->warning, - critical => $plugin->opts->critical, - ); - - if ($response->{$plugin->opts->objectname} >= $plugin->opts->critical) { - $plugin->nagios_exit(CRITICAL, $plugin->opts->objecttype . '::' . $plugin->opts->objectname . ' is above threshold (current: ' . $response->{$plugin->opts->objectname} . ', critical: ' . $plugin->opts->critical . ')'); - } elsif ($response->{$plugin->opts->objectname} >= $plugin->opts->warning) { - $plugin->nagios_exit(WARNING, $plugin->opts->objecttype . '::' . $plugin->opts->objectname . ' is above threshold (current: ' . $response->{$plugin->opts->objectname} . ', warning: ' . $plugin->opts->warning . ')'); - } else { - $plugin->nagios_exit(OK, $plugin->opts->objecttype . '::' . $plugin->opts->objectname . ' OK ('.$response->{$plugin->opts->objectname}.')'); - } -} - -sub check_threshold_below -{ - my $plugin = shift; - - if (!defined $plugin->opts->objecttype) { - $plugin->nagios_die('command requires parameter for objecttype'); - } - - if (!defined $plugin->opts->objectname) { - $plugin->nagios_die('command requires parameter for objectname'); - } - - if (!defined $plugin->opts->warning || !defined $plugin->opts->critical) { - $plugin->nagios_die('command requires parameter for warning and critical'); + if ($direction ne "above" && $direction ne "below") { + $plugin->nagios_die('threshold can only be checked for "above" and "below"'); } my %params; @@ -515,21 +476,22 @@ sub check_threshold_below my $response = nitro_client($plugin, \%params); $response = $response->{$plugin->opts->objecttype}; + $plugin->add_perfdata( label => $plugin->opts->objecttype . '::' . $plugin->opts->objectname, value => $response->{$plugin->opts->objectname}, - min => 0, + min => undef, max => undef, warning => $plugin->opts->warning, critical => $plugin->opts->critical, ); - if ($response->{$plugin->opts->objectname} <= $plugin->opts->critical) { - $plugin->nagios_exit(CRITICAL, $plugin->opts->objecttype . '::' . $plugin->opts->objectname . ' is below threshold (current: ' . $response->{$plugin->opts->objectname} . ', critical: ' . $plugin->opts->critical . ')'); - } elsif ($response->{$plugin->opts->objectname} <= $plugin->opts->warning) { - $plugin->nagios_exit(WARNING, $plugin->opts->objecttype . '::' . $plugin->opts->objectname . ' is below threshold (current: ' . $response->{$plugin->opts->objectname} . ', warning: ' . $plugin->opts->warning . ')'); + if (($direction eq "above" && $response->{$plugin->opts->objectname} >= $plugin->opts->critical) || ($direction eq "below" && $response->{$plugin->opts->objectname} <= $plugin->opts->critical)) { + $plugin->nagios_exit(CRITICAL, $plugin->opts->objecttype . '::' . $plugin->opts->objectname . ' is ' . $direction . ' threshold (current: ' . $response->{$plugin->opts->objectname} . ', critical: ' . $plugin->opts->critical . ')'); + } elsif (($direction eq "above" && $response->{$plugin->opts->objectname} >= $plugin->opts->warning) || ($direction eq "below" && $response->{$plugin->opts->objectname} <= $plugin->opts->warning)) { + $plugin->nagios_exit(WARNING, $plugin->opts->objecttype . '::' . $plugin->opts->objectname . ' is ' . $direction . ' threshold (current: ' . $response->{$plugin->opts->objectname} . ', warning: ' . $plugin->opts->warning . ')'); } else { - $plugin->nagios_exit(OK, $plugin->opts->objecttype . '::' . $plugin->opts->objectname . ' ('.$response->{$plugin->opts->objectname}.')'); + $plugin->nagios_exit(OK, $plugin->opts->objecttype . '::' . $plugin->opts->objectname . ' OK ('.$response->{$plugin->opts->objectname}.')'); } } @@ -552,7 +514,7 @@ sub check_sslcert foreach $response (@{$response}) { if ($response->{daystoexpiration} <= $plugin->opts->critical) { - $plugin->add_message(CRITICAL, $response->{certkey} . ' expires in ' . $response->{daystoexpiration} . ' days;'); + $plugin->add_message(CRITICAL, $response->{certkey} . ' expires in ' . $response->{daystoexpiration} . ' days;'); } elsif ($response->{daystoexpiration} <= $plugin->opts->warning) { $plugin->add_message(WARNING, $response->{certkey} . ' expires in ' . $response->{daystoexpiration} . ' days;'); } From 2817c472f6fe86b53b8e59fab1d0991575f0238d Mon Sep 17 00:00:00 2001 From: Ricardo Date: Fri, 11 Aug 2017 13:09:15 +0200 Subject: [PATCH 21/38] enhanced performance data output for "perfromancedata" --- check_netscaler.pl | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/check_netscaler.pl b/check_netscaler.pl index 5c3812e..fdaaf07 100755 --- a/check_netscaler.pl +++ b/check_netscaler.pl @@ -682,10 +682,10 @@ sub get_performancedata $plugin->nagios_exit(UNKNOWN, 'performancedata: object name "' . $objectname_name . '" not found in output.'); } - $plugin->add_message(OK, $response->{$objectname_id} .".". $objectname_name .":", $response->{$objectname_name}. ","); + $plugin->add_message(OK, $params{'objecttype'} . "." . $response->{$objectname_id} . "." . $objectname_name . ":" . $response->{$objectname_name} . ","); $plugin->add_perfdata( - label => "'". $response->{$objectname_id} .".". $objectname_name."'", + label => "'" . $params{'objecttype'} . "." . $response->{$objectname_id} . "." . $objectname_name . "'", value => $response->{$objectname_name}, min => undef, max => undef, @@ -699,10 +699,10 @@ sub get_performancedata if (not defined($response->{$objectname})) { $plugin->nagios_exit(UNKNOWN, 'performancedata: object name "' . $objectname . '" not found in output.'); } - $plugin->add_message(OK, $objectname .":", $response->{$objectname}. ","); + $plugin->add_message(OK, $params{'objecttype'} . "." . $objectname .":", $response->{$objectname}. ","); $plugin->add_perfdata( - label => "'".$objectname."'", + label => "'" . $params{'objecttype'} . "." . $objectname . "'", value => $response->{$objectname}, min => undef, max => undef, From 1c4c25d1558fe5294dec9cd28ffe774cb431d47d Mon Sep 17 00:00:00 2001 From: Ricardo Date: Fri, 11 Aug 2017 13:48:57 +0200 Subject: [PATCH 22/38] added member quorum check to servicegroup command now you can define (in percent) how many servicegroup members can go DOWN until you get a WARNING or CRITICAL output --- check_netscaler.pl | 75 +++++++++++++++++++++++++++++++++++----------- 1 file changed, 57 insertions(+), 18 deletions(-) diff --git a/check_netscaler.pl b/check_netscaler.pl index fdaaf07..275c8a1 100755 --- a/check_netscaler.pl +++ b/check_netscaler.pl @@ -783,6 +783,12 @@ sub check_servicegroup my $plugin = shift; my @servicegroup_errors; + # define quorum (in percent) of working servicegroup members + my $member_quorum_warning = $plugin->opts->warning || "90"; + my $member_quorum_critical = $plugin->opts->critical || "50"; + + my %member_state; + my %params; $params{'endpoint'} = 'config'; $params{'objecttype'} = 'servicegroup'; @@ -790,18 +796,18 @@ sub check_servicegroup $params{'options'} = undef; if (not defined ($plugin->opts->objectname)) { - $plugin->nagios_exit(UNKNOWN, 'servicegroup: no object name "-n" set'); + $plugin->nagios_die('servicegroup: no object name "-n" set'); } - my %servicegroup_states; - $servicegroup_states{"state"} = "ENABLED"; - $servicegroup_states{"servicegroupeffectivestate"} = "UP"; - $servicegroup_states{"monstate"} = "ENABLED"; - $servicegroup_states{"healthmonitor"} = "YES"; + my %healthy_servicegroup_states; + $healthy_servicegroup_states{"state"} = "ENABLED"; + $healthy_servicegroup_states{"servicegroupeffectivestate"} = "UP"; + $healthy_servicegroup_states{"monstate"} = "ENABLED"; + $healthy_servicegroup_states{"healthmonitor"} = "YES"; - my %servicegroup_member_states; - $servicegroup_member_states{"state"} = "ENABLED"; - $servicegroup_member_states{"svrstate"} = "UP"; + my %healthy_servicegroup_member_states; + $healthy_servicegroup_member_states{"state"} = "ENABLED"; + $healthy_servicegroup_member_states{"svrstate"} = "UP"; my $response = nitro_client($plugin, \%params); my $servicegroup_response = $response->{$params{'objecttype'}}; @@ -810,11 +816,10 @@ sub check_servicegroup # check servicegroup health status foreach my $servicegroup_response (@{$servicegroup_response}) { - foreach my $servicegroup_check_key ( keys %servicegroup_states ) { + foreach my $servicegroup_check_key ( keys %healthy_servicegroup_states ) { - if ($servicegroup_response->{$servicegroup_check_key} ne $servicegroup_states{$servicegroup_check_key}) { - push(@servicegroup_errors, 'servicegroup ' . $servicegroup_response->{"servicegroupname"} . ' "'. $servicegroup_check_key . '" is: '. $servicegroup_states{$servicegroup_check_key}); - $servicegroup_state = CRITICAL; + if ($servicegroup_response->{$servicegroup_check_key} ne $healthy_servicegroup_states{$servicegroup_check_key}) { + push(@servicegroup_errors, 'servicegroup ' . $servicegroup_response->{"servicegroupname"} . ' "'. $servicegroup_check_key . '" is: '. $healthy_servicegroup_states{$servicegroup_check_key}); } } $plugin->add_message(OK, $servicegroup_response->{'servicegroupname'} . ' (' . $servicegroup_response->{'servicetype'} . ') - state: ' . $servicegroup_response->{'servicegroupeffectivestate'} . ' -'); @@ -829,16 +834,50 @@ sub check_servicegroup # check servicegroup members health status foreach my $servicegroup_members_response (@{$servicegroup_members_response}) { - foreach my $servicegroup_members_check_key ( keys %servicegroup_member_states ) { + foreach my $servicegroup_members_check_key ( keys %healthy_servicegroup_member_states ) { - if ($servicegroup_members_response->{$servicegroup_members_check_key} ne $servicegroup_member_states{$servicegroup_members_check_key}) { - push(@servicegroup_errors, 'servicegroup member ' . $servicegroup_members_response->{"servername"} . ' "'. $servicegroup_members_check_key . '" is: '. $servicegroup_member_states{$servicegroup_members_check_key}); - $servicegroup_state = CRITICAL; + if ($servicegroup_members_response->{$servicegroup_members_check_key} ne $healthy_servicegroup_member_states{$servicegroup_members_check_key}) { + push(@servicegroup_errors, 'servicegroup member ' . $servicegroup_members_response->{"servername"} . ' "'. $servicegroup_members_check_key . '" is '. $healthy_servicegroup_member_states{$servicegroup_members_check_key}); + $member_state{$servicegroup_members_response->{"servername"}} = "DOWN"; } } - $plugin->add_message(OK, $servicegroup_members_response->{'servername'} . ' (' . $servicegroup_members_response->{'ip'}.':'. $servicegroup_members_response->{'port'} . ') - state: ' . $servicegroup_members_response->{'svrstate'} .','); + if (not defined $member_state{$servicegroup_members_response->{"servername"}}) { + $member_state{$servicegroup_members_response->{"servername"}} = "UP"; + } + $plugin->add_message(OK, $servicegroup_members_response->{'servername'} . ' (' . $servicegroup_members_response->{'ip'}.':'. $servicegroup_members_response->{'port'} . ') is ' . $servicegroup_members_response->{'svrstate'} .','); + } + + # count states + my $members_up = 0; + my $members_down = 0; + foreach my $member_state_key ( keys %member_state ) { + if ($member_state{$member_state_key} eq "DOWN") { + $members_down++; + } else { + $members_up++; + } } + # check quorum + my $member_quorum = sprintf("%1.2f", 100 / ( $members_up + $members_down ) * $members_up); + + if ($member_quorum <= $member_quorum_critical) { + $servicegroup_state = CRITICAL; + } elsif ($member_quorum <= $member_quorum_warning) { + $servicegroup_state = WARNING; + } + + $plugin->add_message(OK, "member quorum: " . $member_quorum . "% (UP/DOWN): " . $members_up . "/" . $members_down); + + $plugin->add_perfdata( + label => "'" . $plugin->opts->objectname . ".member_quorum'", + value => $member_quorum."%", + min => 0, + max => 100, + warning => $member_quorum_warning, + critical => $member_quorum_critical, + ); + my ($code, $message) = $plugin->check_messages; if (scalar @servicegroup_errors != 0 ) { $message = join(", ",@servicegroup_errors). " - ". $message From 1f721963c260601edf5dbf3396fe9165da3327f8 Mon Sep 17 00:00:00 2001 From: Ricardo Date: Fri, 11 Aug 2017 13:52:28 +0200 Subject: [PATCH 23/38] updated CHANGELOG for servicegroup command --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fcbe25d..5473a43 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,7 +3,7 @@ - added command hwinfo to just print information about the Netscaler itself - added command interfaces to check state of all interfaces and add performance data for each interface - added command to request performance data -- added command to check the state of a servicegroup and its members +- added command to check the state of a servicegroup and its members (set warning and critical values for member quorum) - added Icinga2 config templates ## 1.1.1 (2017-06-10) From dcaaf93a20a08f03c15e515d56dd7b6ade559c0f Mon Sep 17 00:00:00 2001 From: Ricardo Date: Fri, 11 Aug 2017 13:58:51 +0200 Subject: [PATCH 24/38] Updated README with latest changes --- README.md | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index b0e8c4e..07bf826 100644 --- a/README.md +++ b/README.md @@ -119,9 +119,9 @@ If you want to connect to your NetScaler with SSL/HTTPS you should also install ./check_netscaler.pl -H ${IPADDR} -s -C server ## Check status of a service group - +##### define member quorum (in percent) with warning and critical values # NetScaler::Servicegroup::vs_vpn_gateway - ./check_netscaler.pl -H ${IPADDR} -s -C servicegroup -n vs_vpn_gateway + ./check_netscaler.pl -H ${IPADDR} -s -C servicegroup -n vs_vpn_gateway -w 75 -c 50 ## Get information about the netscaler @@ -142,6 +142,9 @@ If you want to connect to your NetScaler with SSL/HTTPS you should also install # NetScaler::Performancedata on tcp connections ./check_netscaler.pl -H ${IPADDR} -s -C performancedata -o ns -n tcpcurclientconn,tcpcurclientconnestablished,tcpcurserverconn,tcpcurserverconnestablished + # NetScaler::Performancedata on network interfaces + ./check_netscaler.pl -H ${IPADDR} -s -C performancedata -o Interface -n id.totrxbytes + # find more object names to check out for object type "ns" /check_netscaler.pl -H ${IPADDR} -s -C debug -o ns @@ -177,8 +180,10 @@ username=nagios password=password ``` -# Contributors +# Authors - @slauger + +# Contributors - @macampo - @Velociraptor85 - @bb-ricardo From 28949d4694ab3e23359be0e61dc73cbe7d6d48f5 Mon Sep 17 00:00:00 2001 From: Ricardo Date: Fri, 11 Aug 2017 14:24:17 +0200 Subject: [PATCH 25/38] merged check_string and check_string_not into one function --- check_netscaler.pl | 47 +++++++++------------------------------------- 1 file changed, 9 insertions(+), 38 deletions(-) diff --git a/check_netscaler.pl b/check_netscaler.pl index 275c8a1..836a9c4 100755 --- a/check_netscaler.pl +++ b/check_netscaler.pl @@ -141,10 +141,10 @@ check_threshold($plugin, $plugin->opts->command); } elsif ($plugin->opts->command eq 'string') { # check if a response does contains a specific string - check_string($plugin); + check_string($plugin, "matches"); } elsif ($plugin->opts->command eq 'string_not') { # check if a response does not contains a specific string - check_string_not($plugin); + check_string($plugin, "matches not"); } elsif ($plugin->opts->command eq 'sslcert') { # check for the lifetime of installed certificates check_sslcert($plugin); @@ -381,6 +381,7 @@ sub check_state sub check_string { my $plugin = shift; + my $type_of_string_comparison = shift; if (!defined $plugin->opts->objecttype) { $plugin->nagios_die('command requires parameter for objecttype'); @@ -394,38 +395,8 @@ sub check_string $plugin->nagios_die('command requires parameter for warning and critical'); } - my %params; - $params{'endpoint'} = $plugin->opts->endpoint || 'stat'; - $params{'objecttype'} = $plugin->opts->objecttype; - $params{'objectname'} = undef; - $params{'options'} = undef; - - my $response = nitro_client($plugin, \%params); - $response = $response->{$plugin->opts->objecttype}; - - if ($response->{$plugin->opts->objectname} eq $plugin->opts->critical) { - $plugin->nagios_exit(CRITICAL, $plugin->opts->objecttype . '::' . $plugin->opts->objectname . ' matches keyword (current: ' . $response->{$plugin->opts->objectname} . ', critical: ' . $plugin->opts->critical . ')'); - } elsif ($response->{$plugin->opts->objectname} eq $plugin->opts->warning) { - $plugin->nagios_exit(WARNING, $plugin->opts->objecttype . '::' . $plugin->opts->objectname . ' matches keyword (current: ' . $response->{$plugin->opts->objectname} . ', warning: ' . $plugin->opts->warning . ')'); - } else { - $plugin->nagios_exit(OK, $plugin->opts->objecttype . '::' . $plugin->opts->objectname . ' OK ('.$response->{$plugin->opts->objectname}.')'); - } -} - -sub check_string_not -{ - my $plugin = shift; - - if (!defined $plugin->opts->objecttype) { - $plugin->nagios_die('command requires parameter for objecttype'); - } - - if (!defined $plugin->opts->objectname) { - $plugin->nagios_die('command requires parameter for objectname'); - } - - if (!defined $plugin->opts->warning || !defined $plugin->opts->critical) { - $plugin->nagios_die('command requires parameter for warning and critical'); + if ($type_of_string_comparison ne "matches" && $type_of_string_comparison ne "matches not") { + $plugin->nagios_die('string can only be checked for "matches" and "matches not"'); } my %params; @@ -437,10 +408,10 @@ sub check_string_not my $response = nitro_client($plugin, \%params); $response = $response->{$plugin->opts->objecttype}; - if ($response->{$plugin->opts->objectname} ne $plugin->opts->critical) { - $plugin->nagios_exit(CRITICAL, $plugin->opts->objecttype . '::' . $plugin->opts->objectname . ' not matches keyword (current: ' . $response->{$plugin->opts->objectname} . ', critical: ' . $plugin->opts->critical . ')'); - } elsif ($response->{$plugin->opts->objectname} ne $plugin->opts->warning) { - $plugin->nagios_exit(WARNING, $plugin->opts->objecttype . '::' . $plugin->opts->objectname . ' not matches keyword (current: ' . $response->{$plugin->opts->objectname} . ', warning: ' . $plugin->opts->warning . ')'); + if (($type_of_string_comparison eq "matches" && $response->{$plugin->opts->objectname} eq $plugin->opts->critical) || ($type_of_string_comparison eq "matches not" && $response->{$plugin->opts->objectname} ne $plugin->opts->critical)) { + $plugin->nagios_exit(CRITICAL, $plugin->opts->objecttype . '::' . $plugin->opts->objectname . ' ' . $type_of_string_comparison . ' keyword (current: ' . $response->{$plugin->opts->objectname} . ', critical: ' . $plugin->opts->critical . ')'); + } elsif (($type_of_string_comparison eq "matches" && $response->{$plugin->opts->objectname} eq $plugin->opts->warning) || ($type_of_string_comparison eq "matches not" && $response->{$plugin->opts->objectname} ne $plugin->opts->warning)) { + $plugin->nagios_exit(WARNING, $plugin->opts->objecttype . '::' . $plugin->opts->objectname . ' ' . $type_of_string_comparison . ' keyword (current: ' . $response->{$plugin->opts->objectname} . ', warning: ' . $plugin->opts->warning . ')'); } else { $plugin->nagios_exit(OK, $plugin->opts->objecttype . '::' . $plugin->opts->objectname . ' OK ('.$response->{$plugin->opts->objectname}.')'); } From 2d286c141e7735e87c0b6ff928d97e7b58b823b7 Mon Sep 17 00:00:00 2001 From: Ricardo Date: Fri, 11 Aug 2017 14:26:38 +0200 Subject: [PATCH 26/38] make use of nagios_die I like the name of the function --- check_netscaler.pl | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/check_netscaler.pl b/check_netscaler.pl index 836a9c4..5bb8f6c 100755 --- a/check_netscaler.pl +++ b/check_netscaler.pl @@ -631,7 +631,7 @@ sub get_performancedata $params{'options'} = undef; if (not defined ($plugin->opts->objectname)) { - $plugin->nagios_exit(UNKNOWN, 'performancedata: no object name(s) "-n" set'); + $plugin->nagios_die('performancedata: no object name(s) "-n" set'); } my $response = nitro_client($plugin, \%params); @@ -641,16 +641,16 @@ sub get_performancedata foreach $response (@{$response}) { foreach my $objectname (split(",",$plugin->opts->objectname)) { if (not index($objectname, ".") != -1) { - $plugin->nagios_exit(UNKNOWN, 'performancedata: return data is an array and contains multible objects. You need te seperate id and name with a ".".'); + $plugin->nagios_die('performancedata: return data is an array and contains multible objects. You need te seperate id and name with a ".".'); } my ($objectname_id, $objectname_name) = split /\./, $objectname; if (not defined($response->{$objectname_id})) { - $plugin->nagios_exit(UNKNOWN, 'performancedata: object id "' . $objectname_id . '" not found in output.'); + $plugin->nagios_die('performancedata: object id "' . $objectname_id . '" not found in output.'); } if (not defined($response->{$objectname_name})) { - $plugin->nagios_exit(UNKNOWN, 'performancedata: object name "' . $objectname_name . '" not found in output.'); + $plugin->nagios_die('performancedata: object name "' . $objectname_name . '" not found in output.'); } $plugin->add_message(OK, $params{'objecttype'} . "." . $response->{$objectname_id} . "." . $objectname_name . ":" . $response->{$objectname_name} . ","); @@ -668,7 +668,7 @@ sub get_performancedata } elsif ( ref $response eq "HASH" ) { foreach my $objectname (split(",",$plugin->opts->objectname)) { if (not defined($response->{$objectname})) { - $plugin->nagios_exit(UNKNOWN, 'performancedata: object name "' . $objectname . '" not found in output.'); + $plugin->nagios_die('performancedata: object name "' . $objectname . '" not found in output.'); } $plugin->add_message(OK, $params{'objecttype'} . "." . $objectname .":", $response->{$objectname}. ","); @@ -682,7 +682,7 @@ sub get_performancedata ); } } else { - $plugin->nagios_exit(UNKNOWN, 'performancedata: unable to parse data. Returned data is not a HASH or ARRAY!'); + $plugin->nagios_die('performancedata: unable to parse data. Returned data is not a HASH or ARRAY!'); } my ($code, $message) = $plugin->check_messages; From 5ddac46030d38881a2a563cfe107610911a275ce Mon Sep 17 00:00:00 2001 From: Ricardo Date: Fri, 11 Aug 2017 14:40:24 +0200 Subject: [PATCH 27/38] added ICA User session example to README --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index 07bf826..88668f1 100644 --- a/README.md +++ b/README.md @@ -145,6 +145,9 @@ If you want to connect to your NetScaler with SSL/HTTPS you should also install # NetScaler::Performancedata on network interfaces ./check_netscaler.pl -H ${IPADDR} -s -C performancedata -o Interface -n id.totrxbytes + # NetScaler::Current user sessions + ./check_netscaler.pl -H ${IPADDR} -s -C performancedata -o aaa -n aaacuricasessions,aaacuricaonlyconn + # find more object names to check out for object type "ns" /check_netscaler.pl -H ${IPADDR} -s -C debug -o ns From 49b50d515b026440bea6d0918298ad04909c54bb Mon Sep 17 00:00:00 2001 From: Ricardo Date: Fri, 11 Aug 2017 15:20:15 +0200 Subject: [PATCH 28/38] adding cli option -x (urlopts) Adding command line option -x / --urlopts to set NITRO URL options for further filtering in debug mode --- check_netscaler.pl | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/check_netscaler.pl b/check_netscaler.pl index 5bb8f6c..ce429f9 100755 --- a/check_netscaler.pl +++ b/check_netscaler.pl @@ -35,7 +35,7 @@ my $plugin = Nagios::Plugin->new( plugin => 'check_netscaler', shortname => 'NetScaler', - version => '1.1.1', + version => '1.2.X', url => 'https://github.com/slauger/check_netscaler', blurb => 'Nagios Plugin for Citrix NetScaler Appliance (VPX/MPX/SDX/CPX)', usage => 'Usage: %s -H [ -u ] [ -p ] @@ -122,6 +122,12 @@ desc => 'Value for critical', required => 0, }, + { + spec => 'urlopts|x=s', + usage => '-x, --urlopts=STRING', + desc => 'DEBUG ONLY: add additional url options', + required => 0, + }, ); foreach my $arg (@args) { @@ -864,7 +870,7 @@ sub check_debug $params{'endpoint'} = $plugin->opts->endpoint || 'stat'; $params{'objecttype'} = $plugin->opts->objecttype; $params{'objectname'} = $plugin->opts->objectname; - $params{'options'} = undef; + $params{'options'} = $plugin->opts->urlopts; my $response = nitro_client($plugin, \%params); From d5c7a3e3918f910f0388e968b826a874b32337dd Mon Sep 17 00:00:00 2001 From: Ricardo Date: Fri, 11 Aug 2017 15:54:38 +0200 Subject: [PATCH 29/38] added new commands to Icinga2 templates --- examples/icinga2_service_emplates.conf | 51 +++++++++++++++++++++++++- 1 file changed, 50 insertions(+), 1 deletion(-) diff --git a/examples/icinga2_service_emplates.conf b/examples/icinga2_service_emplates.conf index 9802ce8..c755847 100644 --- a/examples/icinga2_service_emplates.conf +++ b/examples/icinga2_service_emplates.conf @@ -67,7 +67,7 @@ template Service "netscaler_disk1_template" { vars.netscaler_command = "above" vars.netscaler_objecttype = "system" - vars.netscaler_objectname = "disk0perusage" + vars.netscaler_objectname = "disk1perusage" vars.warning = 75 vars.critical = 80 @@ -109,6 +109,25 @@ template Service "netscaler_config_status_template" { vars.netscaler_command = "nsconfig" } +// Netscaler info +template Service "netscaler_hwinfo_template" { + import "generic-service" + + check_command = "netscaler" + + vars.netscaler_command = "hwinfo" +} + +// Interfaces status +template Service "netscaler_interfaces_template" { + import "generic-service" + import "perf_enabled" + + check_command = "netscaler" + + vars.netscaler_command = "interfaces" +} + // Server Status template Service "netscaler_staserver_template" { import "generic-service" @@ -118,6 +137,14 @@ template Service "netscaler_staserver_template" { vars.netscaler_command = "staserver" } +template Service "netscaler_server_template" { + import "generic-service" + + check_command = "netscaler" + + vars.netscaler_command = "server" +} + template Service "netscaler_lbvserver_template" { import "generic-service" import "perf_enabled" @@ -137,3 +164,25 @@ template Service "netscaler_vpnvserver_template" { vars.netscaler_command = "state" vars.netscaler_objecttype = "vpnvserver" } + +// Servicegroup status +template Service "netscaler_servicegroup_template" { + import "generic-service" + import "perf_enabled" + + check_command = "netscaler" + + vars.netscaler_command = "servicegroup" +} + +// Performancedata +template Service "netscaler_performancedata_template" { + import "generic-service" + import "perf_enabled" + + check_command = "netscaler" + + vars.netscaler_command = "performancedata" +} + +// EOF From 66025c74010eae8ab2601b3f0e539c71078d6b5b Mon Sep 17 00:00:00 2001 From: Ricardo Date: Fri, 11 Aug 2017 16:04:25 +0200 Subject: [PATCH 30/38] Added Icinga2 service examples --- examples/icinga2_service_definitions.conf | 139 ++++++++++++++++++++++ 1 file changed, 139 insertions(+) create mode 100644 examples/icinga2_service_definitions.conf diff --git a/examples/icinga2_service_definitions.conf b/examples/icinga2_service_definitions.conf new file mode 100644 index 0000000..e6d63d5 --- /dev/null +++ b/examples/icinga2_service_definitions.conf @@ -0,0 +1,139 @@ +/******************************* + NetScaler Checks +*******************************/ +template Service "netscaler_env_details" { + + vars.netscaler_user = "icinga" + vars.netscaler_password = "super_secret" + vars.netscaler_ssl = true +} + +apply Service "CPU" { + import "netscaler_cpu_template" + import "netscaler_env_details" + + assign where host.vars.hw_type == "Netscaler" && host.vars.ns_env == "my_netscaler_env_a" +} + +apply Service "Mgmt CPU" { + import "netscaler_mgmtcpu_template" + import "netscaler_env_details" + + assign where host.vars.hw_type == "Netscaler" && host.vars.ns_env == "my_netscaler_env_a" +} + +apply Service "MEM" { + import "netscaler_mem_template" + import "netscaler_env_details" + + assign where host.vars.hw_type == "Netscaler" && host.vars.ns_env == "my_netscaler_env_a" +} + +apply Service "Disk 0" { + import "netscaler_disk0_template" + import "netscaler_env_details" + + assign where host.vars.hw_type == "Netscaler" && host.vars.ns_env == "my_netscaler_env_a" +} + +apply Service "Disk 1" { + import "netscaler_disk1_template" + import "netscaler_env_details" + + assign where host.vars.hw_type == "Netscaler" && host.vars.ns_env == "my_netscaler_env_a" +} + +apply Service "HA Status" { + import "netscaler_ha_status_template" + import "netscaler_env_details" + + assign where host.vars.hw_type == "Netscaler" && host.vars.ns_env == "my_netscaler_env_a" +} + +apply Service "HA State" { + import "netscaler_ha_state_template" + import "netscaler_env_details" + + assign where host.vars.hw_type == "Netscaler" && host.vars.ns_env == "my_netscaler_env_a" +} + +apply Service "Config Status" { + import "netscaler_config_status_template" + import "netscaler_env_details" + + assign where host.vars.hw_type == "Netscaler" && host.vars.ns_env == "my_netscaler_env_a" +} + +apply Service "HW Info" { + import "netscaler_hwinfo_template" + import "netscaler_env_details" + + assign where host.vars.hw_type == "Netscaler" && host.vars.ns_env == "my_netscaler_env_a" +} + +apply Service "Interfaces" { + import "netscaler_interfaces_template" + import "netscaler_env_details" + + assign where host.vars.hw_type == "Netscaler" && host.vars.ns_env == "my_netscaler_env_a" +} + +apply Service "Load Balanced server status" { + import "netscaler_server_template" + import "netscaler_env_details" + + assign where host.vars.hw_type == "Netscaler" && host.vars.ns_env == "my_netscaler_env_a" +} + +apply Service "STA Status " for (vpnverver in [ "my_vpnvserver" ] ) { + import "netscaler_staserver_template" + import "netscaler_env_details" + + vars.netscaler_objectname = vpnverver + assign where host.vars.hw_type == "Netscaler" && host.vars.ns_env == "my_netscaler_env_a" +} + +apply Service "VPNV Status " for (vpnverver in [ "my_vpnvserver_a" ] ) { + import "netscaler_vpnvserver_template" + import "netscaler_env_details" + + vars.netscaler_objectname = vpnverver + assign where host.vars.hw_type == "Netscaler" && host.vars.ns_env == "my_netscaler_env_a" +} + +apply Service "LB Status " for (lbvserver in [ "my_lbvserver_a", "my_lbvserver_b" ] ) { + import "netscaler_lbvserver_template" + import "netscaler_env_details" + + vars.netscaler_objectname = lbvserver + assign where host.vars.hw_type == "Netscaler" && host.vars.ns_env == "my_netscaler_env_a" +} + +apply Service "Servicegroup Status " for (servicegroup in [ "my_servicegroup_a", "my_servicegroup_b" ] ) { + import "netscaler_servicegroup_template" + import "netscaler_env_details" + + vars.netscaler_objectname = servicegroup + assign where host.vars.hw_type == "Netscaler" && host.vars.ns_env == "my_netscaler_env_a" +} + +// Perfdata +apply Service "Perf Ctirix Sessions" { + import "netscaler_performancedata_template" + import "netscaler_env_details" + + vars.netscaler_objecttype = "aaa" + vars.netscaler_objectname = "aaacuricasessions,aaacuricaonlyconn" + assign where host.vars.hw_type == "Netscaler" && host.vars.ns_env == "my_netscaler_env_a" +} + +apply Service "Perf TCP connections" { + import "netscaler_performancedata_template" + import "netscaler_env_details" + + vars.netscaler_objecttype = "ns" + vars.netscaler_objectname = "tcpcurclientconn,tcpcurclientconnestablished,tcpcurserverconn,tcpcurserverconnestablished" + assign where host.vars.hw_type == "Netscaler" && host.vars.ns_env == "my_netscaler_env_a" +} + +/* EOF */ From c6801d566f75de0de40d8a5179e1d5173482ac1b Mon Sep 17 00:00:00 2001 From: Ricardo Date: Fri, 11 Aug 2017 16:05:36 +0200 Subject: [PATCH 31/38] fixed typo in icinga2 templates file --- ...inga2_service_emplates.conf => icinga2_service_templates.conf} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename examples/{icinga2_service_emplates.conf => icinga2_service_templates.conf} (100%) diff --git a/examples/icinga2_service_emplates.conf b/examples/icinga2_service_templates.conf similarity index 100% rename from examples/icinga2_service_emplates.conf rename to examples/icinga2_service_templates.conf From de728edd395c6755d64bc143e880d2177e7df3f4 Mon Sep 17 00:00:00 2001 From: Simon Lauger Date: Sat, 12 Aug 2017 16:40:11 +0200 Subject: [PATCH 32/38] refactored the documentation --- README.md | 285 ++++++++++++++++++++++++++++++++---------------------- 1 file changed, 170 insertions(+), 115 deletions(-) diff --git a/README.md b/README.md index 88668f1..28be19a 100644 --- a/README.md +++ b/README.md @@ -4,176 +4,227 @@ A Nagios Plugin written for the Citrix NetScaler Application Delivery Controller Currently the plugin has the following subcommands: -- **state:** check the current service state of vservers (e.g. lb, vpn, gslb), services and service groups -- **string, string_not:** check if a string exists in the api response or not (e.g. HA or cluster status) -- **above, below:** check if a value is above/below a threshold (e.g. traffic limits, concurrent connections) -- **sslcert:** check the lifetime for installed ssl certificates -- **nsconfig:** check for configuration changes which are not saved to disk -- **staserver:** check if configured STA servers are available -- **server:** check status of Load Balancing Servers -- **servicegroup:** check the state of a servicegroup and its members -- **hwinfo:** just print information about the Netscaler itself -- **interfaces:** check state of all interfaces and add performance data for each interface -- **performancedata:** gather performancedata from all sorts of API endpoints -- **debug:** debug command, print all data for a endpoint + +| command | description | +--- | --- | +**state** | check the current service state of vservers (e.g. lb, vpn, gslb), services and service groups +**string, string_not** | check if a string exists in the api response or not (e.g. HA or cluster status) +**above, below** | check if a value is above/below a threshold (e.g. traffic limits, concurrent connections) +**sslcert** | check the lifetime for installed ssl certificates +**nsconfig** | check for configuration changes which are not saved to disk +**server** | check status of Load Balancing Servers +**staserver** | check if configured STA (secure ticket authority) servers are available +**servicegroup** | check the state of a servicegroup and its members +**hwinfo** | just print information about the Netscaler itself +**interfaces** | check state of all interfaces and add performance data for each interface +**performancedata** | gather performancedata from all sorts of API endpoints +**debug** | debug command, print all data for a endpoint This plugin works with VPX, MPX, SDX and CPX NetScaler Appliances. The api responses may differ by build, appliance type and your installed license. -The plugin supports performance data for the commands state and the above or below threshold checks. +The plugin supports performance data for the commands state and the above or below threshold checks. Also there is a performancedata command to gather information from your NetScaler. + +Example configurations for Nagios and Icinga 2 can be found in the exmaples directory of this repository. -Feedback and feature requests are appreciated. +Feedback and feature requests are appreciated. Just create an issue on GitHub or send me a pull request. -# Installation +## Installation On a Enterprise Linux machine (CentOS, RHEL) execute the following commands to install all Perl dependencies (Nagios::Plugin, LWP, JSON): - yum install perl-libwww-perl perl-JSON perl-Nagios-Plugin +``` +yum install perl-libwww-perl perl-JSON perl-Nagios-Plugin +``` If you want to connect to your NetScaler with SSL/HTTPS you should also install the LWP HTTPS package. - yum install perl-LWP-Protocol-https +``` +yum install perl-LWP-Protocol-https +``` -# Usage Examples +## Usage Examples -## Check status of vServers - # NetScaler::LBvServer - ./check_netscaler.pl -H ${IPADDR} -s -C state -o lbvserver +### Check status of vServers - # NetScaler::LBvServer::Website - ./check_netscaler.pl -H ${IPADDR} -s -C state -o lbvserver -n vs_lb_http_webserver +``` +# NetScaler::LBvServer +./check_netscaler.pl -H ${IPADDR} -s -C state -o lbvserver - # NetScaler::VPNvServer - ./check_netscaler.pl -H ${IPADDR} -s -C state -o vpnvserver +# NetScaler::LBvServer::Website +./check_netscaler.pl -H ${IPADDR} -s -C state -o lbvserver -n vs_lb_http_webserver - # NetScaler::GSLBvServer - ./check_netscaler.pl -H ${IPADDR} -s -C state -o gslbvserver +# NetScaler::VPNvServer +./check_netscaler.pl -H ${IPADDR} -s -C state -o vpnvserver - # NetScaler::AAAvServer - ./check_netscaler.pl -H ${IPADDR} -s -C state -o authenticationvserver +# NetScaler::GSLBvServer +./check_netscaler.pl -H ${IPADDR} -s -C state -o gslbvserver - # NetScaler::CSvServer - ./check_netscaler.pl -H ${IPADDR} -s -C state -o csvserver +# NetScaler::AAAvServer +./check_netscaler.pl -H ${IPADDR} -s -C state -o authenticationvserver - # NetScaler::SSLvServer (obsolet and replaced by lbvserver for newer builds) - ./check_netscaler.pl -H ${IPADDR} -s -C state -o sslvserver +# NetScaler::CSvServer +./check_netscaler.pl -H ${IPADDR} -s -C state -o csvserver -## Check status of services - # NetScaler::Services - ./check_netscaler.pl -H ${IPADDR} -s -C state -o service +# NetScaler::SSLvServer (obsolet and replaced by lbvserver for newer builds) +./check_netscaler.pl -H ${IPADDR} -s -C state -o sslvserver +``` - # NetScaler::Services::Webserver - ./check_netscaler.pl -H ${IPADDR} -s -C state -o service -n svc_webserver +### Check status of services -## Check status of servicegroups - # NetScaler::Servicegroups - ./check_netscaler.pl -H ${IPADDR} -s -C state -o servicegroup +``` +# NetScaler::Services +./check_netscaler.pl -H ${IPADDR} -s -C state -o service - # NetScaler::Servicegroups::Webservers - ./check_netscaler.pl -H ${IPADDR} -s -C state -o servicegroup -n sg_webservers +# NetScaler::Services::Webserver +./check_netscaler.pl -H ${IPADDR} -s -C state -o service -n svc_webserver +``` -## Check system health - # NetScaler::Memory - ./check_netscaler.pl -H ${IPADDR} -s -C above -o system -n memusagepcnt -w 75 -c 80 +### Check status of service groups - # NetScaler::CPU - ./check_netscaler.pl -H ${IPADDR} -s -C above -o system -n cpuusagepcnt -w 75 -c 80 +``` +# NetScaler::Servicegroups +./check_netscaler.pl -H ${IPADDR} -s -C state -o servicegroup - # NetScaler::CPUMGMT - ./check_netscaler.pl -H ${IPADDR} -s -C above -o system -n mgmtcpuusagepcnt -w 75 -c 80 +# NetScaler::Servicegroups::Webservers +./check_netscaler.pl -H ${IPADDR} -s -C state -o servicegroup -n sg_webservers +``` - # NetScaler::Disk0 - ./check_netscaler.pl -H ${IPADDR} -s -C above -o system -n disk0perusage -w 75 -c 80 +### Check status of a service group and quorum - # NetScaler::Disk1 - ./check_netscaler.pl -H ${IPADDR} -s -C above -o system -n disk1perusage -w 75 -c 80 +define member quorum (in percent) with warning and critical values -## Check high availability status - # NetScaler::HA::Status - ./check_netscaler.pl -H ${IPADDR} -s -C string_not -o hanode -n hacurstatus -w YES -c YES +``` +# NetScaler::Servicegroup::Webservers +./check_netscaler.pl -H ${IPADDR} -s -C servicegroup -n sg_webservers -w 75 -c 50 +``` - # NetScaler::HA::State - ./check_netscaler.pl -H ${IPADDR} -s -C string_not -o hanode -n hacurstate -w UP -c UP +### Check if Load Balancing servers are enabled -## Check expiration of installed ssl certificates - # NetScaler::Certs - ./check_netscaler.pl -H ${IPADDR} -s -C sslcert -w 30 -c 10 +``` +# NetScaler::Server +./check_netscaler.pl -H ${IPADDR} -s -C server - # NetScaler::Certs::Wildcard - ./check_netscaler.pl -H ${IPADDR} -s -C sslcert -n wildcard.example.com -w 30 -c 10 +# NetScaler::Server +./check_netscaler.pl -H ${IPADDR} -s -C server -n web01.example.com +``` -## Check for unsaved configuration changes - # NetScaler::Config - ./check_netscaler.pl -H ${IPADDR} -s -C nsconfig +### Check system health -## Check if STA servers are working +``` +# NetScaler::Memory +./check_netscaler.pl -H ${IPADDR} -s -C above -o system -n memusagepcnt -w 75 -c 80 - # NetScaler::STA - ./check_netscaler.pl -H ${IPADDR} -s -C staserver +# NetScaler::CPU +./check_netscaler.pl -H ${IPADDR} -s -C above -o system -n cpuusagepcnt -w 75 -c 80 - # NetScaler::STA::vs_vpn_gateway - ./check_netscaler.pl -H ${IPADDR} -s -C staserver -n vs_vpn_gateway +# NetScaler::CPUMGMT +./check_netscaler.pl -H ${IPADDR} -s -C above -o system -n mgmtcpuusagepcnt -w 75 -c 80 -## Check if Load Balancer server are working +# NetScaler::Disk0 +./check_netscaler.pl -H ${IPADDR} -s -C above -o system -n disk0perusage -w 75 -c 80 - # NetScaler::Server - ./check_netscaler.pl -H ${IPADDR} -s -C server +# NetScaler::Disk1 +./check_netscaler.pl -H ${IPADDR} -s -C above -o system -n disk1perusage -w 75 -c 80 +``` -## Check status of a service group -##### define member quorum (in percent) with warning and critical values - # NetScaler::Servicegroup::vs_vpn_gateway - ./check_netscaler.pl -H ${IPADDR} -s -C servicegroup -n vs_vpn_gateway -w 75 -c 50 +### Check high availability status -## Get information about the netscaler +``` +# NetScaler::HA::Status +./check_netscaler.pl -H ${IPADDR} -s -C string_not -o hanode -n hacurstatus -w YES -c YES - # NetScaler::HWInfo - ./check_netscaler.pl -H ${IPADDR} -s -C hwinfo +# NetScaler::HA::State +./check_netscaler.pl -H ${IPADDR} -s -C string_not -o hanode -n hacurstate -w UP -c UP +``` -## Check status of all network interfaces +### Check expiration of installed ssl certificates - # NetScaler::Interfaces - ./check_netscaler.pl -H ${IPADDR} -s -C interfaces +``` +# NetScaler::Certs +./check_netscaler.pl -H ${IPADDR} -s -C sslcert -w 30 -c 10 -## Request performance data -##### all fields must be defined via "-n" option and be seperated with a comma +# NetScaler::Certs::Wildcard +./check_netscaler.pl -H ${IPADDR} -s -C sslcert -n wildcard.example.com -w 30 -c 10 +``` - # NetScaler::Performancedata on Cache hit/misses - ./check_netscaler.pl -H ${IPADDR} -s -C performancedata -o ns -n cachetothits,cachetotmisses +### Check for unsaved configuration changes - # NetScaler::Performancedata on tcp connections - ./check_netscaler.pl -H ${IPADDR} -s -C performancedata -o ns -n tcpcurclientconn,tcpcurclientconnestablished,tcpcurserverconn,tcpcurserverconnestablished +``` +# NetScaler::Config +./check_netscaler.pl -H ${IPADDR} -s -C nsconfig +``` - # NetScaler::Performancedata on network interfaces - ./check_netscaler.pl -H ${IPADDR} -s -C performancedata -o Interface -n id.totrxbytes +### Check if STA servers are working - # NetScaler::Current user sessions - ./check_netscaler.pl -H ${IPADDR} -s -C performancedata -o aaa -n aaacuricasessions,aaacuricaonlyconn +``` +# NetScaler::STA +./check_netscaler.pl -H ${IPADDR} -s -C staserver - # find more object names to check out for object type "ns" - /check_netscaler.pl -H ${IPADDR} -s -C debug -o ns +# NetScaler::STA::vs_vpn_gateway +./check_netscaler.pl -H ${IPADDR} -s -C staserver -n vs_vpn_gateway +``` - # more interesting performance data object types - * ns - * cache - * protocolhttp - * protocolip - * protocoltcp +### Get information about the netscaler + +``` +# NetScaler::HWInfo +./check_netscaler.pl -H ${IPADDR} -s -C hwinfo +``` + +### Check status of all network interfaces + +``` +# NetScaler::Interfaces +./check_netscaler.pl -H ${IPADDR} -s -C interfaces +``` + +### Request performance data + +All fields must be defined via "-n" option and be seperated with a comma. + +``` +# NetScaler::Performancedata on Cache hit/misses +./check_netscaler.pl -H ${IPADDR} -s -C performancedata -o ns -n cachetothits,cachetotmisses + +# NetScaler::Performancedata on tcp connections +./check_netscaler.pl -H ${IPADDR} -s -C performancedata -o ns -n tcpcurclientconn,tcpcurclientconnestablished,tcpcurserverconn,tcpcurserverconnestablished + +# NetScaler::Performancedata on network interfaces +./check_netscaler.pl -H ${IPADDR} -s -C performancedata -o Interface -n id.totrxbytes + +# NetScaler::Current user sessions +./check_netscaler.pl -H ${IPADDR} -s -C performancedata -o aaa -n aaacuricasessions,aaacuricaonlyconn + +# find more object names to check out for object type "ns" +/check_netscaler.pl -H ${IPADDR} -s -C debug -o ns +``` + +For more interesting performance data object types see the following API methods. + +- ns +- cache +- protocolhttp +- protocolip +- protocoltcp ## Debug command - # Print all LB vServers (stat endpoint) - ./check_netscaler.pl -H ${IPADDR} -s -C debug -o lbvserver - # Print all LB vServers (config endpoint) - ./check_netscaler.pl -H ${IPADDR} -s -C debug -o lbvserver -e config +``` +# Print all LB vServers (stat endpoint) +./check_netscaler.pl -H ${IPADDR} -s -C debug -o lbvserver + +# Print all LB vServers (config endpoint) +./check_netscaler.pl -H ${IPADDR} -s -C debug -o lbvserver -e config +``` -# Configuration File -The plugin uses the Nagios::Plugin Libary, so you can use --extra-opts and seperate the login crendetials from your nagios configuration. +## Configuration File -e.g. +The plugin uses the Nagios::Plugin Libary, so you can use --extra-opts and seperate the login crendetials from your nagios configuration. ``` define command { command_name check_netscaler_vserver - command_line $USER5$/3rdparty/check_netscaler/check_netscaler.pl -H $HOSTADDRESS$ --extra-opts=netscaler@$USER11$/plugins.ini -C check_vserver -I '$ARG1$' + command_line $USER5$/3rdparty/check_netscaler/check_netscaler.pl -H $HOSTADDRESS$ -s --extra-opts=netscaler@$USER11$/plugins.ini -C state -n '$ARG1$' } ``` @@ -183,20 +234,24 @@ username=nagios password=password ``` -# Authors +## Authors - @slauger -# Contributors +## Contributors - @macampo - @Velociraptor85 - @bb-ricardo -# NITRO API Documentation +## NITRO API Documentation You will find a full documentation about the NITRO API on your NetScaler Appliance in the "Download" area. http://NSIP/nitro-rest.tgz (where NSIP is the IP address of your NetScaler appliance). -# Tested Firmware +## Tested Firmware Tested with NetScaler 10.5, 11.0, 11.1 and 12.0. The plugin should work with all available firmware builds. + +## Changelog + +See [CHANGELOG](CHANGELOG.md) \ No newline at end of file From 0290e0c4671c3d234b3f70999359f99683653499 Mon Sep 17 00:00:00 2001 From: Simon Lauger Date: Sat, 12 Aug 2017 17:28:38 +0200 Subject: [PATCH 33/38] changed description for service group check --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 28be19a..c9bef60 100644 --- a/README.md +++ b/README.md @@ -89,7 +89,7 @@ yum install perl-LWP-Protocol-https ./check_netscaler.pl -H ${IPADDR} -s -C state -o servicegroup -n sg_webservers ``` -### Check status of a service group and quorum +### Check status and quorum of a service group define member quorum (in percent) with warning and critical values From f497d77427efa0754e083b298365b0680ec87d05 Mon Sep 17 00:00:00 2001 From: Simon Lauger Date: Sat, 12 Aug 2017 17:48:55 +0200 Subject: [PATCH 34/38] added new commands to plugin_test.sh --- examples/plugin_test.sh | 63 +++++++++++++++++++++++++++++++---------- 1 file changed, 48 insertions(+), 15 deletions(-) diff --git a/examples/plugin_test.sh b/examples/plugin_test.sh index 7158efa..dafc3d3 100755 --- a/examples/plugin_test.sh +++ b/examples/plugin_test.sh @@ -40,47 +40,80 @@ else PORT="-P ${5}" fi -# NetScaler::SSLCerts +echo NetScaler::SSLCerts ./check_netscaler.pl -H ${IPADDR} ${PORT} ${SSL} -u ${USERNAME} -p ${PASSWORD} -C sslcert -w 30 -c 10 +echo -# NetScaler::NSConfig +echo NetScaler::NSConfig ./check_netscaler.pl -H ${IPADDR} ${PORT} ${SSL} -u ${USERNAME} -p ${PASSWORD} -C nsconfig +echo -# NetScaler::VPNvServer::State +echo NetScaler::HWInfo +./check_netscaler.pl -H ${IPADDR} ${PORT} ${SSL} -u ${USERNAME} -p ${PASSWORD} -C hwinfo +echo + +echo NetScaler::Interfaces +./check_netscaler.pl -H ${IPADDR} ${PORT} ${SSL} -u ${USERNAME} -p ${PASSWORD} -C interfaces +echo + +echo NetScaler::Perfdata::AAA +./check_netscaler.pl -H ${IPADDR} ${PORT} ${SSL} -u ${USERNAME} -p ${PASSWORD} -C performancedata -o aaa -n aaacuricasessions,aaacuricaonlyconn +echo + +echo NetScaler::VPNvServer::State ./check_netscaler.pl -H ${IPADDR} ${PORT} ${SSL} -u ${USERNAME} -p ${PASSWORD} -C state -o vpnvserver +echo -# NetScaler::LBvServer::State +echo NetScaler::LBvServer::State ./check_netscaler.pl -H ${IPADDR} ${PORT} ${SSL} -u ${USERNAME} -p ${PASSWORD} -C state -o lbvserver +echo -# NetScaler::GSLBvServer::State +echo NetScaler::GSLBvServer::State ./check_netscaler.pl -H ${IPADDR} ${PORT} ${SSL} -u ${USERNAME} -p ${PASSWORD} -C state -o gslbvserver +echo -# NetScaler:::AAAvServer::State +echo NetScaler:::AAAvServer::State ./check_netscaler.pl -H ${IPADDR} ${PORT} ${SSL} -u ${USERNAME} -p ${PASSWORD} -C state -o authenticationvserver +echo -# NetScaler:::CSvServer::State +echo NetScaler:::CSvServer::State ./check_netscaler.pl -H ${IPADDR} ${PORT} ${SSL} -u ${USERNAME} -p ${PASSWORD} -C state -o csvserver +echo -# NetScaler::SSLvServer::State +#echo NetScaler::SSLvServer::State #./check_netscaler.pl -H ${IPADDR} ${PORT} ${SSL} -u ${USERNAME} -p ${PASSWORD} -C state -o sslvserver +#echo -# NetScaler::System::Memory +echo NetScaler::Server +./check_netscaler.pl -H ${IPADDR} ${PORT} ${SSL} -u ${USERNAME} -p ${PASSWORD} -C server +echo + +echo NetScaler::System::Memory ./check_netscaler.pl -H ${IPADDR} ${PORT} ${SSL} -u ${USERNAME} -p ${PASSWORD} -C above -o system -n memusagepcnt -w 75 -c 80 +echo -# NetScaler::System::CPU +echo NetScaler::System::CPU ./check_netscaler.pl -H ${IPADDR} ${PORT} ${SSL} -u ${USERNAME} -p ${PASSWORD} -C above -o system -n cpuusagepcnt -w 75 -c 80 +echo -# NetScaler::System::CPU::MGMT +echo NetScaler::System::CPU::MGMT ./check_netscaler.pl -H ${IPADDR} ${PORT} ${SSL} -u ${USERNAME} -p ${PASSWORD} -C above -o system -n mgmtcpuusagepcnt -w 75 -c 80 +echo -# NetScaler::System::Disk0 +echo NetScaler::System::Disk0 ./check_netscaler.pl -H ${IPADDR} ${PORT} ${SSL} -u ${USERNAME} -p ${PASSWORD} -C above -o system -n disk0perusage -w 75 -c 80 +echo -# NetScaler::System::Disk1 +echo NetScaler::System::Disk1 ./check_netscaler.pl -H ${IPADDR} ${PORT} ${SSL} -u ${USERNAME} -p ${PASSWORD} -C above -o system -n disk1perusage -w 75 -c 80 +echo -# NetScaler::HA::Status +echo NetScaler::HA::Status ./check_netscaler.pl -H ${IPADDR} ${PORT} ${SSL} -u ${USERNAME} -p ${PASSWORD} -C string_not -o hanode -n hacurstatus -w YES -c YES +echo -# NetScaler::HA::State +echo NetScaler::HA::State ./check_netscaler.pl -H ${IPADDR} ${PORT} ${SSL} -u ${USERNAME} -p ${PASSWORD} -C string_not -o hanode -n hacurstate -w UP -c UP +echo + + From 168026cb26cf28b76b5c09b9467d340b04abf7eb Mon Sep 17 00:00:00 2001 From: Simon Lauger Date: Sat, 12 Aug 2017 17:51:07 +0200 Subject: [PATCH 35/38] prepare for v1.2.0, harmonize string quoting --- check_netscaler.pl | 124 ++++++++++++++++++++++----------------------- 1 file changed, 62 insertions(+), 62 deletions(-) diff --git a/check_netscaler.pl b/check_netscaler.pl index ce429f9..a78591f 100755 --- a/check_netscaler.pl +++ b/check_netscaler.pl @@ -6,7 +6,7 @@ # # https://github.com/slauger/check_netscaler # -# Version: 1.2.0 (2017-XX-XX) +# Version: 1.2.0 (2017-08-12) # # Copyright 2015-2017 Simon Lauger # @@ -35,8 +35,8 @@ my $plugin = Nagios::Plugin->new( plugin => 'check_netscaler', shortname => 'NetScaler', - version => '1.2.X', - url => 'https://github.com/slauger/check_netscaler', + version => '1.2.0', + url => 'https://github.com/slauger/check_netscaler', blurb => 'Nagios Plugin for Citrix NetScaler Appliance (VPX/MPX/SDX/CPX)', usage => 'Usage: %s -H [ -u ] [ -p ] -C [ -o ] [ -n ] [ -e ] @@ -147,10 +147,10 @@ check_threshold($plugin, $plugin->opts->command); } elsif ($plugin->opts->command eq 'string') { # check if a response does contains a specific string - check_string($plugin, "matches"); + check_string($plugin, 'matches'); } elsif ($plugin->opts->command eq 'string_not') { # check if a response does not contains a specific string - check_string($plugin, "matches not"); + check_string($plugin, 'matches not'); } elsif ($plugin->opts->command eq 'sslcert') { # check for the lifetime of installed certificates check_sslcert($plugin); @@ -258,7 +258,7 @@ sub nitro_client { } if ($plugin->opts->verbose) { - print "debug: target url is " . $url . "\n"; + print "debug: target url is $url\n"; } my $request = HTTP::Request->new(GET => $url); @@ -401,7 +401,7 @@ sub check_string $plugin->nagios_die('command requires parameter for warning and critical'); } - if ($type_of_string_comparison ne "matches" && $type_of_string_comparison ne "matches not") { + if ($type_of_string_comparison ne 'matches' && $type_of_string_comparison ne 'matches not') { $plugin->nagios_die('string can only be checked for "matches" and "matches not"'); } @@ -414,9 +414,9 @@ sub check_string my $response = nitro_client($plugin, \%params); $response = $response->{$plugin->opts->objecttype}; - if (($type_of_string_comparison eq "matches" && $response->{$plugin->opts->objectname} eq $plugin->opts->critical) || ($type_of_string_comparison eq "matches not" && $response->{$plugin->opts->objectname} ne $plugin->opts->critical)) { + if (($type_of_string_comparison eq 'matches' && $response->{$plugin->opts->objectname} eq $plugin->opts->critical) || ($type_of_string_comparison eq 'matches not' && $response->{$plugin->opts->objectname} ne $plugin->opts->critical)) { $plugin->nagios_exit(CRITICAL, $plugin->opts->objecttype . '::' . $plugin->opts->objectname . ' ' . $type_of_string_comparison . ' keyword (current: ' . $response->{$plugin->opts->objectname} . ', critical: ' . $plugin->opts->critical . ')'); - } elsif (($type_of_string_comparison eq "matches" && $response->{$plugin->opts->objectname} eq $plugin->opts->warning) || ($type_of_string_comparison eq "matches not" && $response->{$plugin->opts->objectname} ne $plugin->opts->warning)) { + } elsif (($type_of_string_comparison eq 'matches' && $response->{$plugin->opts->objectname} eq $plugin->opts->warning) || ($type_of_string_comparison eq 'matches not' && $response->{$plugin->opts->objectname} ne $plugin->opts->warning)) { $plugin->nagios_exit(WARNING, $plugin->opts->objecttype . '::' . $plugin->opts->objectname . ' ' . $type_of_string_comparison . ' keyword (current: ' . $response->{$plugin->opts->objectname} . ', warning: ' . $plugin->opts->warning . ')'); } else { $plugin->nagios_exit(OK, $plugin->opts->objecttype . '::' . $plugin->opts->objectname . ' OK ('.$response->{$plugin->opts->objectname}.')'); @@ -440,7 +440,7 @@ sub check_threshold $plugin->nagios_die('command requires parameter for warning and critical'); } - if ($direction ne "above" && $direction ne "below") { + if ($direction ne 'above' && $direction ne 'below') { $plugin->nagios_die('threshold can only be checked for "above" and "below"'); } @@ -463,9 +463,9 @@ sub check_threshold critical => $plugin->opts->critical, ); - if (($direction eq "above" && $response->{$plugin->opts->objectname} >= $plugin->opts->critical) || ($direction eq "below" && $response->{$plugin->opts->objectname} <= $plugin->opts->critical)) { + if (($direction eq 'above' && $response->{$plugin->opts->objectname} >= $plugin->opts->critical) || ($direction eq 'below' && $response->{$plugin->opts->objectname} <= $plugin->opts->critical)) { $plugin->nagios_exit(CRITICAL, $plugin->opts->objecttype . '::' . $plugin->opts->objectname . ' is ' . $direction . ' threshold (current: ' . $response->{$plugin->opts->objectname} . ', critical: ' . $plugin->opts->critical . ')'); - } elsif (($direction eq "above" && $response->{$plugin->opts->objectname} >= $plugin->opts->warning) || ($direction eq "below" && $response->{$plugin->opts->objectname} <= $plugin->opts->warning)) { + } elsif (($direction eq 'above' && $response->{$plugin->opts->objectname} >= $plugin->opts->warning) || ($direction eq 'below' && $response->{$plugin->opts->objectname} <= $plugin->opts->warning)) { $plugin->nagios_exit(WARNING, $plugin->opts->objecttype . '::' . $plugin->opts->objectname . ' is ' . $direction . ' threshold (current: ' . $response->{$plugin->opts->objectname} . ', warning: ' . $plugin->opts->warning . ')'); } else { $plugin->nagios_exit(OK, $plugin->opts->objecttype . '::' . $plugin->opts->objectname . ' OK ('.$response->{$plugin->opts->objectname}.')'); @@ -539,7 +539,7 @@ sub check_staserver my ($code, $message) = $plugin->check_messages; - if ( $critical == 1) { $code = CRITICAL ; } + if ( $critical == 1) { $code = CRITICAL; } $plugin->nagios_exit($code, 'server ' . $message); } @@ -552,15 +552,15 @@ sub check_server $params{'endpoint'} = $plugin->opts->endpoint || 'config'; $params{'objectname'} = $plugin->opts->objectname || ''; $params{'options'} = undef; - $params{'objecttype'} = "server"; + $params{'objecttype'} = 'server'; my $response = nitro_client($plugin, \%params); $response = $response->{$params{'objecttype'}}; - # return critical if all staservers are down at once + # return critical if all servers are disabled at once my $critical = 1; - # check if any stas are in down state + # check if any server is in disabled state foreach $response (@{$response}) { if ($response->{'state'} ne 'ENABLED') { $plugin->add_message(WARNING, $response->{'name'} . '('. $response->{'ipaddress'} .') ' . $response->{'state'} . ' ;'); @@ -572,7 +572,7 @@ sub check_server my ($code, $message) = $plugin->check_messages; - if ( $critical == 1) { $code = CRITICAL ; } + if ( $critical == 1) { $code = CRITICAL; } $plugin->nagios_exit($code, 'server ' . $message); } @@ -610,17 +610,17 @@ sub get_hardware_info my $response = nitro_client($plugin, \%params); $response = $response->{$params{'objecttype'}}; - $plugin->add_message(OK, "Platform: " . $response->{'hwdescription'} . ' ' . $response->{'sysid'} . ';'); - $plugin->add_message(OK, "Manufactured on: " . $response->{'manufactureyear'} . '/' . $response->{'manufacturemonth'} . '/' . $response->{'manufactureday'} . ';'); - $plugin->add_message(OK, "CPU: " . $response->{'cpufrequncy'} . 'MHz;'); - $plugin->add_message(OK, "Serial no: " . $response->{'serialno'} . ';'); + $plugin->add_message(OK, 'Platform: ' . $response->{'hwdescription'} . ' ' . $response->{'sysid'} . ';'); + $plugin->add_message(OK, 'Manufactured on: ' . $response->{'manufactureyear'} . '/' . $response->{'manufacturemonth'} . '/' . $response->{'manufactureday'} . ';'); + $plugin->add_message(OK, 'CPU: ' . $response->{'cpufrequncy'} . 'MHz;'); + $plugin->add_message(OK, 'Serial no: ' . $response->{'serialno'} . ';'); $params{'objecttype'} = 'nsversion'; $response = nitro_client($plugin, \%params); $response = $response->{$params{'objecttype'}}; - $plugin->add_message(OK, "Build Version: " . $response->{'version'} . ';'); + $plugin->add_message(OK, 'Build Version: ' . $response->{'version'} . ';'); my ($code, $message) = $plugin->check_messages; $plugin->nagios_exit($code, 'INFO: ' . $message); @@ -636,17 +636,17 @@ sub get_performancedata $params{'objectname'} = undef; $params{'options'} = undef; - if (not defined ($plugin->opts->objectname)) { - $plugin->nagios_die('performancedata: no object name(s) "-n" set'); + if (!defined $plugin->opts->objectname) { + $plugin->nagios_die('performancedata: command requires parameter for objectname'); } my $response = nitro_client($plugin, \%params); $response = $response->{$params{'objecttype'}}; - if ( ref $response eq "ARRAY" ) { + if ( ref $response eq 'ARRAY' ) { foreach $response (@{$response}) { - foreach my $objectname (split(",",$plugin->opts->objectname)) { - if (not index($objectname, ".") != -1) { + foreach my $objectname (split(',', $plugin->opts->objectname)) { + if (not index($objectname, '.') != -1) { $plugin->nagios_die('performancedata: return data is an array and contains multible objects. You need te seperate id and name with a ".".'); } @@ -659,10 +659,10 @@ sub get_performancedata $plugin->nagios_die('performancedata: object name "' . $objectname_name . '" not found in output.'); } - $plugin->add_message(OK, $params{'objecttype'} . "." . $response->{$objectname_id} . "." . $objectname_name . ":" . $response->{$objectname_name} . ","); + $plugin->add_message(OK, $params{'objecttype'} . '.' . $response->{$objectname_id} . '.' . $objectname_name . ":" . $response->{$objectname_name} . ","); $plugin->add_perfdata( - label => "'" . $params{'objecttype'} . "." . $response->{$objectname_id} . "." . $objectname_name . "'", + label => "'" . $params{'objecttype'} . '.' . $response->{$objectname_id} . '.' . $objectname_name . "'", value => $response->{$objectname_name}, min => undef, max => undef, @@ -671,15 +671,15 @@ sub get_performancedata ); } } - } elsif ( ref $response eq "HASH" ) { - foreach my $objectname (split(",",$plugin->opts->objectname)) { + } elsif ( ref $response eq 'HASH' ) { + foreach my $objectname (split(',', $plugin->opts->objectname)) { if (not defined($response->{$objectname})) { $plugin->nagios_die('performancedata: object name "' . $objectname . '" not found in output.'); } - $plugin->add_message(OK, $params{'objecttype'} . "." . $objectname .":", $response->{$objectname}. ","); + $plugin->add_message(OK, $params{'objecttype'} . '.' . $objectname . ':', $response->{$objectname}. ','); $plugin->add_perfdata( - label => "'" . $params{'objecttype'} . "." . $objectname . "'", + label => "'" . $params{'objecttype'} . '.' . $objectname . "'", value => $response->{$objectname}, min => undef, max => undef, @@ -712,45 +712,45 @@ sub check_interfaces my $interface_state = OK; - my $interface_speed = "N/A"; + my $interface_speed = 'N/A'; if ($interface->{'actspeed'}) { $interface_speed = $interface->{'actspeed'}; } if ($interface->{'linkstate'} != 1 ) { - push(@interface_errors, "interface " . $interface->{'devicename'} . " has linkstate \"DOWN\""); + push(@interface_errors, 'interface ' . $interface->{'devicename'} . " has linkstate \"DOWN\""); $interface_state = CRITICAL; } if ($interface->{'intfstate'} != 1 ) { - push(@interface_errors, "interface " . $interface->{'devicename'} . " has intstate \"DOWN\""); + push(@interface_errors, 'interface ' . $interface->{'devicename'} . " has intstate \"DOWN\""); $interface_state = CRITICAL; } - if ($interface->{'state'} ne "ENABLED" ) { - push(@interface_errors, "interface " . $interface->{'devicename'} . " has state \"".$interface->{'state'}."\""); + if ($interface->{'state'} ne 'ENABLED' ) { + push(@interface_errors, 'interface ' . $interface->{'devicename'} . " has state \"".$interface->{'state'}."\""); $interface_state = CRITICAL; } - $plugin->add_message($interface_state, "device: " . $interface->{'devicename'} . ' (speed: ' . $interface_speed . ', MTU: ' . $interface->{'actualmtu'} . ', VLAN: ' . $interface->{'vlan'} . ', type: ' . $interface->{'intftype'} . ') ' . $interface->{'state'} . ';'); + $plugin->add_message($interface_state, 'device: ' . $interface->{'devicename'} . ' (speed: ' . $interface_speed . ', MTU: ' . $interface->{'actualmtu'} . ', VLAN: ' . $interface->{'vlan'} . ', type: ' . $interface->{'intftype'} . ') ' . $interface->{'state'} . ';'); $plugin->add_perfdata( label => "\'".$interface->{'devicename'} . ".rxbytes'", - value => $interface->{'rxbytes'}."B" + value => $interface->{'rxbytes'}.'B' ); $plugin->add_perfdata( label => "\'".$interface->{'devicename'} . ".txbytes'", - value => $interface->{'txbytes'}."B" + value => $interface->{'txbytes'}.'B' ); $plugin->add_perfdata( label => "\'".$interface->{'devicename'} . ".rxerrors'", - value => $interface->{'rxerrors'}."c" + value => $interface->{'rxerrors'}.'c' ); $plugin->add_perfdata( label => "\'".$interface->{'devicename'} . ".txerrors'", - value => $interface->{'txerrors'}."c" + value => $interface->{'txerrors'}.'c' ); } my ($code, $message) = $plugin->check_messages; if (scalar @interface_errors != 0 ) { - $message = join(", ",@interface_errors). " - ". $message + $message = join(', ', @interface_errors). ' - '. $message } $plugin->nagios_exit($code, 'Interfaces: ' . $message); } @@ -761,8 +761,8 @@ sub check_servicegroup my @servicegroup_errors; # define quorum (in percent) of working servicegroup members - my $member_quorum_warning = $plugin->opts->warning || "90"; - my $member_quorum_critical = $plugin->opts->critical || "50"; + my $member_quorum_warning = $plugin->opts->warning || '90'; + my $member_quorum_critical = $plugin->opts->critical || '50'; my %member_state; @@ -777,14 +777,14 @@ sub check_servicegroup } my %healthy_servicegroup_states; - $healthy_servicegroup_states{"state"} = "ENABLED"; - $healthy_servicegroup_states{"servicegroupeffectivestate"} = "UP"; - $healthy_servicegroup_states{"monstate"} = "ENABLED"; - $healthy_servicegroup_states{"healthmonitor"} = "YES"; + $healthy_servicegroup_states{'state'} = 'ENABLED'; + $healthy_servicegroup_states{'servicegroupeffectivestate'} = 'UP'; + $healthy_servicegroup_states{'monstate'} = 'ENABLED'; + $healthy_servicegroup_states{'healthmonitor'} = 'YES'; my %healthy_servicegroup_member_states; - $healthy_servicegroup_member_states{"state"} = "ENABLED"; - $healthy_servicegroup_member_states{"svrstate"} = "UP"; + $healthy_servicegroup_member_states{'state'} = 'ENABLED'; + $healthy_servicegroup_member_states{'svrstate'} = 'UP'; my $response = nitro_client($plugin, \%params); my $servicegroup_response = $response->{$params{'objecttype'}}; @@ -796,7 +796,7 @@ sub check_servicegroup foreach my $servicegroup_check_key ( keys %healthy_servicegroup_states ) { if ($servicegroup_response->{$servicegroup_check_key} ne $healthy_servicegroup_states{$servicegroup_check_key}) { - push(@servicegroup_errors, 'servicegroup ' . $servicegroup_response->{"servicegroupname"} . ' "'. $servicegroup_check_key . '" is: '. $healthy_servicegroup_states{$servicegroup_check_key}); + push(@servicegroup_errors, 'servicegroup ' . $servicegroup_response->{'servicegroupname'} . ' "'. $servicegroup_check_key . '" is: '. $healthy_servicegroup_states{$servicegroup_check_key}); } } $plugin->add_message(OK, $servicegroup_response->{'servicegroupname'} . ' (' . $servicegroup_response->{'servicetype'} . ') - state: ' . $servicegroup_response->{'servicegroupeffectivestate'} . ' -'); @@ -814,12 +814,12 @@ sub check_servicegroup foreach my $servicegroup_members_check_key ( keys %healthy_servicegroup_member_states ) { if ($servicegroup_members_response->{$servicegroup_members_check_key} ne $healthy_servicegroup_member_states{$servicegroup_members_check_key}) { - push(@servicegroup_errors, 'servicegroup member ' . $servicegroup_members_response->{"servername"} . ' "'. $servicegroup_members_check_key . '" is '. $healthy_servicegroup_member_states{$servicegroup_members_check_key}); - $member_state{$servicegroup_members_response->{"servername"}} = "DOWN"; + push(@servicegroup_errors, 'servicegroup member ' . $servicegroup_members_response->{'servername'} . ' "'. $servicegroup_members_check_key . '" is '. $healthy_servicegroup_member_states{$servicegroup_members_check_key}); + $member_state{$servicegroup_members_response->{'servername'}} = 'DOWN'; } } - if (not defined $member_state{$servicegroup_members_response->{"servername"}}) { - $member_state{$servicegroup_members_response->{"servername"}} = "UP"; + if (not defined $member_state{$servicegroup_members_response->{'servername'}}) { + $member_state{$servicegroup_members_response->{'servername'}} = "UP"; } $plugin->add_message(OK, $servicegroup_members_response->{'servername'} . ' (' . $servicegroup_members_response->{'ip'}.':'. $servicegroup_members_response->{'port'} . ') is ' . $servicegroup_members_response->{'svrstate'} .','); } @@ -828,7 +828,7 @@ sub check_servicegroup my $members_up = 0; my $members_down = 0; foreach my $member_state_key ( keys %member_state ) { - if ($member_state{$member_state_key} eq "DOWN") { + if ($member_state{$member_state_key} eq 'DOWN') { $members_down++; } else { $members_up++; @@ -836,7 +836,7 @@ sub check_servicegroup } # check quorum - my $member_quorum = sprintf("%1.2f", 100 / ( $members_up + $members_down ) * $members_up); + my $member_quorum = sprintf('%1.2f', 100 / ( $members_up + $members_down ) * $members_up); if ($member_quorum <= $member_quorum_critical) { $servicegroup_state = CRITICAL; @@ -844,11 +844,11 @@ sub check_servicegroup $servicegroup_state = WARNING; } - $plugin->add_message(OK, "member quorum: " . $member_quorum . "% (UP/DOWN): " . $members_up . "/" . $members_down); + $plugin->add_message(OK, 'member quorum: ' . $member_quorum . '% (UP/DOWN): ' . $members_up . '/' . $members_down); $plugin->add_perfdata( label => "'" . $plugin->opts->objectname . ".member_quorum'", - value => $member_quorum."%", + value => $member_quorum.'%', min => 0, max => 100, warning => $member_quorum_warning, @@ -857,7 +857,7 @@ sub check_servicegroup my ($code, $message) = $plugin->check_messages; if (scalar @servicegroup_errors != 0 ) { - $message = join(", ",@servicegroup_errors). " - ". $message + $message = join(', ', @servicegroup_errors). ' - '. $message } $plugin->nagios_exit($servicegroup_state, 'servicegroup: ' . $message); } From b02e56085bc827d5c79e9010366eca7ffe64aedb Mon Sep 17 00:00:00 2001 From: Simon Lauger Date: Sat, 12 Aug 2017 17:51:56 +0200 Subject: [PATCH 36/38] release v1.2.0 --- CHANGELOG.md | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5473a43..ac18469 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,10 +1,12 @@ -## 1.2.0 (2017-XX-XX) -- added command server to check status of Load Balancing Servers -- added command hwinfo to just print information about the Netscaler itself -- added command interfaces to check state of all interfaces and add performance data for each interface -- added command to request performance data -- added command to check the state of a servicegroup and its members (set warning and critical values for member quorum) -- added Icinga2 config templates +## 1.2.0 (2017-08-12) +- merged pull request from @bb-Ricardo + - added command server to check status of Load Balancing Servers + - added command hwinfo to just print information about the Netscaler itself + - added command interfaces to check state of all interfaces and add performance data for each interface + - added command to request performance data + - added command to check the state of a servicegroup and its members (set warning and critical values for member quorum) + - added Icinga2 config templates +- updated documentation and plugin_test.sh ## 1.1.1 (2017-06-10) - bugfix for servicegroups in 12.0 (#12) @@ -22,16 +24,16 @@ - improved check for ssl certificates to only check for a specific certificate - fixed a bug in check_state to support services and servicegroups again -## 0.2.0 +## 0.2.0 2017-01-04 - patch for Nitro.pm to support ssl connections - added check to test the validity and expiry of installed certificates -## 0.1.2 +## 0.1.2 2016-12-02 - added performance data feature - updated sub add_arg and added default values for parameters - Bugfix in vserver checks loop by @macampo -## 0.1.1 +## 0.1.1 2016-11-10 - documentation fixes by @Velociraptor85 ## 0.1.0 (2015-12-17) From 1ebde0756ba372ee1e08d9f8f0fb43fb7693b3c9 Mon Sep 17 00:00:00 2001 From: Simon Lauger Date: Sat, 12 Aug 2017 17:56:11 +0200 Subject: [PATCH 37/38] fixed typo (exmaples) --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index c9bef60..c0e3dc3 100644 --- a/README.md +++ b/README.md @@ -24,7 +24,7 @@ This plugin works with VPX, MPX, SDX and CPX NetScaler Appliances. The api respo The plugin supports performance data for the commands state and the above or below threshold checks. Also there is a performancedata command to gather information from your NetScaler. -Example configurations for Nagios and Icinga 2 can be found in the exmaples directory of this repository. +Example configurations for Nagios and Icinga 2 can be found in the examples directory of this repository. Feedback and feature requests are appreciated. Just create an issue on GitHub or send me a pull request. @@ -254,4 +254,4 @@ Tested with NetScaler 10.5, 11.0, 11.1 and 12.0. The plugin should work with all ## Changelog -See [CHANGELOG](CHANGELOG.md) \ No newline at end of file +See [CHANGELOG](CHANGELOG.md) From 0b5c317b2eb087fdacd309ed7fad92037ac4cb3a Mon Sep 17 00:00:00 2001 From: Simon Lauger Date: Sat, 12 Aug 2017 18:01:22 +0200 Subject: [PATCH 38/38] =?UTF-8?q?added=20links=20to=20contributors=20in=20?= =?UTF-8?q?Markdown=20syntax=20(GitHub=20does=20not=20recognize=20the=20sy?= =?UTF-8?q?ntax=20with=20=E2=80=98@user')?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index c0e3dc3..3e877cb 100644 --- a/README.md +++ b/README.md @@ -235,12 +235,12 @@ password=password ``` ## Authors -- @slauger +- [slauger](https://github.com/slauger) ## Contributors -- @macampo -- @Velociraptor85 -- @bb-ricardo +- [macampo](https://github.com/macampo) +- [Velociraptor85](https://github.com/Velociraptor85) +- [bb-ricardo](https://github.com/bb-ricardo) ## NITRO API Documentation