check_rmx2000_ports
On this page you will find the current version of the Polycom RMX 2000 port usage check script. Furthermore you will find some PNP template and a small description of the script parameters.
Idea
The RMX2000 bridge capacities are defined by the number of ports. You can assign these ports to audio- and video-processing. There is a small graph on the administration web interface of that bridge to see the current usage of these ports but there is no historical view for the port usage.
This check script for Nagios gives you the ability to gather the port usage via Nagios and track the port usage via graphing tools for Nagios like PNP or NETWAYS Grapher.Prerequisites
You will need the following perl modules to get the plugin running:
- Getopt::Long
- LWP::UserAgent
- HTTP::Request::Common
- XML::Simple
- Sys::Hostname
- Data::Dumper (Only for debugging)
check_rmx2000_ports
Copy the file to your nagios/libexec directory, fix owner and make it executable.
#!/usr/bin/perl -w # ############################################################################## # 2009-02-03 Lars Michelsen <lars@vertical-visions.de> # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, # # GNU General Public License: http://www.gnu.org/licenses/gpl-2.0.txt # # ############################################################################## # SCRIPT: check_rmx2000_ports.pl # VERSION: 1.0 # AUTHOR: Lars Michelsen # DECRIPTION: Checks the XML API of RMX2000 (And maybe other polycom bridges # like MGC) for the CIF port usage. # ############################################################################## use strict; use Getopt::Long; use LWP::UserAgent; use HTTP::Request::Common qw(GET POST); use XML::Simple; use Data::Dumper; use Sys::Hostname; Getopt::Long::Configure('bundling'); my ($oHelp, $oHost, $oUser, $oPw, $oAddress, $oPort, $oWarn, $oCrit); my @warn = (-1,-1); my @crit = (-1,-1); my $state = 'OK'; my $output = ''; my $perfdata = ''; my $userAgent; my $token; my $uToken; my $bridgeIp = ''; my $bridgeUser = ''; my $bridgePw = ''; my $hostName = hostname; my $bridgePort = '80'; my $bridgeUrl = ''; # Exit-Status-Array my %ERRORS = ('UNKNOWN' , '-1', 'OK' , '0', 'WARNING', '1', 'CRITICAL', '2'); # Parameter handling ########################################################### GetOptions("H|host:s" => \$oHost, "U|user:s" => \$oUser, "P|pw:s" => \$oPw, "A|address:s" => \$oAddress, "w|warn:s" => \$oWarn, "c|crit:s" => \$oCrit, "p|port:i" => \$oPort, "h|help" => \$oHelp); if($oHelp || !$oUser || !$oHost || !$oPw || !$oAddress) { print <<EOU; Usage: $0 -H <FQDN/IP: string> -A <URL/Address: string> -U <Username: string> -P <Passwort: string> [-p <Port: integer>] [-w <audio ports warn: integer>,<video ports warn: integer>] [-c <audio ports warn: integer>,<video ports warn: integer>] Options: -H --host STRING or IPADDRESS FQDN or IP-Address of the bridge -A --address STRING Address to the XML API (e.g. http://<hostname>/Receiver.asp) -U --user STRING User name on the bridge -P --pw STRING Password of the account on the bridge -p --port INTEGER TCP port the API listens on the bridge -w --warn INTEGER Warning tresholds. Give maximum number of audio/video ports to be occupied before warning state occurs. Example: A value of 50,25 would warn on 51 occupied audio- and/or 26 occupied video ports. -c --crit INTEGER Critical tresholds. Give maximum number of audio/video ports to be occupied before critical state occurs. Example: A value of 60,30 would warn on 61 occupied audio- and/or 31 occupied video ports. EOU exit($ERRORS{'UNKNOWN'}); } $bridgeIp = $oHost; $bridgeUrl = $oAddress; $bridgeUser = $oUser; $bridgePw = $oPw; if($oPort) { $bridgePort = $oPort; } if($oWarn) { @warn = split(',', $oWarn); } if($oCrit) { @crit = split(',', $oCrit); } # Script start ################################################################# connect_bridge() if !$userAgent; my $request = '<TRANS_RSRC_REPORT><TRANS_COMMON_PARAMS><MCU_TOKEN>'.$token.'</MCU_TOKEN>'. '<MCU_USER_TOKEN>'.$uToken.'</MCU_USER_TOKEN><MESSAGE_ID>0</MESSAGE_ID>'. '</TRANS_COMMON_PARAMS><ACTION><GET_CARMEL_REPORT/></ACTION></TRANS_RSRC_REPORT>'; my $responseXml = http_post($bridgeUrl, $request); my $oXml = XMLin($responseXml); # DEBUG: print Dumper($oXml); my $audioPorts; my $videoPorts; foreach my $report (@{$oXml->{'ACTION'}->{'GET_CARMEL_REPORT'}->{'RSRC_REPORT_RMX_LIST'}->{'RSRC_REPORT_RMX'}}) { if($report->{'RSRC_REPORT_ITEM'} eq 'audio') { # Possible options: #$report->{'RSRC_REPORT_ITEM'}->{'RESERVED'} #$report->{'RSRC_REPORT_ITEM'}->{'OCCUPIED'} #$report->{'RSRC_REPORT_ITEM'}->{'TOTAL'} #$report->{'RSRC_REPORT_ITEM'}->{'FREE'} $audioPorts = $report; } elsif($report->{'RSRC_REPORT_ITEM'} eq 'video') { $videoPorts = $report; } } # Audio tresholds if($warn[0] != -1 && $audioPorts->{'OCCUPIED'} > $warn[0]) { $state = 'WARNING'; } if($crit[0] != -1 && $videoPorts->{'OCCUPIED'} > $crit[0]) { $state = 'CRITICAL'; } # Video tresholds if($warn[1] != -1 && $videoPorts->{'OCCUPIED'} > $warn[1]) { $state = 'WARNING'; } if($crit[1] != -1 && $videoPorts->{'OCCUPIED'} > $crit[1]) { $state = 'CRITICAL'; } $output = $state.': Audio occupied: '.$audioPorts->{'OCCUPIED'}.'/'.$audioPorts->{'TOTAL'}. ' Video occupied: '.$videoPorts->{'OCCUPIED'}.'/'.$videoPorts->{'TOTAL'}; $perfdata = 'audio='.$audioPorts->{'OCCUPIED'}.';'.$warn[0].';'.$crit[0].';0;'.$audioPorts->{'TOTAL'}. ' video='.$videoPorts->{'OCCUPIED'}.';'.$warn[1].';'.$crit[1].';0;'.$videoPorts->{'TOTAL'}; print($output.' | '.$perfdata."\n"); exit($ERRORS{$state}); # Subs ######################################################################### sub login_bridge { my $request = '<TRANS_MCU><TRANS_COMMON_PARAMS><MCU_TOKEN>-1</MCU_TOKEN>'. '<MCU_USER_TOKEN>-1</MCU_USER_TOKEN></TRANS_COMMON_PARAMS><ACTION><LOGIN>'. '<MCU_IP><IP>'.$bridgeIp.'</IP>'. '<LISTEN_PORT>'.$bridgePort.'</LISTEN_PORT>'. '</MCU_IP><USER_NAME>'.$bridgeUser.'</USER_NAME>'. '<PASSWORD>'.$bridgePw.'</PASSWORD>'. '<STATION_NAME>'.$hostName.'</STATION_NAME>'. '</LOGIN></ACTION></TRANS_MCU>'; my $responseXml = http_post($bridgeUrl, $request); my $xml = XMLin($responseXml); # DEBUG: print Dumper($xml); my $token = 0; my $uToken = 0; if($xml->{'RETURN_STATUS'}->{'ID'} == 0) { $token = $xml->{'ACTION'}->{'LOGIN'}->{'MCU_TOKEN'}; $uToken = $xml->{'ACTION'}->{'LOGIN'}->{'MCU_USER_TOKEN'}; } return ($token, $uToken); } sub connect_bridge { $userAgent = LWP::UserAgent->new(agent => 'VCMgmtLib', keep_alive => 1); ($token, $uToken) = login_bridge(); if($token == 0 || $uToken == 0) { # Login failed print("UNKNOWN: Login failed!\n"); exit($ERRORS{'UNKNOWN'}); } } sub http_post { my ($url, $content) = @_; my $req = POST $bridgeUrl, Content_Type => 'application/x-www-form-urlencoded', Content => $content; my $response = $userAgent->request($req); print $response->error_as_HTML unless $response->is_success; return $response->content; } # End of script ################################################################ |
PNP-Template
<?php $multigraph_name[1] = "Occupied ports"; $opt[1] = "--vertical-label \"Occupied ports\" --title \"Occupied Ports: $hostname ($servicedesc)\" "; # # # $def[1] = "DEF:var1=$rrdfile:$DS[1]:AVERAGE " ; $def[1] .= "DEF:var2=$rrdfile:$DS[2]:AVERAGE " ; $def[1] .= "CDEF:var2draw=var2,-1,* "; $def[1] .= "HRULE:$CRIT[1]#FF0000 "; $def[1] .= "AREA:var1#9CCFFF:\"$NAME[1] \" " ; $def[1] .= "LINE1:var1#10A2FF " ; $def[1] .= "AREA:var2draw#FFCF9C:\"$NAME[2] \\n\" " ; $def[1] .= "LINE1:var2draw#FFA26B " ; $def[1] .= "COMMENT:\" current average maximum\" " ; $def[1] .= "COMMENT:\"\\n\" " ; $def[1] .= "COMMENT:\"audio \" " ; $def[1] .= "GPRINT:var1:LAST:\"%7.0lf \" " ; $def[1] .= "GPRINT:var1:AVERAGE:\"%7.0lf \" " ; $def[1] .= "GPRINT:var1:MAX:'%7.0lf' " ; $def[1] .= "COMMENT:\"\\n\" " ; $def[1] .= "COMMENT:\"video \" " ; $def[1] .= "GPRINT:var2:LAST:\"%7.0lf \" " ; $def[1] .= "GPRINT:var2:AVERAGE:\"%7.0lf \" " ; $def[1] .= "GPRINT:var2:MAX:\"%7.0lf\" " ; $def[1] .= "COMMENT:\" ".date("d.m.Y H:i:s")."\\n\" " ; ?> |
Just drop the template in the pnp/share/templates directory and name it like your check command.
Parameters
Usage: ./check_rmx2000_ports.pl -H <FQDN/IP: string> -A <URL/Address: string> -U <Username: string> -P <Passwort: string> [-p <Port: integer>] [-w <audio ports warn: integer>,<video ports warn: integer>] [-c <audio ports warn: integer>,<video ports warn: integer>] Options: -H --host STRING or IPADDRESS FQDN or IP-Address of the bridge -A --address STRING Address to the XML API (e.g. http://<hostname>/Receiver.asp) -U --user STRING User name on the bridge -P --pw STRING Password of the account on the bridge -p --port INTEGER TCP port the API listens on the bridge -w --warn INTEGER Warning tresholds. Give maximum number of audio/video ports to be occupied before warning state occurs. Example: A value of 50,25 would warn on 51 occupied audio- and/or 26 occupied video ports. -c --crit INTEGER Critical tresholds. Give maximum number of audio/video ports to be occupied before critical state occurs. Example: A value of 60,30 would warn on 61 occupied audio- and/or 31 occupied video ports. |
Sample configuration
Here some sample command and service definition for Nagios configuration.
define command { command_name check_rmx2000_ports command_line $USER1$/check_rmx2000_ports.pl -H $HOSTADDRESS$ -A $ARG1$ -U $ARG2$ -P $ARG3$ -w $ARG4$ -c $ARG5$ } define service { host_name rmx2000 service_description OCCUPIED-PORTS check_command check_rmx2000_ports!http://rmx2000/Receiver.asp!script-read!aLAn7gjMa29naHAy!30,15!45,18 use service-standard } |







01:11 on September 29th, 2010
Thanks for script. Works great!
15:51 on October 7th, 2010
Will this work with a RMX 1000 unit?
16:12 on October 7th, 2010
I didn’t try but I think it should work with the RMX1000. Just give it a try…