ITPub博客

首页 > 应用开发 > IT综合 > Nagios 监控ESXI脚本

Nagios 监控ESXI脚本

原创 IT综合 作者:Michael_DD 时间:2016-01-22 16:25:28 0 删除 编辑
Nagios 监控ESXI脚本


1. 监控脚本下载。
https://exchange.nagios.org/directory/Plugins/Operating-Systems/%2A-Virtual-Environments/VMWare/Vmware-ESX-%26-VM-host/details

2. 监控展示
check_esx -H 10.8.3.115 -u xxx -p xxx -l cpu 
CHECK_ESX OK - cpu usage=1169.82 MHz (4.99%) | cpu_usagemhz=1169.82Mhz;; cpu_usage=4.99%;; 

#check_esx -H 10.8.3.115 -u xxx -p xxx -l cpu -s usage -w 80 -c 90 -t 60 
CHECK_ESX OK - cpu usage=3.56 % | cpu_usage=3.56%;80;90 

#check_esx -H 10.8.3.115 -u xxx -p xxx -l vmfs 
CHECK_ESX OK - storages : Storage1=2287.00 MB (3.36%), Storage3=35440.00 MB (3.72%), Storage2=40352.00 MB (14.49%) | Storage1=2287.00MB;; Storage3=35440.00MB;; Storage2=40352.00MB;; 

#check_esx -H 10.8.3.115 -u xxx -p xxx -l net 
CHECK_ESX OK - net receive=4.40 KBps, send=0.30 KBps, all 1 NICs are connected | net_receive=4.40KBps;; net_send=0.30KBps;; OK_NICs=1;; Bad_NICs=0;; 

#check_esx -H 10.8.3.115 -u xxx -p xxx -l io 
CHECK_ESX OK - io commands aborted=0, io bus resets=0, io read latency=0 ms, write latency=0 ms, kernel latency=0 ms, device latency=0 ms, queue latency=0 ms | io_aborted=0;; io_busresets=0;; io_read=0ms;; io_write=0ms;; io_kernel=0ms;; io_device=0ms;; io_queue=0ms;; 

#check_esx -H 10.8.3.115 -u xxx -p xxx -l runtime 
CHECK_ESX OK - 3/4 VMs up, overall status=green, connection state=connected, maintenance=no, All 175 health checks are Green, no config issues | vmcount=3units;; 

#check_esx -H 10.8.3.115 -u xxx -p xxx -l service 
CHECK_ESX OK - services : ntpd (down), sshd (up), vmware-vpxa (up), vmware-webAccess (up) 


脚本可以到官网下载,文本末尾也有下载链接。

官网网页上已有很多安装办法。主要报错的点也列出来了。

记录一下我自己的问题。
[root@sznagiosapp8 libexec]# ./check_esx -H 172.25.133.52 -u esxmon -p Sinolife2014  -l cpu
CHECK_ESX CRITICAL - Undefined subroutine &HTTP::Headers::redirects called at (eval 51) line 1


一直报这个垃圾错误。问题主要缺包HTTP-Message-6.11.tar.gz


其他缺包报错,需要安装的包
[root@sznagiosapp8 SNMP]# ll
total 142104
drwxr-xr-x   8 nagios   nagios      4096 Jan 21 16:00 Config-IniFiles-2.88
-rw-r--r--   1 root     root       80137 Jan 21 15:57 Config-IniFiles-2.88.tar_.gz
-rw-------   1 root     root       80137 Jan 21 15:39 Config-IniFiles-2.88.tar.gz
drwxr-xr-x   3     1000   1000      4096 Jan 21 15:25 Crypt-DES-2.07
-rw-r--r--.  1 root     root       16720 Jan  6 09:22 Crypt-DES-2.07.tar.gz
drwxr-xr-x   5 centreon games       4096 Jan 21 15:27 Digest-HMAC-1.03
-rw-r--r--.  1 root     root        7251 Jan  6 09:22 Digest-HMAC-1.03.tar.gz
drwxr-xr-x   5 centreon games       4096 Jan 21 15:28 Digest-MD5-2.54
-rw-r--r--.  1 root     root       48699 Jan  6 09:22 Digest-MD5-2.54.tar.gz
drwxr-xr-x   5 centreon games       4096 Jan 21 15:28 Digest-SHA1-2.13
-rw-r--r--.  1 root     root       39078 Jan  6 09:22 Digest-SHA1-2.13.tar.gz
-rw-r--r--   1 root     root       35147 Jan 21 17:12 gpl.txt
-rw-r--r--   1 root     root       59981 Jan 22 16:08 HTTP-Message-6.11.tar.gz
-rw-r--r--   1 root     root        2943 Jan 21 16:26 Nagios-Plugin-0.990001.tar.gz
drwxr-xr-x   5      502 games       4096 Jan 22 16:03 Net-HTTP-6.09
-rw-r--r--   1 root     root       17686 Jan 22 14:26 Net-HTTP-6.09.tar.gz
drwxr-xr-x   6     1000   1000      4096 Jan 21 15:26 Net-SNMP-v6.0.1
-rw-r--r--.  1 root     root       94664 Jan  6 09:22 Net-SNMP-v6.0.1.tar.gz
drwxr-sr-x   5     1000   1000      4096 Jan 21 15:59 Scalar-List-Utils-1.42
-rw-r--r--   1 root     root       82574 Jan 21 15:57 Scalar-List-Utils-1.42.tar.gz
drwxr-xr-x  12 root     root        4096 Jan 21 17:22 vmware-vsphere-cli-distrib
-rw-r--r--   1 root     root   144885760 Jan 21 16:16 VMware-vSphere-Perl-SDK-5.5.0-1292267.x86_64.tar

包下载地址:
https://metacpan.org/pod/HTTP::Headers

per脚本:

点击(此处)折叠或打开

  1. #!/usr/bin/perl -w
  2. #
  3. # Nagios plugin to monitor vmware esx servers
  4. #
  5. # License: GPL
  6. # Copyright (c) 2008 op5 AB
  7. # Author: Kostyantyn Hushchyn <dev@op5.com>
  8. # Contributor(s): Patrick Müller, Jeremy Martin, Eric Jonsson, stumpr, John Cavanaugh, Libor Klepac, maikmayers, Steffen Poulsen, Mark Elliott
  9. #
  10. # For direct contact with any of the op5 developers send a mail to
  11. # dev@op5.com
  12. # Discussions are directed to the mailing list op5-users@op5.com,
  13. # see http://lists.op5.com/mailman/listinfo/op5-users
  14. #
  15. # This program is free software; you can redistribute it and/or modify
  16. # it under the terms of the GNU General Public License version 2 as
  17. # published by the Free Software Foundation.
  18. #
  19. # This program is distributed in the hope that it will be useful,
  20. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  21. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  22. # GNU General Public License for more details.
  23. #
  24. # You should have received a copy of the GNU General Public License
  25. # along with this program. If not, see <http://www.gnu.org/licenses/>.
  26. #

  27. use strict;
  28. use warnings;
  29. use vars qw($PROGNAME $VERSION $output $values $result);
  30. use Nagios::Plugin;
  31. use File::Basename;
  32. my $perl_module_instructions="
  33. Download the latest version of Perl Toolkit from VMware support page.
  34. In this example we use VMware-vSphere-SDK-for-Perl-4.0.0-161974.x86_64.tar.gz,
  35. but the instructions should apply to newer versions as well.
  36.   
  37. Upload the file to your op5 Monitor server's /root dir and execute:

  38.     cd /root
  39.     tar xvzf VMware-vSphere-SDK-for-Perl-4.0.0-161974.x86_64.tar.gz
  40.     cd vmware-vsphere-cli-distrib/
  41.     ./vmware-install.pl
  42.   
  43. Follow the on screen instructions, described below:

  44.   \"Creating a new vSphere CLI installer database using the tar4 format.

  45.   Installing vSphere CLI.

  46.   Installing version 161974 of vSphere CLI

  47.   You must read and accept the vSphere CLI End User License Agreement to
  48.   continue.
  49.   Press enter to display it.\"
  50.   
  51.     <ENTER>

  52.   \"Read through the License Agreement\"
  53.   \"Do you accept? (yes/no)
  54.   
  55.     yes


  56.   \"The following Perl modules were found on the system but may be too old to work
  57.   with VIPerl:
  58.   
  59.   Crypt::SSLeay
  60.   Compress::Zlib\"
  61.   
  62.   \"In which directory do you want to install the executable files? [/usr/bin]\"

  63.     <ENTER>

  64.   \"Please wait while copying vSphere CLI files...

  65.   The installation of vSphere CLI 4.0.0 build-161974 for Linux completed
  66.   successfully. You can decide to remove this software from your system at any
  67.   time by invoking the following command:
  68.   \"/usr/bin/vmware-uninstall-vSphere-CLI.pl\".
  69.   
  70.   This installer has successfully installed both vSphere CLI and the vSphere SDK
  71.   for Perl.
  72.   Enjoy,
  73.   
  74.   --the VMware team\"

  75. Note: \"Crypt::SSLeay\" and \"Compress::Zlib\" are not needed for check_esx3 to work.
  76. ";


  77. eval {
  78.     require VMware::VIRuntime
  79. } or Nagios::Plugin::Functions::nagios_exit(UNKNOWN, "Missing perl module VMware::VIRuntime. Download and install \'VMware Infrastructure (VI) Perl Toolkit\', available at http://www.vmware.com/download/sdk/\n $perl_module_instructions");

  80. $PROGNAME = basename($0);
  81. $VERSION = '0.5.0';

  82. my $np = Nagios::Plugin->new(
  83.   usage => "Usage: %s -D <data_center> | -H <host_name> [ -N <vm_name> ]\n"
  84.     . " -u <user> -p <pass> | -f <authfile>\n"
  85.     . " -l <command> [ -s <subcommand> ]\n"
  86.     . " [ -x <black_list> ] [ -o <additional_options> ]\n"
  87.     . " [ -t <timeout> ] [ -w <warn_range> ] [ -c <crit_range> ]\n"
  88.     . ' [ -V ] [ -h ]',
  89.   version => $VERSION,
  90.   plugin => $PROGNAME,
  91.   shortname => uc($PROGNAME),
  92.   blurb => 'VMWare Infrastructure plugin',
  93.   extra => "Supported commands(^ means blank or not specified parameter) :\n"
  94.     . " Common options for VM, Host and DC :\n"
  95.     . " * cpu - shows cpu info\n"
  96.     . " + usage - CPU usage in percentage\n"
  97.     . " + usagemhz - CPU usage in MHz\n"
  98.     . " ^ all cpu info\n"
  99.     . " * mem - shows mem info\n"
  100.     . " + usage - mem usage in percentage\n"
  101.     . " + usagemb - mem usage in MB\n"
  102.     . " + swap - swap mem usage in MB\n"
  103.     . " + overhead - additional mem used by VM Server in MB\n"
  104.     . " + overall - overall mem used by VM Server in MB\n"
  105.     . " + memctl - mem used by VM memory control driver(vmmemctl) that controls ballooning\n"
  106.     . " ^ all mem info\n"
  107.     . " * net - shows net info\n"
  108.     . " + usage - overall network usage in KBps(Kilobytes per Second) \n"
  109.     . " + receive - receive in KBps(Kilobytes per Second) \n"
  110.     . " + send - send in KBps(Kilobytes per Second) \n"
  111.     . " ^ all net info\n"
  112.     . " * io - shows disk io info\n"
  113.     . " + read - read latency in ms (totalReadLatency.average)\n"
  114.     . " + write - write latency in ms (totalWriteLatency.average)\n"
  115.     . " ^ all disk io info\n"
  116.     . " * runtime - shows runtime info\n"
  117.     . " + status - overall host status (gray/green/red/yellow)\n"
  118.     . " + issues - all issues for the host\n"
  119.     . " ^ all runtime info\n"
  120.     . " VM specific :\n"
  121.     . " * cpu - shows cpu info\n"
  122.     . " + wait - CPU wait time in ms\n"
  123.     . " + ready - CPU ready time in ms\n"
  124.     . " * mem - shows mem info\n"
  125.     . " + swapin - swapin mem usage in MB\n"
  126.     . " + swapout - swapout mem usage in MB\n"
  127.     . " + active - active mem usage in MB\n"
  128.     . " * io - shows disk I/O info\n"
  129.     . " + usage - overall disk usage in MB/s\n"
  130.     . " * runtime - shows runtime info\n"
  131.     . " + con - connection state\n"
  132.     . " + cpu - allocated CPU in MHz\n"
  133.     . " + mem - allocated mem in MB\n"
  134.     . " + state - virtual machine state (UP, DOWN, SUSPENDED)\n"
  135.     . " + consoleconnections - console connections to VM\n"
  136.     . " + guest - guest OS status, needs VMware Tools\n"
  137.     . " + tools - VMWare Tools status\n"
  138.     . " Host specific :\n"
  139.     . " * net - shows net info\n"
  140.     . " + nic - makes sure all active NICs are plugged in\n"
  141.     . " * io - shows disk io info\n"
  142.     . " + aborted - aborted commands count\n"
  143.     . " + resets - bus resets count\n"
  144.     . " + kernel - kernel latency in ms\n"
  145.     . " + device - device latency in ms\n"
  146.     . " + queue - queue latency in ms\n"
  147.     . " * vmfs - shows Datastore info\n"
  148.     . " + (name) - free space info for datastore with name (name)\n"
  149.     . " ^ all datastore info\n"
  150.     . " * runtime - shows runtime info\n"
  151.     . " + con - connection state\n"
  152.     . " + health - checks cpu/storage/memory/sensor status\n"
  153.     . " + maintenance - shows whether host is in maintenance mode\n"
  154.     . " + list(vm) - list of VMWare machines and their statuses\n"
  155.     . " * service - shows Host service info\n"
  156.     . " + (names) - check the state of one or several services specified by (names), syntax for (names):<service1>,<service2>,...,<serviceN>\n"
  157.     . " ^ show all services\n"
  158.     . " * storage - shows Host storage info\n"
  159.     . " + adapter - list bus adapters\n"
  160.     . " + lun - list SCSI logical units\n"
  161.     . " + path - list logical unit paths\n"
  162.     . " DC specific :\n"
  163.     . " * io - shows disk io info\n"
  164.     . " + aborted - aborted commands count\n"
  165.     . " + resets - bus resets count\n"
  166.     . " + kernel - kernel latency in ms\n"
  167.     . " + device - device latency in ms\n"
  168.     . " + queue - queue latency in ms\n"
  169.     . " * vmfs - shows Datastore info\n"
  170.     . " + (name) - free space info for datastore with name (name)\n"
  171.     . " ^ all datastore info\n"
  172.     . " * runtime - shows runtime info\n"
  173.     . " + list(vm) - list of VMWare machines and their statuses\n"
  174.     . " + listhost - list of VMWare esx host servers and their statuses\n"
  175.     . " + tools - VMWare Tools status\n"
  176.     . " * recommendations - shows recommendations for cluster\n"
  177.     . " + (name) - recommendations for cluster with name (name)\n"
  178.     . " ^ all clusters recommendations\n"
  179.     . "\n\nCopyright (c) 2008 op5",
  180.   timeout => 30,
  181. );

  182. $np->add_arg(
  183.   spec => 'host|H=s',
  184.   help => "-H, --host=<hostname>\n"
  185.     . ' ESX or ESXi hostname.',
  186.   required => 0,
  187. );

  188. $np->add_arg(
  189.   spec => 'cluster|C=s',
  190.   help => "-C, --cluster=<clustername>\n"
  191.     . ' ESX or ESXi clustername.',
  192.   required => 0,
  193. );

  194. $np->add_arg(
  195.   spec => 'datacenter|D=s',
  196.   help => "-D, --datacenter=<DCname>\n"
  197.     . ' Datacenter hostname.',
  198.   required => 0,
  199. );

  200. $np->add_arg(
  201.   spec => 'name|N=s',
  202.   help => "-N, --name=<vmname>\n"
  203.     . ' Virtual machine name.',
  204.   required => 0,
  205. );

  206. $np->add_arg(
  207.   spec => 'username|u=s',
  208.   help => "-u, --username=<username>\n"
  209.     . ' Username to connect with.',
  210.   required => 0,
  211. );

  212. $np->add_arg(
  213.   spec => 'password|p=s',
  214.   help => "-p, --password=<password>\n"
  215.     . ' Password to use with the username.',
  216.   required => 0,
  217. );

  218. $np->add_arg(
  219.   spec => 'authfile|f=s',
  220.   help => "-f, --authfile=<path>\n"
  221.     . " Authentication file with login and password. File syntax :\n"
  222.     . " username=<login>\n"
  223.     . ' password=<password>',
  224.   required => 0,
  225. );

  226. $np->add_arg(
  227.   spec => 'warning|w=s',
  228.   help => "-w, --warning=THRESHOLD\n"
  229.     . " Warning threshold. See\n"
  230.     . " http://nagiosplug.sourceforge.net/developer-guidelines.html#THRESHOLDFORMAT\n"
  231.     . ' for the threshold format.',
  232.   required => 0,
  233. );

  234. $np->add_arg(
  235.   spec => 'critical|c=s',
  236.   help => "-c, --critical=THRESHOLD\n"
  237.     . " Critical threshold. See\n"
  238.     . " http://nagiosplug.sourceforge.net/developer-guidelines.html#THRESHOLDFORMAT\n"
  239.     . ' for the threshold format.',
  240.   required => 0,
  241. );

  242. $np->add_arg(
  243.   spec => 'command|l=s',
  244.   help => "-l, --command=COMMAND\n"
  245.     . ' Specify command type (CPU, MEM, NET, IO, VMFS, RUNTIME, ...)',
  246.   required => 1,
  247. );

  248. $np->add_arg(
  249.   spec => 'subcommand|s=s',
  250.   help => "-s, --subcommand=SUBCOMMAND\n"
  251.     . ' Specify subcommand',
  252.   required => 0,
  253. );

  254. $np->add_arg(
  255.   spec => 'sessionfile|S=s',
  256.   help => "-S, --sessionfile=SESSIONFILE\n"
  257.     . ' Specify a filename to store sessions for faster authentication',
  258.   required => 0,
  259. );

  260. $np->add_arg(
  261.   spec => 'exclude|x=s',
  262.   help => "-x, --exclude=<black_list>\n"
  263.     . ' Specify black list',
  264.   required => 0,
  265. );

  266. $np->add_arg(
  267.   spec => 'options|o=s',
  268.   help => "-o, --options=<additional_options> \n"
  269.     . ' Specify additional command options',
  270.   required => 0,
  271. );

  272. $np->getopts;

  273. my $host = $np->opts->host;
  274. my $cluster = $np->opts->cluster;
  275. my $datacenter = $np->opts->datacenter;
  276. my $vmname = $np->opts->name;
  277. my $username = $np->opts->username;
  278. my $password = $np->opts->password;
  279. my $authfile = $np->opts->authfile;
  280. my $warning = $np->opts->warning;
  281. my $critical = $np->opts->critical;
  282. my $command = $np->opts->command;
  283. my $subcommand = $np->opts->subcommand;
  284. my $sessionfile = $np->opts->sessionfile;
  285. my $blacklist = $np->opts->exclude;
  286. my $addopts = $np->opts->options;
  287. my $percw;
  288. my $percc;
  289. $output = "Unknown ERROR!";
  290. $result = CRITICAL;

  291. if (defined($subcommand))
  292. {
  293.     $subcommand = undef if ($subcommand eq '');
  294. }

  295. if (defined($critical))
  296. {
  297.     ($percc, $critical) = check_percantage($critical);
  298.     $critical = undef if ($critical eq '');
  299. }

  300. if (defined($warning))
  301. {
  302.     ($percw, $warning) = check_percantage($warning);
  303.     $warning = undef if ($warning eq '');
  304. }

  305. $np->set_thresholds(critical => $critical, warning => $warning);

  306. eval
  307. {
  308.     die "Provide either Password/Username or Auth file or Session file\n" if ((!defined($password) || !defined($username) || defined($authfile)) && (defined($password) || defined($username) || !defined($authfile)) && (defined($password) || defined($username) || defined($authfile) || !defined($sessionfile)));
  309.     die "Both threshold values must be the same units\n" if (($percw && !$percc && defined($critical)) || (!$percw && $percc && defined($warning)));
  310.     if (defined($authfile))
  311.     {
  312.         open (AUTH_FILE, $authfile) || die "Unable to open auth file \"$authfile\"\n";
  313.         while( <AUTH_FILE> ) {
  314.             if(s/^[ \t]*username[ \t]*=//){
  315.                 s/^\s+//;s/\s+$//;
  316.                 $username = $_;
  317.             }
  318.             if(s/^[ \t]*password[ \t]*=//){
  319.                 s/^\s+//;s/\s+$//;
  320.                 $password = $_;
  321.             }
  322.         }
  323.         die "Auth file must contain both username and password\n" if (!(defined($username) && defined($password)));
  324.     }

  325.     my $host_address;

  326.     if (defined($datacenter))
  327.     {
  328.         $host_address = $datacenter;
  329.     }
  330.     elsif (defined($host))
  331.     {
  332.         $host_address = $host;
  333.     }
  334.     else
  335.     {
  336.         $np->nagios_exit(CRITICAL, "No Host or Datacenter specified");
  337.     }

  338.     $host_address .= ":443" if (index($host_address, ":") == -1);
  339.     $host_address = "https://" . $host_address . "/sdk/webService";

  340.     if (defined($sessionfile) and -e $sessionfile)
  341.     {
  342.         Opts::set_option("sessionfile", $sessionfile);
  343.         eval {
  344.             Util::connect($host_address, $username, $password);
  345.             die "Connected host doesn't match reqested once\n" if (Opts::get_option("url") ne $host_address);
  346.         };
  347.         if ($@) {
  348.             Opts::set_option("sessionfile", undef);
  349.             Util::connect($host_address, $username, $password);
  350.         }
  351.     }
  352.     else
  353.     {
  354.         Util::connect($host_address, $username, $password);
  355.     }

  356.     if (defined($sessionfile))
  357.     {
  358.         Vim::save_session(session_file => $sessionfile);
  359.     }
  360.     $command = uc($command);
  361.     if (defined($vmname))
  362.     {
  363.         if ($command eq "CPU")
  364.         {
  365.             ($result, $output) = vm_cpu_info($vmname, $np, local_uc($subcommand));
  366.         }
  367.         elsif ($command eq "MEM")
  368.         {
  369.             ($result, $output) = vm_mem_info($vmname, $np, local_uc($subcommand));
  370.         }
  371.         elsif ($command eq "NET")
  372.         {
  373.             ($result, $output) = vm_net_info($vmname, $np, local_uc($subcommand));
  374.         }
  375.         elsif ($command eq "IO")
  376.         {
  377.             ($result, $output) = vm_disk_io_info($vmname, $np, local_uc($subcommand));
  378.         }
  379.         elsif ($command eq "RUNTIME")
  380.         {
  381.             ($result, $output) = vm_runtime_info($vmname, $np, local_uc($subcommand));
  382.         }
  383.         else
  384.         {
  385.             $output = "Unknown HOST-VM command\n" . $np->opts->_help;
  386.             $result = CRITICAL;
  387.         }
  388.     }
  389.     elsif (defined($host))
  390.     {
  391.         my $esx;
  392.         $esx = {name => $host} if (defined($datacenter));
  393.         if ($command eq "CPU")
  394.         {
  395.             ($result, $output) = host_cpu_info($esx, $np, local_uc($subcommand), $addopts);
  396.         }
  397.         elsif ($command eq "MEM")
  398.         {
  399.             ($result, $output) = host_mem_info($esx, $np, local_uc($subcommand), $addopts);
  400.         }
  401.         elsif ($command eq "NET")
  402.         {
  403.             ($result, $output) = host_net_info($esx, $np, local_uc($subcommand));
  404.         }
  405.         elsif ($command eq "IO")
  406.         {
  407.             ($result, $output) = host_disk_io_info($esx, $np, local_uc($subcommand));
  408.         }
  409.         elsif ($command eq "VMFS")
  410.         {
  411.             ($result, $output) = host_list_vm_volumes_info($esx, $np, $subcommand, $blacklist, $percc || $percw, $addopts);
  412.         }
  413.         elsif ($command eq "RUNTIME")
  414.         {
  415.             ($result, $output) = host_runtime_info($esx, $np, local_uc($subcommand), $blacklist);
  416.         }
  417.         elsif ($command eq "SERVICE")
  418.         {
  419.             ($result, $output) = host_service_info($esx, $np, $subcommand);
  420.         }
  421.         elsif ($command eq "STORAGE")
  422.         {
  423.             ($result, $output) = host_storage_info($esx, $np, local_uc($subcommand), $blacklist);
  424.         }
  425.         else
  426.         {
  427.             $output = "Unknown HOST command\n" . $np->opts->_help;
  428.             $result = CRITICAL;
  429.         }
  430.     }
  431.     elsif (defined($cluster))
  432.     {
  433.         if ($command eq "CPU")
  434.         {
  435.             ($result, $output) = cluster_cpu_info($cluster, $np, local_uc($subcommand));
  436.         }
  437.         elsif ($command eq "MEM")
  438.         {
  439.             ($result, $output) = cluster_mem_info($cluster, $np, local_uc($subcommand), $addopts);
  440.         }
  441.         elsif ($command eq "CLUSTER")
  442.         {
  443.             ($result, $output) = cluster_cluster_info($cluster, $np, local_uc($subcommand));
  444.         }
  445.         elsif ($command eq "VMFS")
  446.         {
  447.             ($result, $output) = cluster_list_vm_volumes_info($cluster, $np, $subcommand, $blacklist, $percc || $percw, $addopts);
  448.         }
  449.         elsif ($command eq "RUNTIME")
  450.         {
  451.             ($result, $output) = cluster_runtime_info($cluster, $np, local_uc($subcommand));
  452.         }
  453.         else
  454.         {
  455.             $output = "Unknown CLUSTER command\n" . $np->opts->_help;
  456.             $result = CRITICAL;
  457.         }
  458.     }
  459.     else
  460.     {
  461.         if ($command eq "RECOMMENDATIONS")
  462.         {
  463.             my $cluster_name;
  464.             $cluster_name = {name => $subcommand} if (defined($subcommand));
  465.             ($result, $output) = return_cluster_DRS_recommendations($np, $cluster_name);
  466.         }
  467.         elsif ($command eq "CPU")
  468.         {
  469.             ($result, $output) = dc_cpu_info($np, local_uc($subcommand), $addopts);
  470.         }
  471.         elsif ($command eq "MEM")
  472.         {
  473.             ($result, $output) = dc_mem_info($np, local_uc($subcommand), $addopts);
  474.         }
  475.         elsif ($command eq "NET")
  476.         {
  477.             ($result, $output) = dc_net_info($np, local_uc($subcommand));
  478.         }
  479.         elsif ($command eq "IO")
  480.         {
  481.             ($result, $output) = dc_disk_io_info($np, local_uc($subcommand));
  482.         }
  483.         elsif ($command eq "VMFS")
  484.         {
  485.             ($result, $output) = dc_list_vm_volumes_info($np, $subcommand, $blacklist, $percc || $percw, $addopts);
  486.         }
  487.         elsif ($command eq "RUNTIME")
  488.         {
  489.             ($result, $output) = dc_runtime_info($np, local_uc($subcommand), $blacklist);
  490.         }
  491.         else
  492.         {
  493.             $output = "Unknown HOST command\n" . $np->opts->_help;
  494.             $result = CRITICAL;
  495.         }        
  496.     }
  497. };
  498. if ($@)
  499. {
  500.     if (uc(ref($@)) eq "HASH")
  501.     {
  502.         $output = $@->{msg};
  503.         $result = $@->{code};
  504.     }
  505.     else
  506.     {
  507.         $output = $@ . "";
  508.         $result = CRITICAL;
  509.     }
  510. }

  511. Util::disconnect();
  512. $np->nagios_exit($result, $output);

  513. #######################################################################################################################################################################

  514. sub get_key_metrices {
  515.     my ($perfmgr_view, $group, @names) = @_;

  516.     my $perfCounterInfo = $perfmgr_view->perfCounter;
  517.     my @counters;

  518.     die "Insufficient rights to access perfcounters\n" if (!defined($perfCounterInfo));

  519.     foreach (@$perfCounterInfo) {
  520.         if ($_->groupInfo->key eq $group) {
  521.             my $cur_name = $_->nameInfo->key . "." . $_->rollupType->val;
  522.             foreach my $index (0..@names-1)
  523.             {
  524.                 if ($names[$index] =~ /$cur_name/)
  525.                 {
  526.                     $names[$index] =~ /(\w+).(\w+):*(.*)/;
  527.                     $counters[$index] = PerfMetricId->new(counterId => $_->key, instance => $3);
  528.                 }
  529.             }
  530.         }
  531.     }

  532.     return \@counters;
  533. }

  534. sub generic_performance_values {
  535.     my ($views, $group, @list) = @_;
  536.     my $counter = 0;
  537.     my @values = ();
  538.     my $amount = @list;
  539.     my $perfMgr = Vim::get_view(mo_ref => Vim::get_service_content()->perfManager, properties => [ 'perfCounter' ]);
  540.     my $metrices = get_key_metrices($perfMgr, $group, @list);

  541.     my @perf_query_spec = ();
  542.     push(@perf_query_spec, PerfQuerySpec->new(entity => $_, metricId => $metrices, format => 'csv', intervalId => 20, maxSample => 1)) foreach (@$views);
  543.     my $perf_data = $perfMgr->QueryPerf(querySpec => \@perf_query_spec);
  544.     $amount *= @$perf_data;

  545.     while (@$perf_data)
  546.     {
  547.         my $unsorted = shift(@$perf_data)->value;
  548.         my @host_values = ();

  549.         foreach my $id (@$unsorted)
  550.         {
  551.             foreach my $index (0..@$metrices-1)
  552.             {
  553.                 if ($id->id->counterId == $$metrices[$index]->counterId)
  554.                 {
  555.                     $counter++ if (!defined($host_values[$index]));
  556.                     $host_values[$index] = $id;
  557.                 }
  558.             }
  559.         }
  560.         push(@values, \@host_values);
  561.     }
  562.     return undef if ($counter != $amount || $counter == 0);
  563.     return \@values;
  564. }

  565. sub return_host_performance_values {
  566.     my $values;
  567.     my $host_name = shift(@_);
  568.     my $host_view = Vim::find_entity_views(view_type => 'HostSystem', filter => $host_name, properties => [ 'name', 'runtime.inMaintenanceMode' ]); # Added properties named argument.
  569.     die "Runtime error\n" if (!defined($host_view));
  570.     die "Host \"" . $$host_name{"name"} . "\" does not exist\n" if (!@$host_view);
  571.     die {msg => ("NOTICE: \"" . $$host_view[0]->name . "\" is in maintenance mode, check skipped\n"), code => OK} if (uc($$host_view[0]->get_property('runtime.inMaintenanceMode')) eq "TRUE");
  572.     $values = generic_performance_values($host_view, @_);

  573.     return undef if ($@);
  574.     return ($host_view, $values);
  575. }

  576. sub return_host_vmware_performance_values {
  577.     my $values;
  578.     my $vmname = shift(@_);
  579.     my $vm_view = Vim::find_entity_views(view_type => 'VirtualMachine', filter => {name => "$vmname"}, properties => [ 'name', 'runtime.powerState' ]);
  580.     die "Runtime error\n" if (!defined($vm_view));
  581.     die "VMware machine \"" . $vmname . "\" does not exist\n" if (!@$vm_view);
  582.     die "VMware machine \"" . $vmname . "\" is not running. Current state is \"" . $$vm_view[0]->get_property('runtime.powerState')->val . "\"\n" if ($$vm_view[0]->get_property('runtime.powerState')->val ne "poweredOn");
  583.     $values = generic_performance_values($vm_view, @_);

  584.     return $@ if ($@);
  585.     return ($vm_view, $values);
  586. }

  587. sub return_dc_performance_values {
  588.     my $values;
  589.     my $host_views = Vim::find_entity_views(view_type => 'HostSystem', properties => [ 'name' ]);
  590.     die "Runtime error\n" if (!defined($host_views));
  591.     die "Datacenter does not contain any hosts\n" if (!@$host_views);
  592.     $values = generic_performance_values($host_views, @_);

  593.     return undef if ($@);
  594.     return ($host_views, $values);
  595. }

  596. sub return_cluster_performance_values {
  597.     my $values;
  598.     my $cluster_name = shift(@_);
  599.     my $cluster_view = Vim::find_entity_views(view_type => 'ClusterComputeResource', filter => { name => "$cluster_name" }, properties => [ 'name' ]); # Added properties named argument.
  600.     die "Runtime error\n" if (!defined($cluster_view));
  601.     die "Cluster \"" . $cluster_name . "\" does not exist\n" if (!@$cluster_view);
  602.     $values = generic_performance_values($cluster_view, @_);

  603.     return undef if ($@);
  604.     return $values;
  605. }

  606. sub local_uc
  607. {
  608.     my ($val) = shift(@_);
  609.     return defined($val)?uc($val):undef;
  610. }

  611. sub simplify_number
  612. {
  613.     my ($number, $cnt) = @_;
  614.     $cnt = 2 if (!defined($cnt));
  615.     return sprintf("%.${cnt}f", "$number");
  616. }

  617. sub convert_number
  618. {
  619.     my @vals = split(/,/, shift(@_));
  620.     return shift(@vals) if ($vals[-1] < 0);
  621.     return pop(@vals);
  622. }

  623. sub check_percantage
  624. {
  625.     my ($number) = shift(@_);
  626.     my $perc = $number =~ s/\%//;
  627.     return ($perc, $number);
  628. }

  629. sub check_health_state
  630. {
  631.     my ($state) = shift(@_);
  632.     my $res = UNKNOWN;

  633.     if (uc($state) eq "GREEN") {
  634.         $res = OK
  635.     } elsif (uc($state) eq "YELLOW") {
  636.         $res = WARNING;
  637.     } elsif (uc($state) eq "RED") {
  638.         $res = CRITICAL;
  639.     }
  640.     
  641.     return $res;
  642. }

  643. sub format_issue {
  644.     my ($issue) = shift(@_);

  645.     my $output = '';

  646.     if (defined($issue->datacenter))
  647.     {
  648.         $output .= 'Datacenter "' . $issue->datacenter->name . '", ';
  649.     }
  650.     if (defined($issue->host))
  651.     {
  652.         $output .= 'Host "' . $issue->host->name . '", ';
  653.     }
  654.     if (defined($issue->vm))
  655.     {
  656.         $output .= 'VM "' . $issue->vm->name . '", ';
  657.     }
  658.     if (defined($issue->computeResource))
  659.     {
  660.         $output .= 'Compute Resource "' . $issue->computeResource->name . '", ';
  661.     }
  662.     if (exists($issue->{dvs}) && defined($issue->dvs))
  663.     {
  664.         # Since vSphere API 4.0
  665.         $output .= 'Virtual Switch "' . $issue->dvs->name . '", ';
  666.     }
  667.     if (exists($issue->{ds}) && defined($issue->ds))
  668.     {
  669.         # Since vSphere API 4.0
  670.         $output .= 'Datastore "' . $issue->ds->name . '", ';
  671.     }
  672.     if (exists($issue->{net}) && defined($issue->net))
  673.     {
  674.         # Since vSphere API 4.0
  675.         $output .= 'Network "' . $issue->net->name . '" ';
  676.     }

  677.     $output =~ s/, $/ /;
  678.     $output .= ": " . $issue->fullFormattedMessage;
  679.     $output .= "(caused by " . $issue->userName . ")" if ($issue->userName ne "");

  680.     return $output;
  681. }

  682. sub datastore_volumes_info
  683. {
  684.     my ($datastore, $np, $subcommand, $blacklist, $perc, $addopts) = @_;

  685.     my $res = OK;
  686.     my $output = '';

  687.     my $usedflag;
  688.     my $briefflag;
  689.     my $regexpflag;
  690.     my $blackregexpflag;
  691.     $usedflag = $addopts =~ m/(^|\s|\t|,)\Qused\E($|\s|\t|,)/ if (defined($addopts));
  692.     $briefflag = $addopts =~ m/(^|\s|\t|,)\Qbrief\E($|\s|\t|,)/ if (defined($addopts));
  693.     $regexpflag = $addopts =~ m/(^|\s|\t|,)\Qregexp\E($|\s|\t|,)/ if (defined($addopts));
  694.     $blackregexpflag = $addopts =~ m/(^|\s|\t|,)\Qblacklistregexp\E($|\s|\t|,)/ if (defined($addopts));

  695.     die "Blacklist is supported only in generic check or regexp subcheck\n" if (defined($subcommand) && defined($blacklist) && !defined($regexpflag));

  696.     if (defined($regexpflag) && defined($subcommand))
  697.     {
  698.         eval
  699.         {
  700.             qr{$subcommand};
  701.         };
  702.         if ($@)
  703.         {
  704.             $@ =~ s/ at.*line.*\.//;
  705.             die $@;
  706.         }
  707.     }

  708.     my $state;
  709.     foreach my $ref_store (@{$datastore})
  710.     {
  711.         my $store = Vim::get_view(mo_ref => $ref_store, properties => ['summary', 'info']);
  712.         my $name = $store->summary->name;
  713.         if (!defined($subcommand) || ($name eq $subcommand) || (defined($regexpflag) && $name =~ /$subcommand/))
  714.         {
  715.             if (defined($blacklist))
  716.             {
  717.                 next if ($blackregexpflag?$name =~ /$blacklist/:$blacklist =~ m/(^|\s|\t|,)\Q$name\E($|\s|\t|,)/);
  718.             }

  719.             if ($store->summary->accessible)
  720.             {
  721.                 my $value1 = simplify_number(convert_number($store->summary->freeSpace) / 1024 / 1024);
  722.                 my $value2 = convert_number($store->summary->capacity);
  723.                 $value2 = simplify_number(convert_number($store->info->freeSpace) / $value2 * 100) if ($value2 > 0);

  724.                 if ($usedflag)
  725.                 {
  726.                     $value1 = simplify_number(convert_number($store->summary->capacity) / 1024 / 1024) - $value1;
  727.                     $value2 = 100 - $value2;
  728.                 }

  729.                 $state = $np->check_threshold(check => $perc?$value2:$value1);
  730.                 $res = Nagios::Plugin::Functions::max_state($res, $state);
  731.                 $np->add_perfdata(label => $name, value => $perc?$value2:$value1, uom => $perc?'%':'MB', threshold => $np->threshold);
  732.                 $output .= $name . "=". $value1 . " MB (" . $value2 . "%), " if (!$briefflag || $state != OK);
  733.             }
  734.             else
  735.             {
  736.                 $res = CRITICAL;
  737.                 $output .= $name . " is not accessible, ";
  738.             }
  739.             last if (!$regexpflag && defined($subcommand) && ($name eq $subcommand));
  740.             $blacklist .= $blackregexpflag?"|^$name\$":",$name";
  741.         }
  742.     }

  743.     if ($output)
  744.     {
  745.         chop($output);
  746.         chop($output);
  747.         $output = "Storages : " . $output;
  748.     }
  749.     else
  750.     {
  751.         if ($briefflag)
  752.         {
  753.             $output = "There are no alerts";
  754.         }
  755.         else
  756.         {
  757.             $res = WARNING;
  758.             $output = defined($subcommand)?$regexpflag? "No matching volumes for regexp \"$subcommand\" found":"No volume named \"$subcommand\" found":"There are no volumes";
  759.         }
  760.     }

  761.     return ($res, $output);
  762. }

  763. #=====================================================================| HOST |============================================================================#

  764. sub host_cpu_info
  765. {
  766.     my ($host, $np, $subcommand, $addopts) = @_;

  767.     my $res = CRITICAL;
  768.     my $output = 'HOST CPU Unknown error';

  769.     my $quickStats;
  770.     $quickStats = $addopts =~ m/(^|\s|\t|,)\Qquickstats\E($|\s|\t|,)/ if (defined($addopts));

  771.     if (defined($subcommand))
  772.     {
  773.         if ($subcommand eq "USAGE")
  774.         {
  775.             my $value;
  776.             if (defined($quickStats))
  777.             {
  778.                 my $host_view = Vim::find_entity_view(view_type => 'HostSystem', filter => $host, properties => ['name', 'runtime.inMaintenanceMode', 'summary.hardware', 'summary.quickStats']);
  779.                 die "Host \"" . $$host{"name"} . "\" does not exist\n" if (!defined($host_view));
  780.                 die {msg => ("NOTICE: \"" . $host_view->name . "\" is in maintenance mode, check skipped\n"), code => OK} if (uc($host_view->get_property('runtime.inMaintenanceMode')) eq "TRUE");
  781.                 $values = $host_view->get_property('summary.quickStats');
  782.                 my $hardinfo = $host_view->get_property('summary.hardware');
  783.                 $value = simplify_number($values->overallCpuUsage / ($hardinfo->numCpuCores * $hardinfo->cpuMhz) * 100) if exists($values->{overallCpuUsage}) && defined($hardinfo);
  784.             }
  785.             else
  786.             {
  787.                 $values = return_host_performance_values($host, 'cpu', ('usage.average'));
  788.                 $value = simplify_number(convert_number($$values[0][0]->value) * 0.01) if (defined($values));
  789.             }
  790.             if (defined($value))
  791.             {
  792.                 $np->add_perfdata(label => "cpu_usage", value => $value, uom => '%', threshold => $np->threshold);
  793.                 $output = "cpu usage=" . $value . " %";
  794.                 $res = $np->check_threshold(check => $value);
  795.             }
  796.         }
  797.         elsif ($subcommand eq "USAGEMHZ")
  798.         {
  799.             my $value;
  800.             if (defined($quickStats))
  801.             {
  802.                 my $host_view = Vim::find_entity_view(view_type => 'HostSystem', filter => $host, properties => ['name', 'runtime.inMaintenanceMode', 'summary.quickStats']);
  803.                 die "Host \"" . $$host{"name"} . "\" does not exist\n" if (!defined($host_view));
  804.                 die {msg => ("NOTICE: \"" . $host_view->name . "\" is in maintenance mode, check skipped\n"), code => OK} if (uc($host_view->get_property('runtime.inMaintenanceMode')) eq "TRUE");
  805.                 $values = $host_view->get_property('summary.quickStats');
  806.                 $value = simplify_number($values->overallCpuUsage) if exists($values->{overallCpuUsage});
  807.             }
  808.             else
  809.             {
  810.                 $values = return_host_performance_values($host, 'cpu', ('usagemhz.average'));
  811.                 $value = simplify_number(convert_number($$values[0][0]->value)) if (defined($values));
  812.             }
  813.             if (defined($value))
  814.             {
  815.                 $np->add_perfdata(label => "cpu_usagemhz", value => $value, uom => 'Mhz', threshold => $np->threshold);
  816.                 $output = "cpu usagemhz=" . $value . " MHz";
  817.                 $res = $np->check_threshold(check => $value);
  818.             }
  819.         }
  820.         else
  821.         {
  822.             $res = CRITICAL;
  823.             $output = "HOST CPU - unknown subcommand\n" . $np->opts->_help;
  824.         }
  825.     }
  826.     else
  827.     {
  828.         my $value1;
  829.         my $value2;
  830.         if (defined($quickStats))
  831.         {
  832.             my $host_view = Vim::find_entity_view(view_type => 'HostSystem', filter => $host, properties => ['name', 'runtime.inMaintenanceMode', 'summary.hardware', 'summary.quickStats']);
  833.             die "Host \"" . $$host{"name"} . "\" does not exist\n" if (!defined($host_view));
  834.             die {msg => ("NOTICE: \"" . $host_view->name . "\" is in maintenance mode, check skipped\n"), code => OK} if (uc($host_view->get_property('runtime.inMaintenanceMode')) eq "TRUE");
  835.             $values = $host_view->get_property('summary.quickStats');
  836.             my $hardinfo = $host_view->get_property('summary.hardware');
  837.             if (exists($values->{overallCpuUsage}) && defined($hardinfo))
  838.             {
  839.                 $value1 = simplify_number($values->overallCpuUsage);
  840.                 $value2 = simplify_number($values->overallCpuUsage / ($hardinfo->numCpuCores * $hardinfo->cpuMhz) * 100);
  841.             }
  842.         }
  843.         else
  844.         {
  845.             $values = return_host_performance_values($host, 'cpu', ('usagemhz.average', 'usage.average'));
  846.             if ($values) {
  847.                 $value1 = simplify_number(convert_number($$values[0][0]->value));
  848.                 $value2 = simplify_number(convert_number($$values[0][1]->value) * 0.01);
  849.             }
  850.         }
  851.         if (defined($value1) && defined($value2))
  852.         {
  853.             $np->add_perfdata(label => "cpu_usagemhz", value => $value1, uom => 'Mhz', threshold => $np->threshold);
  854.             $np->add_perfdata(label => "cpu_usage", value => $value2, uom => '%', threshold => $np->threshold);
  855.             $res = OK;
  856.             $output = "cpu usage=" . $value1 . " MHz (" . $value2 . "%)";
  857.         }
  858.     }

  859.     return ($res, $output);
  860. }

  861. sub host_mem_info
  862. {
  863.     my ($host, $np, $subcommand, $addopts) = @_;

  864.     my $res = CRITICAL;
  865.     my $output = 'HOST MEM Unknown error';

  866.     my $quickStats;
  867.     my $outputlist;
  868.     $quickStats = $addopts =~ m/(^|\s|\t|,)\Qquickstats\E($|\s|\t|,)/ if (defined($addopts));
  869.     $outputlist = $addopts =~ m/(^|\s|\t|,)\Qlistvm\E($|\s|\t|,)/ if (defined($addopts));

  870.     if (defined($subcommand))
  871.     {
  872.         if ($subcommand eq "USAGE")
  873.         {
  874.             my $value;
  875.             if (defined($quickStats))
  876.             {
  877.                 my $host_view = Vim::find_entity_view(view_type => 'HostSystem', filter => $host, properties => ['name', 'runtime.inMaintenanceMode', 'summary.hardware', 'summary.quickStats']);
  878.                 die "Host \"" . $$host{"name"} . "\" does not exist\n" if (!defined($host_view));
  879.                 die {msg => ("NOTICE: \"" . $host_view->name . "\" is in maintenance mode, check skipped\n"), code => OK} if (uc($host_view->get_property('runtime.inMaintenanceMode')) eq "TRUE");
  880.                 $values = $host_view->get_property('summary.quickStats');
  881.                 my $hardinfo = $host_view->get_property('summary.hardware');
  882.                 $value = simplify_number($values->overallMemoryUsage / ($hardinfo->memorySize / 1024 / 1024) * 100) if exists($values->{overallMemoryUsage}) && defined($hardinfo);
  883.             }
  884.             else
  885.             {
  886.                 $values = return_host_performance_values($host, 'mem', ('usage.average'));
  887.                 $value = simplify_number(convert_number($$values[0][0]->value) * 0.01) if (defined($values));
  888.             }
  889.             if (defined($value))
  890.             {
  891.                 $np->add_perfdata(label => "mem_usage", value => $value, uom => '%', threshold => $np->threshold);
  892.                 $output = "mem usage=" . $value . " %";
  893.                 $res = $np->check_threshold(check => $value);
  894.             }
  895.         }
  896.         elsif ($subcommand eq "USAGEMB")
  897.         {
  898.             my $value;
  899.             if (defined($quickStats))
  900.             {
  901.                 my $host_view = Vim::find_entity_view(view_type => 'HostSystem', filter => $host, properties => ['name', 'runtime.inMaintenanceMode', 'summary.quickStats']);
  902.                 die "Host \"" . $$host{"name"} . "\" does not exist\n" if (!defined($host_view));
  903.                 die {msg => ("NOTICE: \"" . $host_view->name . "\" is in maintenance mode, check skipped\n"), code => OK} if (uc($host_view->get_property('runtime.inMaintenanceMode')) eq "TRUE");
  904.                 $values = $host_view->get_property('summary.quickStats');
  905.                 $value = simplify_number($values->overallMemoryUsage) if exists($values->{overallMemoryUsage});
  906.             }
  907.             else
  908.             {
  909.                 $values = return_host_performance_values($host, 'mem', ('consumed.average'));
  910.                 $value = simplify_number(convert_number($$values[0][0]->value) / 1024) if (defined($values));
  911.             }
  912.             if (defined($value))
  913.             {
  914.                 $np->add_perfdata(label => "mem_usagemb", value => $value, uom => 'MB', threshold => $np->threshold);
  915.                 $output = "mem usage=" . $value . " MB";
  916.                 $res = $np->check_threshold(check => $value);
  917.             }
  918.         }
  919.         elsif ($subcommand eq "SWAP")
  920.         {
  921.             my $host_view;
  922.             ($host_view, $values) = return_host_performance_values($host, 'mem', ('swapused.average'));
  923.             if (defined($values))
  924.             {
  925.                 my $value = simplify_number(convert_number($$values[0][0]->value) / 1024);
  926.                 $np->add_perfdata(label => "mem_swap", value => $value, uom => 'MB', threshold => $np->threshold);
  927.                 $output = "swap usage=" . $value . " MB: ";
  928.                 $res = $np->check_threshold(check => $value);
  929.                 if ($res != OK && $outputlist)
  930.                 {
  931.                     my $vm_views = Vim::find_entity_views(view_type => 'VirtualMachine', begin_entity => $$host_view[0], properties => ['name', 'runtime.powerState']);
  932.                     die "Runtime error\n" if (!defined($vm_views));
  933.                     die "There are no VMs.\n" if (!@$vm_views);
  934.                     my @vms = ();
  935.                     foreach my $vm (@$vm_views)
  936.                     {
  937.                         push(@vms, $vm) if ($vm->get_property('runtime.powerState')->val eq "poweredOn");
  938.                     }
  939.                     $values = generic_performance_values(\@vms, 'mem', ('swapped.average'));
  940.                     if (defined($values))
  941.                     {
  942.                         foreach my $index (0..@vms-1) {
  943.                             my $value = simplify_number(convert_number($$values[$index][0]->value) / 1024);
  944.                             $output .= $vms[$index]->name . " (" . $value . "MB), " if ($value > 0);
  945.                         }
  946.                     }
  947.                 }
  948.                 chop($output);
  949.                 chop($output);
  950.             }
  951.         }
  952.         elsif ($subcommand eq "OVERHEAD")
  953.         {
  954.             $values = return_host_performance_values($host, 'mem', ('overhead.average'));
  955.             if (defined($values))
  956.             {
  957.                 my $value = simplify_number(convert_number($$values[0][0]->value) / 1024);
  958.                 $np->add_perfdata(label => "mem_overhead", value => $value, uom => 'MB', threshold => $np->threshold);
  959.                 $output = "overhead=" . $value . " MB";
  960.                 $res = $np->check_threshold(check => $value);
  961.             }
  962.         }
  963.         elsif ($subcommand eq "OVERALL")
  964.         {
  965.             $values = return_host_performance_values($host, 'mem', ('consumed.average', 'overhead.average'));
  966.             if (defined($values))
  967.             {
  968.                 my $value = simplify_number((convert_number($$values[0][0]->value) + convert_number($$values[0][1]->value)) / 1024);
  969.                 $np->add_perfdata(label => "mem_overhead", value => $value, uom => 'MB', threshold => $np->threshold);
  970.                 $output = "overall=" . $value . " MB";
  971.                 $res = $np->check_threshold(check => $value);
  972.             }
  973.         }
  974.         elsif ($subcommand eq "MEMCTL")
  975.         {
  976.             my $host_view;
  977.             ($host_view, $values) = return_host_performance_values($host, 'mem', ('vmmemctl.average'));
  978.             if (defined($values))
  979.             {
  980.                 my $value = simplify_number(convert_number($$values[0][0]->value) / 1024);
  981.                 $np->add_perfdata(label => "mem_memctl", value => $value, uom => 'MB', threshold => $np->threshold);
  982.                 $output = "memctl=" . $value . " MB: ";
  983.                 $res = $np->check_threshold(check => $value);
  984.                 if ($res != OK && $outputlist)
  985.                 {
  986.                     my $vm_views = Vim::find_entity_views(view_type => 'VirtualMachine', begin_entity => $$host_view[0], properties => ['name', 'runtime.powerState']);
  987.                     die "Runtime error\n" if (!defined($vm_views));
  988.                     die "There are no VMs.\n" if (!@$vm_views);
  989.                     my @vms = ();
  990.                     foreach my $vm (@$vm_views)
  991.                     {
  992.                         push(@vms, $vm) if ($vm->get_property('runtime.powerState')->val eq "poweredOn");
  993.                     }
  994.                     $values = generic_performance_values(\@vms, 'mem', ('vmmemctl.average'));
  995.                     if (defined($values))
  996.                     {
  997.                         foreach my $index (0..@vms-1) {
  998.                             my $value = simplify_number(convert_number($$values[$index][0]->value) / 1024);
  999.                             $output .= $vms[$index]->name . " (" . $value . "MB), " if ($value > 0);
  1000.                         }
  1001.                     }
  1002.                 }
  1003.                 chop($output);
  1004.                 chop($output);
  1005.             }
  1006.         }
  1007.         else
  1008.         {
  1009.             $res = CRITICAL;
  1010.             $output = "HOST MEM - unknown subcommand\n" . $np->opts->_help;
  1011.         }
  1012.     }
  1013.     else
  1014.     {
  1015.         $values = return_host_performance_values($host, 'mem', ('consumed.average', 'usage.average', 'overhead.average', 'swapused.average', 'vmmemctl.average'));
  1016.         if (defined($values))
  1017.         {
  1018.             my $value1 = simplify_number(convert_number($$values[0][0]->value) / 1024);
  1019.             my $value2 = simplify_number(convert_number($$values[0][1]->value) * 0.01);
  1020.             my $value3 = simplify_number(convert_number($$values[0][2]->value) / 1024);
  1021.             my $value4 = simplify_number(convert_number($$values[0][3]->value) / 1024);
  1022.             my $value5 = simplify_number(convert_number($$values[0][4]->value) / 1024);
  1023.             $np->add_perfdata(label => "mem_usagemb", value => $value1, uom => 'MB', threshold => $np->threshold);
  1024.             $np->add_perfdata(label => "mem_usage", value => $value2, uom => '%', threshold => $np->threshold);
  1025.             $np->add_perfdata(label => "mem_overhead", value => $value3, uom => 'MB', threshold => $np->threshold);
  1026.             $np->add_perfdata(label => "mem_swap", value => $value4, uom => 'MB', threshold => $np->threshold);
  1027.             $np->add_perfdata(label => "mem_memctl", value => $value5, uom => 'MB', threshold => $np->threshold);
  1028.             $res = OK;
  1029.             $output = "mem usage=" . $value1 . " MB (" . $value2 . "%), overhead=" . $value3 . " MB, swapped=" . $value4 . " MB, memctl=" . $value5 . " MB";
  1030.         }
  1031.     }

  1032.     return ($res, $output);
  1033. }

  1034. sub host_net_info
  1035. {
  1036.     my ($host, $np, $subcommand) = @_;

  1037.     my $res = CRITICAL;
  1038.     my $output = 'HOST NET Unknown error';
  1039.     
  1040.     if (defined($subcommand))
  1041.     {
  1042.         if ($subcommand eq "USAGE")
  1043.         {
  1044.             $values = return_host_performance_values($host, 'net', ('usage.average:*'));
  1045.             if (defined($values))
  1046.             {
  1047.                 my $value = simplify_number(convert_number($$values[0][0]->value));
  1048.                 $np->add_perfdata(label => "net_usage", value => $value, uom => 'KBps', threshold => $np->threshold);
  1049.                 $output = "net usage=" . $value . " KBps";
  1050.                 $res = $np->check_threshold(check => $value);
  1051.             }
  1052.         }
  1053.         elsif ($subcommand eq "RECEIVE")
  1054.         {
  1055.             $values = return_host_performance_values($host, 'net', ('received.average:*'));
  1056.             if (defined($values))
  1057.             {
  1058.                 my $value = simplify_number(convert_number($$values[0][0]->value));
  1059.                 $np->add_perfdata(label => "net_receive", value => $value, uom => 'KBps', threshold => $np->threshold);
  1060.                 $output = "net receive=" . $value . " KBps";
  1061.                 $res = $np->check_threshold(check => $value);
  1062.             }
  1063.         }
  1064.         elsif ($subcommand eq "SEND")
  1065.         {
  1066.             $values = return_host_performance_values($host, 'net', ('transmitted.average:*'));
  1067.             if (defined($values))
  1068.             {
  1069.                 my $value = simplify_number(convert_number($$values[0][0]->value));
  1070.                 $np->add_perfdata(label => "net_send", value => $value, uom => 'KBps', threshold => $np->threshold);
  1071.                 $output = "net send=" . $value . " KBps";
  1072.                 $res = $np->check_threshold(check => $value);
  1073.             }
  1074.         }
  1075.         elsif ($subcommand eq "NIC")
  1076.         {
  1077.             my $host_view = Vim::find_entity_view(view_type => 'HostSystem', filter => $host, properties => ['name', 'configManager.networkSystem', 'runtime.inMaintenanceMode']);
  1078.             die "Host \"" . $$host{"name"} . "\" does not exist\n" if (!defined($host_view));
  1079.             die {msg => ("NOTICE: \"" . $host_view->name . "\" is in maintenance mode, check skipped\n"), code => OK} if (uc($host_view->get_property('runtime.inMaintenanceMode')) eq "TRUE");
  1080.             my $network_system = Vim::get_view(mo_ref => $host_view->get_property('configManager.networkSystem') , properties => ['networkInfo']);
  1081.             $network_system->update_view_data(['networkInfo']);
  1082.             my $network_config = $network_system->networkInfo;
  1083.             die "Host \"" . $$host{"name"} . "\" has no network info in the API.\n" if (!defined($network_config));

  1084.             $output = "";
  1085.             $res = OK;
  1086.             my $OKCount = 0;
  1087.             my $BadCount = 0;
  1088.             my @switches = ();

  1089.             # create a hash of NIC info to facilitate easy lookups
  1090.             my %NIC = ();
  1091.             foreach (@{$network_config->pnic})
  1092.             {
  1093.                 $NIC{$_->key} = $_;
  1094.             }

  1095.             push(@switches, $network_config->vswitch) if (exists($network_config->{vswitch}));
  1096.             push(@switches, $network_config->proxySwitch) if (exists($network_config->{proxySwitch}));

  1097.             # see which NICs are actively part of a switch
  1098.             foreach my $switch (@switches)
  1099.             {
  1100.                 foreach (@{$switch})
  1101.                 {
  1102.                     # get list of physical nics
  1103.                     if (defined($_->pnic)){
  1104.                         foreach my $nic_key (@{$_->pnic})
  1105.                         {
  1106.                             if (!defined($NIC{$nic_key}->linkSpeed))
  1107.                             {
  1108.                                 $output .= ", " if ($output);
  1109.                                 $output .= $NIC{$nic_key}->device . " is unplugged";
  1110.                                 $res = CRITICAL;
  1111.                                 $BadCount++;
  1112.                             }
  1113.                             else
  1114.                             {
  1115.                                 $OKCount++;
  1116.                             }
  1117.                         }
  1118.                     }
  1119.                 }
  1120.             }

  1121.             if (!$BadCount)
  1122.             {
  1123.                 $output = "All $OKCount NICs are connected";
  1124.             }
  1125.             else
  1126.             {
  1127.                 $output = $BadCount ."/" . ($BadCount + $OKCount) . " NICs are disconnected: " . $output;
  1128.             }
  1129.             $np->add_perfdata(label => "OK_NICs", value => $OKCount);
  1130.             $np->add_perfdata(label => "Bad_NICs", value => $BadCount);
  1131.         }
  1132.         else
  1133.         {
  1134.             $res = CRITICAL;
  1135.             $output = "HOST NET - unknown subcommand\n" . $np->opts->_help;
  1136.         }
  1137.     }
  1138.     else
  1139.     {
  1140.         my $host_view;
  1141.         ($host_view, $values) = return_host_performance_values($host, 'net', ('received.average:*', 'transmitted.average:*'));
  1142.         $output = '';
  1143.         if (defined($values))
  1144.         {
  1145.             my $value1 = simplify_number(convert_number($$values[0][0]->value));
  1146.             my $value2 = simplify_number(convert_number($$values[0][1]->value));
  1147.             $np->add_perfdata(label => "net_receive", value => $value1, uom => 'KBps', threshold => $np->threshold);
  1148.             $np->add_perfdata(label => "net_send", value => $value2, uom => 'KBps', threshold => $np->threshold);
  1149.             $res = OK;
  1150.             $output = "net receive=" . $value1 . " KBps, send=" . $value2 . " KBps, ";
  1151.         }
  1152.         $host_view = $$host_view[0];
  1153.         $host_view->update_view_data(['configManager.networkSystem']);
  1154.         my $network_system = Vim::get_view(mo_ref => $host_view->get_property('configManager.networkSystem') , properties => ['networkInfo']);
  1155.         $network_system->update_view_data(['networkInfo']);
  1156.         my $network_config = $network_system->networkInfo;
  1157.         if (defined($network_config))
  1158.         {
  1159.             my $OKCount = 0;
  1160.             my $BadCount = 0;

  1161.             # create a hash of NIC info to facilitate easy lookups
  1162.             my %NIC = ();
  1163.             foreach (@{$network_config->pnic})
  1164.             {
  1165.                 $NIC{$_->key} = $_;
  1166.             }

  1167.             my $nic_output = '';
  1168.             my @switches = ();

  1169.             push(@switches, $network_config->vswitch) if (exists($network_config->{vswitch}));
  1170.             push(@switches, $network_config->proxySwitch) if (exists($network_config->{proxySwitch}));

  1171.             # see which NICs are actively part of a switch
  1172.             foreach my $switch (@switches)
  1173.             {
  1174.                 foreach (@{$switch})
  1175.                 {
  1176.                     # get list of physical nics
  1177.                     if (defined($_->pnic)){
  1178.                         foreach my $nic_key (@{$_->pnic})
  1179.                         {
  1180.                             if (!defined($NIC{$nic_key}->linkSpeed))
  1181.                             {
  1182.                                 $nic_output .= ", " if ($output);
  1183.                                 $nic_output .= $NIC{$nic_key}->device . " is unplugged";
  1184.                                 $res = CRITICAL;
  1185.                                 $BadCount++;
  1186.                             }
  1187.                             else
  1188.                             {
  1189.                                 $OKCount++;
  1190.                             }
  1191.                         }
  1192.                     }
  1193.                 }
  1194.             }

  1195.             if (!$BadCount)
  1196.             {
  1197.                 $output .= "all $OKCount NICs are connected";
  1198.             }
  1199.             else
  1200.             {
  1201.                 $output .= $BadCount ."/" . ($BadCount + $OKCount) . " NICs are disconnected: " . $nic_output;
  1202.             }
  1203.             $np->add_perfdata(label => "OK_NICs", value => $OKCount);
  1204.             $np->add_perfdata(label => "Bad_NICs", value => $BadCount);
  1205.         }
  1206.     }

  1207.     return ($res, $output);
  1208. }

  1209. sub host_disk_io_info
  1210. {
  1211.     my ($host, $np, $subcommand) = @_;

  1212.     my $res = CRITICAL;
  1213.     my $output = 'HOST IO Unknown error';

  1214.     if (defined($subcommand))
  1215.     {
  1216.         if ($subcommand eq "ABORTED")
  1217.         {
  1218.             $values = return_host_performance_values($host, 'disk', ('commandsAborted.summation:*'));
  1219.             if (defined($values))
  1220.             {
  1221.                 my $value = simplify_number(convert_number($$values[0][0]->value), 0);
  1222.                 $np->add_perfdata(label => "io_aborted", value => $value, threshold => $np->threshold);
  1223.                 $output = "io commands aborted=" . $value;
  1224.                 $res = $np->check_threshold(check => $value);
  1225.             }
  1226.         }
  1227.         elsif ($subcommand eq "RESETS")
  1228.         {
  1229.             $values = return_host_performance_values($host, 'disk', ('busResets.summation:*'));
  1230.             if (defined($values))
  1231.             {
  1232.                 my $value = simplify_number(convert_number($$values[0][0]->value), 0);
  1233.                 $np->add_perfdata(label => "io_busresets", value => $value, threshold => $np->threshold);
  1234.                 $output = "io bus resets=" . $value;
  1235.                 $res = $np->check_threshold(check => $value);
  1236.             }
  1237.         }
  1238.         elsif ($subcommand eq "READ")
  1239.         {
  1240.             $values = return_host_performance_values($host, 'disk', ('totalReadLatency.average:*'));
  1241.             if (defined($values))
  1242.             {
  1243.                 my $value = simplify_number(convert_number($$values[0][0]->value), 0);
  1244.                 $np->add_perfdata(label => "io_read", value => $value, uom => 'ms', threshold => $np->threshold);
  1245.                 $output = "io read latency=" . $value . " ms";
  1246.                 $res = $np->check_threshold(check => $value);
  1247.             }
  1248.         }
  1249.         elsif ($subcommand eq "WRITE")
  1250.         {
  1251.             $values = return_host_performance_values($host, 'disk', ('totalWriteLatency.average:*'));
  1252.             if (defined($values))
  1253.             {
  1254.                 my $value = simplify_number(convert_number($$values[0][0]->value), 0);
  1255.                 $np->add_perfdata(label => "io_write", value => $value, uom => 'ms', threshold => $np->threshold);
  1256.                 $output = "io write latency=" . $value . " ms";
  1257.                 $res = $np->check_threshold(check => $value);
  1258.             }
  1259.         }
  1260.         elsif ($subcommand eq "KERNEL")
  1261.         {
  1262.             $values = return_host_performance_values($host, 'disk', ('kernelLatency.average:*'));
  1263.             if (defined($values))
  1264.             {
  1265.                 my $value = simplify_number(convert_number($$values[0][0]->value), 0);
  1266.                 $np->add_perfdata(label => "io_kernel", value => $value, uom => 'ms', threshold => $np->threshold);
  1267.                 $output = "io kernel latency=" . $value . " ms";
  1268.                 $res = $np->check_threshold(check => $value);
  1269.             }
  1270.         }
  1271.         elsif ($subcommand eq "DEVICE")
  1272.         {
  1273.             $values = return_host_performance_values($host, 'disk', ('deviceLatency.average:*'));
  1274.             if (defined($values))
  1275.             {
  1276.                 my $value = simplify_number(convert_number($$values[0][0]->value), 0);
  1277.                 $np->add_perfdata(label => "io_device", value => $value, uom => 'ms', threshold => $np->threshold);
  1278.                 $output = "io device latency=" . $value . " ms";
  1279.                 $res = $np->check_threshold(check => $value);
  1280.             }
  1281.         }
  1282.         elsif ($subcommand eq "QUEUE")
  1283.         {
  1284.             $values = return_host_performance_values($host, 'disk', ('queueLatency.average:*'));
  1285.             if (defined($values))
  1286.             {
  1287.                 my $value = simplify_number(convert_number($$values[0][0]->value), 0);
  1288.                 $np->add_perfdata(label => "io_queue", value => $value, uom => 'ms', threshold => $np->threshold);
  1289.                 $output = "io queue latency=" . $value . " ms";
  1290.                 $res = $np->check_threshold(check => $value);
  1291.             }
  1292.         }
  1293.         else
  1294.         {
  1295.             $res = CRITICAL;
  1296.             $output = "HOST IO - unknown subcommand\n" . $np->opts->_help;
  1297.         }
  1298.     }
  1299.     else
  1300.     {
  1301.         $values = return_host_performance_values($host, 'disk', ('commandsAborted.summation:*', 'busResets.summation:*', 'totalReadLatency.average:*', 'totalWriteLatency.average:*', 'kernelLatency.average:*', 'deviceLatency.average:*', 'queueLatency.average:*'));
  1302.         if (defined($values))
  1303.         {
  1304.             my $value1 = simplify_number(convert_number($$values[0][0]->value), 0);
  1305.             my $value2 = simplify_number(convert_number($$values[0][1]->value), 0);
  1306.             my $value3 = simplify_number(convert_number($$values[0][2]->value), 0);
  1307.             my $value4 = simplify_number(convert_number($$values[0][3]->value), 0);
  1308.             my $value5 = simplify_number(convert_number($$values[0][4]->value), 0);
  1309.             my $value6 = simplify_number(convert_number($$values[0][5]->value), 0);
  1310.             my $value7 = simplify_number(convert_number($$values[0][6]->value), 0);
  1311.             $np->add_perfdata(label => "io_aborted", value => $value1, threshold => $np->threshold);
  1312.             $np->add_perfdata(label => "io_busresets", value => $value2, threshold => $np->threshold);
  1313.             $np->add_perfdata(label => "io_read", value => $value3, uom => 'ms', threshold => $np->threshold);
  1314.             $np->add_perfdata(label => "io_write", value => $value4, uom => 'ms', threshold => $np->threshold);
  1315.             $np->add_perfdata(label => "io_kernel", value => $value5, uom => 'ms', threshold => $np->threshold);
  1316.             $np->add_perfdata(label => "io_device", value => $value6, uom => 'ms', threshold => $np->threshold);
  1317.             $np->add_perfdata(label => "io_queue", value => $value7, uom => 'ms', threshold => $np->threshold);
  1318.             $res = OK;
  1319.             $output = "io commands aborted=" . $value1 . ", io bus resets=" . $value2 . ", io read latency=" . $value3 . " ms, write latency=" . $value4 . " ms, kernel latency=" . $value5 . " ms, device latency=" . $value6 . " ms, queue latency=" . $value7 ." ms";
  1320.         }
  1321.     }

  1322.     return ($res, $output);
  1323. }

  1324. sub host_list_vm_volumes_info
  1325. {
  1326.     my ($host, $np, $subcommand, $blacklist, $perc, $addopts) = @_;

  1327.     my $host_view = Vim::find_entity_view(view_type => 'HostSystem', filter => $host, properties => ['name', 'datastore', 'runtime.inMaintenanceMode']);
  1328.     die "Host \"" . $$host{"name"} . "\" does not exist\n" if (!defined($host_view));
  1329.     die {msg => ("NOTICE: \"" . $host_view->name . "\" is in maintenance mode, check skipped\n"), code => OK} if (uc($host_view->get_property('runtime.inMaintenanceMode')) eq "TRUE");
  1330.     die "Insufficient rights to access Datastores on the Host\n" if (!defined($host_view->datastore));

  1331.     return datastore_volumes_info($host_view->datastore, $np, $subcommand, $blacklist, $perc, $addopts);
  1332. }

  1333. sub host_runtime_info
  1334. {
  1335.     my ($host, $np, $subcommand, $blacklist) = @_;

  1336.     my $res = CRITICAL;
  1337.     my $output = 'HOST RUNTIME Unknown error';
  1338.     my $runtime;
  1339.     my $host_view = Vim::find_entity_view(view_type => 'HostSystem', filter => $host, properties => ['name', 'runtime', 'overallStatus', 'configIssue']);
  1340.     die "Host \"" . $$host{"name"} . "\" does not exist\n" if (!defined($host_view));
  1341.     $host_view->update_view_data(['name', 'runtime', 'overallStatus', 'configIssue']);
  1342.     $runtime = $host_view->runtime;
  1343.     die {msg => ("NOTICE: \"" . $host_view->name . "\" is in maintenance mode, check skipped\n"), code => OK} if ($runtime->inMaintenanceMode);

  1344.     if (defined($subcommand))
  1345.     {
  1346.         if ($subcommand eq "CON")
  1347.         {
  1348.             $output = "connection state=" . $runtime->connectionState->val;
  1349.             $res = OK if (uc($runtime->connectionState->val) eq "CONNECTED");
  1350.         }
  1351.         elsif ($subcommand eq "HEALTH")
  1352.         {
  1353.             my $OKCount = 0;
  1354.             my $AlertCount = 0;
  1355.             my ($cpuStatusInfo, $storageStatusInfo, $memoryStatusInfo, $numericSensorInfo);

  1356.             $res = UNKNOWN;

  1357.             if(defined($runtime->healthSystemRuntime))
  1358.             {
  1359.                 $cpuStatusInfo = $runtime->healthSystemRuntime->hardwareStatusInfo->cpuStatusInfo;
  1360.                 $storageStatusInfo = $runtime->healthSystemRuntime->hardwareStatusInfo->storageStatusInfo;
  1361.                 $memoryStatusInfo = $runtime->healthSystemRuntime->hardwareStatusInfo->memoryStatusInfo;
  1362.                 $numericSensorInfo = $runtime->healthSystemRuntime->systemHealthInfo->numericSensorInfo;

  1363.                 $output = '';

  1364.                 if (defined($cpuStatusInfo))
  1365.                 {
  1366.                     foreach (@$cpuStatusInfo)
  1367.                     {
  1368.                         # print "CPU Name = ". $_->name .", Label = ". $_->status->label . ", Summary = ". $_->status->summary . ", Key = ". $_->status->key . "\n";
  1369.                         my $state = check_health_state($_->status->key);
  1370.                         if ($state != OK)
  1371.                         {
  1372.                             $res = Nagios::Plugin::Functions::max_state($res, $state);
  1373.                             $output .= ", " if ($output);
  1374.                             $output .= $_->name . ": " . $_->status->summary;
  1375.                             $AlertCount++;
  1376.                         }
  1377.                         else
  1378.                         {
  1379.                             $OKCount++;
  1380.                         }
  1381.                     }
  1382.                 }

  1383.                 if (defined($storageStatusInfo))
  1384.                 {
  1385.                     foreach (@$storageStatusInfo)
  1386.                     {
  1387.                         # print "Storage Name = ". $_->name .", Label = ". $_->status->label . ", Summary = ". $_->status->summary . ", Key = ". $_->status->key . "\n";
  1388.                         my $state = check_health_state($_->status->key);
  1389.                         if ($state != OK)
  1390.                         {
  1391.                             $res = Nagios::Plugin::Functions::max_state($res, $state);
  1392.                             $output .= ", " if ($output);
  1393.                             $output .= "Storage " . $_->name . ": " . $_->status->summary;
  1394.                             $AlertCount++;
  1395.                         }
  1396.                         else
  1397.                         {
  1398.                             $OKCount++;
  1399.                         }
  1400.                     }
  1401.                 }

  1402.                 if (defined($memoryStatusInfo))
  1403.                 {
  1404.                     foreach (@$memoryStatusInfo)
  1405.                     {
  1406.                         # print "Memory Name = ". $_->name .", Label = ". $_->status->label . ", Summary = ". $_->status->summary . ", Key = ". $_->status->key . "\n";
  1407.                         my $state = check_health_state($_->status->key);
  1408.                         if ($state != OK)
  1409.                         {
  1410.                             $res = Nagios::Plugin::Functions::max_state($res, $state);
  1411.                             $output .= ", " if ($output);
  1412.                             $output .= "Memory: " . $_->status->summary;
  1413.                             $AlertCount++;
  1414.                         }
  1415.                         else
  1416.                         {
  1417.                             $OKCount++;
  1418.                         }
  1419.                     }
  1420.                 }

  1421.                 if (defined($numericSensorInfo))
  1422.                 {
  1423.                     foreach (@$numericSensorInfo)
  1424.                     {
  1425.                         # print "Sensor Name = ". $_->name .", Type = ". $_->sensorType . ", Label = ". $_->healthState->label . ", Summary = ". $_->healthState->summary . ", Key = " . $_->healthState->key . "\n";
  1426.                         my $state = check_health_state($_->healthState->key);
  1427.                         if ($state != OK)
  1428.                         {
  1429.                             $res = Nagios::Plugin::Functions::max_state($res, $state);
  1430.                             $output .= ", " if ($output);
  1431.                             $output .= $_->sensorType . " sensor " . $_->name . ": ".$_->healthState->summary;
  1432.                             $AlertCount++;
  1433.                         }
  1434.                         else
  1435.                         {
  1436.                             $OKCount++;
  1437.                         }
  1438.                     }
  1439.                 }

  1440.                 if ($output)
  1441.                 {
  1442.                     $output = "$AlertCount health issue(s) found: $output";
  1443.                 }
  1444.                 else
  1445.                 {
  1446.                     $output = "All $OKCount health checks are Green";
  1447.                     $res = OK;
  1448.                 }
  1449.             }
  1450.             else
  1451.             {
  1452.                 $res = "System health status unavailable";
  1453.             }

  1454.             $np->add_perfdata(label => "Alerts", value => $AlertCount);
  1455.         }
  1456.         elsif ($subcommand eq "MAINTENANCE")
  1457.         {
  1458.             my %host_maintenance_state = (0 => "no", 1 => "yes");
  1459.             $output = "maintenance=" . $host_maintenance_state{$runtime->inMaintenanceMode};
  1460.             $res = OK;
  1461.         }
  1462.         elsif (($subcommand eq "LIST") || ($subcommand eq "LISTVM"))
  1463.         {
  1464.             my %vm_state_strings = ("poweredOn" => "UP", "poweredOff" => "DOWN", "suspended" => "SUSPENDED");
  1465.             my $vm_views = Vim::find_entity_views(view_type => 'VirtualMachine', begin_entity => $host_view, properties => ['name', 'runtime']);
  1466.             die "Runtime error\n" if (!defined($vm_views));
  1467.             die "There are no VMs.\n" if (!@$vm_views);
  1468.             my $up = 0;
  1469.             $output = '';

  1470.             foreach my $vm (@$vm_views)
  1471.             {
  1472.                 my $vm_state = $vm_state_strings{$vm->runtime->powerState->val};
  1473.                 if ($vm_state eq "UP")
  1474.                 {
  1475.                     $up++;
  1476.                     $output .= $vm->name . "(OK), ";
  1477.                 }
  1478.                 else
  1479.                 {
  1480.                     $output = $vm->name . "(" . $vm_state . "), " . $output;
  1481.                 }
  1482.             }

  1483.             chop($output);
  1484.             chop($output);
  1485.             $res = OK;
  1486.             $output = $up . "/" . @$vm_views . " VMs up: " . $output;
  1487.             $np->add_perfdata(label => "vmcount", value => $up, uom => 'units', threshold => $np->threshold);
  1488.             $res = $np->check_threshold(check => $up) if (defined($np->threshold));
  1489.         }
  1490.         elsif ($subcommand eq "STATUS")
  1491.         {
  1492.             my $status = $host_view->overallStatus->val;
  1493.             $output = "overall status=" . $status;
  1494.             $res = check_health_state($status);
  1495.         }
  1496.         elsif ($subcommand eq "ISSUES")
  1497.         {
  1498.             my $issues = $host_view->configIssue;

  1499.             $output = '';
  1500.             if (defined($issues))
  1501.             {
  1502.                 foreach (@$issues)
  1503.                 {
  1504.                     if (defined($blacklist))
  1505.                     {
  1506.                         my $name = ref($_);
  1507.                         next if ($blacklist =~ m/(^|\s|\t|,)\Q$name\E($|\s|\t|,)/);
  1508.                     }
  1509.                     $output .= format_issue($_) . "; ";
  1510.                 }
  1511.             }

  1512.             if ($output eq '')
  1513.             {
  1514.                 $res = OK;
  1515.                 $output = 'No config issues';
  1516.             }
  1517.         }
  1518.         else
  1519.         {
  1520.             $res = CRITICAL;
  1521.             $output = "HOST RUNTIME - unknown subcommand\n" . $np->opts->_help;
  1522.         }
  1523.     }
  1524.     else
  1525.     {
  1526.         my %host_maintenance_state = (0 => "no", 1 => "yes");
  1527.         my $vm_views = Vim::find_entity_views(view_type => 'VirtualMachine', begin_entity => $host_view, properties => ['name', 'runtime']);
  1528.         my $up = 0;

  1529.         die "Runtime error\n" if (!defined($vm_views));
  1530.         if (@$vm_views)
  1531.         {
  1532.             foreach my $vm (@$vm_views)
  1533.             {
  1534.                 $up += $vm->runtime->powerState->val eq "poweredOn";
  1535.             }
  1536.             $output = $up . "/" . @$vm_views . " VMs up";
  1537.         }
  1538.         else
  1539.         {
  1540.             $output = "No VMs installed";
  1541.         }
  1542.         $np->add_perfdata(label => "vmcount", value => $up, uom => 'units', threshold => $np->threshold);

  1543.         my $AlertCount = 0;
  1544.         my $SensorCount = 0;
  1545.         my ($cpuStatusInfo, $storageStatusInfo, $memoryStatusInfo, $numericSensorInfo);
  1546.         if(defined($runtime->healthSystemRuntime))
  1547.         {
  1548.             $cpuStatusInfo = $runtime->healthSystemRuntime->hardwareStatusInfo->cpuStatusInfo;
  1549.             $storageStatusInfo = $runtime->healthSystemRuntime->hardwareStatusInfo->storageStatusInfo;
  1550.             $memoryStatusInfo = $runtime->healthSystemRuntime->hardwareStatusInfo->memoryStatusInfo;
  1551.             $numericSensorInfo = $runtime->healthSystemRuntime->systemHealthInfo->numericSensorInfo;
  1552.         }

  1553.         if (defined($cpuStatusInfo))
  1554.         {
  1555.             foreach (@$cpuStatusInfo)
  1556.             {
  1557.                 $SensorCount++;
  1558.                 $AlertCount++ if (check_health_state($_->status->key) != OK);
  1559.             }
  1560.         }

  1561.         if (defined($storageStatusInfo))
  1562.         {
  1563.             foreach (@$storageStatusInfo)
  1564.             {
  1565.                 $SensorCount++;
  1566.                 $AlertCount++ if (check_health_state($_->status->key) != OK);
  1567.             }
  1568.         }

  1569.         if (defined($memoryStatusInfo))
  1570.         {
  1571.             foreach (@$memoryStatusInfo)
  1572.             {
  1573.                 $SensorCount++;
  1574.                 $AlertCount++ if (check_health_state($_->status->key) != OK);
  1575.             }
  1576.         }

  1577.         if (defined($numericSensorInfo))
  1578.         {
  1579.             foreach (@$numericSensorInfo)
  1580.             {
  1581.                 $SensorCount++;
  1582.                 $AlertCount++ if (check_health_state($_->healthState->key) != OK);
  1583.             }
  1584.         }

  1585.         $res = OK;
  1586.         $output .= ", overall status=" . $host_view->overallStatus->val . ", connection state=" . $runtime->connectionState->val . ", maintenance=" . $host_maintenance_state{$runtime->inMaintenanceMode} . ", ";

  1587.         if ($AlertCount)
  1588.         {
  1589.             $output .= "$AlertCount health issue(s), ";
  1590.         }
  1591.         else
  1592.         {
  1593.             $output .= "All $SensorCount health checks are Green, ";
  1594.         }
  1595.         $np->add_perfdata(label => "health_issues", value => $AlertCount);

  1596.         my $issues = $host_view->configIssue;
  1597.         if (defined($issues))
  1598.         {
  1599.             $output .= @$issues . " config issue(s)";
  1600.             $np->add_perfdata(label => "config_issues", value => "" . @$issues);
  1601.         }
  1602.         else
  1603.         {
  1604.             $output .= "no config issues";
  1605.             $np->add_perfdata(label => "config_issues", value => 0);
  1606.         }
  1607.     }

  1608.     return ($res, $output);
  1609. }

  1610. sub host_service_info
  1611. {
  1612.     my ($host, $np, $subcommand) = @_;

  1613.     my $res = CRITICAL;
  1614.     my $output = 'HOST RUNTIME Unknown error';
  1615.     my $host_view = Vim::find_entity_view(view_type => 'HostSystem', filter => $host, properties => ['name', 'configManager', 'runtime.inMaintenanceMode']);
  1616.     die "Host \"" . $$host{"name"} . "\" does not exist\n" if (!defined($host_view));
  1617.     die {msg => ("NOTICE: \"" . $host_view->name . "\" is in maintenance mode, check skipped\n"), code => OK} if (uc($host_view->get_property('runtime.inMaintenanceMode')) eq "TRUE");

  1618.     my $services = Vim::get_view(mo_ref => $host_view->configManager->serviceSystem, properties => ['serviceInfo'])->serviceInfo->service;

  1619.     if (defined($subcommand))
  1620.     {
  1621.         $subcommand = ',' . $subcommand . ',';
  1622.         $output = '';
  1623.         foreach (@$services)
  1624.         {
  1625.             my $srvname = $_->key;
  1626.             if ($subcommand =~ s/,$srvname,/,/g)
  1627.             {
  1628.                 while ($subcommand =~ s/,$srvname,/,/g){};
  1629.                 $output .= $srvname . ", " if (!$_->running);
  1630.             }
  1631.         }
  1632.         $subcommand =~ s/^,//;
  1633.         chop($subcommand);

  1634.         if ($subcommand ne '')
  1635.         {
  1636.             $res = UNKNOWN;
  1637.             $output = "unknown services : $subcommand";
  1638.         }
  1639.         elsif ($output eq '')
  1640.         {
  1641.             $res = OK;
  1642.             $output = "All services are in their apropriate state.";
  1643.         }
  1644.         else
  1645.         {
  1646.             chop($output);
  1647.             chop($output);
  1648.             $output .= " are down";
  1649.         }
  1650.     }
  1651.     else
  1652.     {
  1653.         my %service_state = (0 => "down", 1 => "up");
  1654.         $res = OK;
  1655.         $output = "services : ";
  1656.         $output .= $_->key . " (" . $service_state{$_->running} . "), " foreach (@$services);
  1657.         chop($output);
  1658.         chop($output);
  1659.     }

  1660.     return ($res, $output);
  1661. }

  1662. sub host_storage_info
  1663. {
  1664.     my ($host, $np, $subcommand, $blacklist) = @_;

  1665.     my $count = 0;
  1666.     my $res = CRITICAL;
  1667.     my $output = 'HOST RUNTIME Unknown error';
  1668.     my $host_view = Vim::find_entity_view(view_type => 'HostSystem', filter => $host, properties => ['name', 'configManager', 'runtime.inMaintenanceMode']);
  1669.     die "Host \"" . $$host{"name"} . "\" does not exist\n" if (!defined($host_view));
  1670.     die {msg => ("NOTICE: \"" . $host_view->name . "\" is in maintenance mode, check skipped\n"), code => OK} if (uc($host_view->get_property('runtime.inMaintenanceMode')) eq "TRUE");

  1671.     my $storage = Vim::get_view(mo_ref => $host_view->configManager->storageSystem, properties => ['storageDeviceInfo']);

  1672.     if (defined($subcommand))
  1673.     {
  1674.         if ($subcommand eq "ADAPTER")
  1675.         {
  1676.             $output = "";
  1677.             $res = OK;
  1678.             foreach my $dev (@{$storage->storageDeviceInfo->hostBusAdapter})
  1679.             {
  1680.                 my $name = $dev->device;
  1681.                 my $status = $dev->status;
  1682.                 if (defined($blacklist))
  1683.                 {
  1684.                     my $key = $dev->key;
  1685.                     if (($blacklist =~ m/(^|\s|\t|,)\Q$name\E($|\s|\t|,)/) || ($blacklist =~ m/(^|\s|\t|,)\Q$key\E($|\s|\t|,)/))
  1686.                     {
  1687.                         $count++;
  1688.                         $status = "ignored";
  1689.                     }
  1690.                 }
  1691.                 $count ++ if (uc($status) eq "ONLINE");
  1692.                 $res = UNKNOWN if (uc($status) eq "UNKNOWN");
  1693.                 $output .= $name . " (" . $status . "); ";
  1694.             }
  1695.             my $state = $np->check_threshold(check => $count);
  1696.             $res = $state if ($state != OK);
  1697.             $np->add_perfdata(label => "adapters", value => $count, uom => 'units', threshold => $np->threshold);
  1698.         }
  1699.         elsif ($subcommand eq "LUN")
  1700.         {
  1701.             $output = "";
  1702.             $res = OK;
  1703.             my $state = OK; # For unkonwn or other statuses
  1704.             foreach my $scsi (@{$storage->storageDeviceInfo->scsiLun})
  1705.             {
  1706.                 my $name = "";
  1707.                 if (exists($scsi->{displayName}))
  1708.                 {
  1709.                     $name = $scsi->displayName;
  1710.                 }
  1711.                 elsif (exists($scsi->{canonicalName}))
  1712.                 {
  1713.                     $name = $scsi->canonicalName;
  1714.                 }
  1715.                 else
  1716.                 {
  1717.                     $name = $scsi->deviceName;
  1718.                 }
  1719.                 $state = OK;

  1720.                 my $operationState;
  1721.                 if (defined($blacklist) && ($blacklist =~ m/(^|\s|\t|,)\Q$name\E($|\s|\t|,)/))
  1722.                 {
  1723.                     $operationState = "ignored";
  1724.                 }
  1725.                 else
  1726.                 {
  1727.                     $operationState = join("-", @{$scsi->operationalState});
  1728.                     foreach (@{$scsi->operationalState})
  1729.                     {
  1730.                         if (uc($_) eq "OK")
  1731.                         {
  1732.                             # $state = OK;
  1733.                         }
  1734.                         elsif (uc($_) eq "UNKNOWN")
  1735.                         {
  1736.                             $res = UNKNOWN;
  1737.                         }
  1738.                         elsif (uc($_) eq "UNKNOWNSTATE")
  1739.                         {
  1740.                             $res = UNKNOWN;
  1741.                         }
  1742.                         else
  1743.                         {
  1744.                             $state = CRITICAL;
  1745.                         }
  1746.                     }
  1747.                 }

  1748.                 $count++ if ($state == OK);
  1749.                 $output .= $name . " <" . $operationState . ">; ";
  1750.             }
  1751.             $np->add_perfdata(label => "LUNs", value => $count, uom => 'units', threshold => $np->threshold);
  1752.             $state = $np->check_threshold(check => $count);
  1753.             $res = $state if ($state != OK);
  1754.         }
  1755.         elsif ($subcommand eq "PATH")
  1756.         {
  1757.             if (exists($storage->storageDeviceInfo->{multipathInfo}))
  1758.             {
  1759.                 $output = "";
  1760.                 $res = OK;
  1761.                 foreach my $lun (@{$storage->storageDeviceInfo->multipathInfo->lun})
  1762.                 {
  1763.                     foreach my $path (@{$lun->path})
  1764.                     {
  1765.                         my $status = UNKNOWN; # For unknown or other statuses
  1766.                         my $pathState = "unknown";
  1767.                         my $name = $path->name;

  1768.                         if (exists($path->{state}))
  1769.                         {
  1770.                             $pathState = $path->state;
  1771.                         }
  1772.                         else
  1773.                         {
  1774.                             $pathState = $path->pathState;
  1775.                         }

  1776.                         if (defined($blacklist) && ($blacklist =~ m/(^|\s|\t|,)\Q$name\E($|\s|\t|,)/))
  1777.                         {
  1778.                             $pathState = "ignored";
  1779.                             $count++;
  1780.                         }

  1781.                         $count++ if (uc($pathState) eq "ACTIVE");
  1782.                         $res = UNKNOWN if (uc($pathState) eq "UNKNOWN");
  1783.                         $output .= $name . " <" . $pathState . ">; ";
  1784.                     }
  1785.                 }
  1786.                 $np->add_perfdata(label => "paths", value => $count, uom => 'units', threshold => $np->threshold);
  1787.                 my $state = $np->check_threshold(check => $count);
  1788.                 $res = $state if ($state != OK);
  1789.             }
  1790.             else
  1791.             {
  1792.                 $output = "path info is unavailable on this host";
  1793.                 $res = UNKNOWN;
  1794.             }
  1795.         }
  1796.         else
  1797.         {
  1798.             $res = CRITICAL;
  1799.             $output = "HOST STORAGE - unknown subcommand\n" . $np->opts->_help;
  1800.         }
  1801.     }
  1802.     else
  1803.     {
  1804.         my $status = UNKNOWN;
  1805.         my $state = OK;
  1806.         $output = "";
  1807.         $res = OK;
  1808.         foreach my $dev (@{$storage->storageDeviceInfo->hostBusAdapter})
  1809.         {
  1810.             $status = UNKNOWN;
  1811.             if (uc($dev->status) eq "ONLINE")
  1812.             {
  1813.                 $status = OK;
  1814.                 $count++;
  1815.             }
  1816.             elsif (uc($dev->status) eq "OFFLINE")
  1817.             {
  1818.                 $status = CRITICAL;
  1819.             }
  1820.             elsif (uc($dev->status) eq "FAULT")
  1821.             {
  1822.                 $status = CRITICAL;
  1823.             }
  1824.             else
  1825.             {
  1826.                 $res = UNKNOWN;
  1827.             }
  1828.             $state = Nagios::Plugin::Functions::max_state($state, $status);
  1829.         }
  1830.         $np->add_perfdata(label => "adapters", value => $count, uom => 'units', threshold => $np->threshold);
  1831.         $output .= $count . "/" . @{$storage->storageDeviceInfo->hostBusAdapter} . " adapters online, ";

  1832.         $count = 0;
  1833.         foreach my $scsi (@{$storage->storageDeviceInfo->scsiLun})
  1834.         {
  1835.             $status = UNKNOWN;
  1836.             foreach (@{$scsi->operationalState})
  1837.             {
  1838.                 if (uc($_) eq "OK")
  1839.                 {
  1840.                     $status = OK;
  1841.                     $count++;
  1842.                 }
  1843.                 elsif (uc($_) eq "ERROR")
  1844.                 {
  1845.                     $status = CRITICAL;
  1846.                 }
  1847.                 elsif (uc($_) eq "UNKNOWNSTATE")
  1848.                 {
  1849.                     $status = UNKNOWN;
  1850.                 }
  1851.                 elsif (uc($_) eq "OFF")
  1852.                 {
  1853.                     $status = CRITICAL;
  1854.                 }
  1855.                 elsif (uc($_) eq "QUIESCED")
  1856.                 {
  1857.                     $status = WARNING;
  1858.                 }
  1859.                 elsif (uc($_) eq "DEGRADED")
  1860.                 {
  1861.                     $status = WARNING;
  1862.                 }
  1863.                 elsif (uc($_) eq "LOSTCOMMUNICATION")
  1864.                 {
  1865.                     $status = CRITICAL;
  1866.                 }
  1867.                 else
  1868.                 {
  1869.                     $res = UNKNOWN;
  1870.                     $status = UNKNOWN;
  1871.                 }
  1872.                 $state = Nagios::Plugin::Functions::max_state($state, $status);
  1873.             }
  1874.         }
  1875.         $np->add_perfdata(label => "LUNs", value => $count, uom => 'units', threshold => $np->threshold);
  1876.         $output .= $count . "/" . @{$storage->storageDeviceInfo->scsiLun} . " LUNs ok, ";

  1877.         if (exists($storage->storageDeviceInfo->{multipathInfo}))
  1878.         {
  1879.             $count = 0;
  1880.             my $amount = 0;
  1881.             foreach my $lun (@{$storage->storageDeviceInfo->multipathInfo->lun})
  1882.             {
  1883.                 foreach my $path (@{$lun->path})
  1884.                 {
  1885.                     my $status = UNKNOWN; # For unkonwn or other statuses
  1886.                     my $pathState = "unknown";
  1887.                     if (exists($path->{state}))
  1888.                     {
  1889.                         $pathState = $path->state;
  1890.                     }
  1891.                     else
  1892.                     {
  1893.                         $pathState = $path->pathState;
  1894.                     }

  1895.                     $status = UNKNOWN;
  1896.                     if (uc($pathState) eq "ACTIVE")
  1897.                     {
  1898.                         $status = OK;
  1899.                         $count++;
  1900.                     }
  1901.                     elsif (uc($pathState) eq "DISABLED")
  1902.                     {
  1903.                         $status = WARNING;
  1904.                     }
  1905.                     elsif (uc($pathState) eq "STANDBY")
  1906.                     {
  1907.                         $status = WARNING;
  1908.                     }
  1909.                     elsif (uc($pathState) eq "DEAD")
  1910.                     {
  1911.                         $status = CRITICAL;
  1912.                     }
  1913.                     else
  1914.                     {
  1915.                         $res = UNKNOWN;
  1916.                         $status = UNKNOWN;
  1917.                     }
  1918.                     $state = Nagios::Plugin::Functions::max_state($state, $status);
  1919.                     $amount++;
  1920.                 }
  1921.             }
  1922.             $np->add_perfdata(label => "paths", value => $count, uom => 'units', threshold => $np->threshold);
  1923.             $output .= $count . "/" . $amount . " paths active";
  1924.         }
  1925.         else
  1926.         {
  1927.             $output .= "no path info";
  1928.         }

  1929.         $res = $state if ($state != OK);
  1930.     }

  1931.     return ($res, $output);
  1932. }
  1933. #==========================================================================| VM |============================================================================#

  1934. sub vm_cpu_info
  1935. {
  1936.     my ($vmname, $np, $subcommand) = @_;

  1937.     my $res = CRITICAL;
  1938.     my $output = 'HOST-VM CPU Unknown error';

  1939.     if (defined($subcommand))
  1940.     {
  1941.         if ($subcommand eq "USAGE")
  1942.         {
  1943.             $values = return_host_vmware_performance_values($vmname, 'cpu', ('usage.average'));
  1944.             if (defined($values))
  1945.             {
  1946.                 my $value = simplify_number(convert_number($$values[0][0]->value) * 0.01);
  1947.                 $np->add_perfdata(label => "cpu_usage", value => $value, uom => '%', threshold => $np->threshold);
  1948.                 $output = "\"$vmname\" cpu usage=" . $value . " %";
  1949.                 $res = $np->check_threshold(check => $value);
  1950.             }
  1951.         }
  1952.         elsif ($subcommand eq "USAGEMHZ")
  1953.         {
  1954.             $values = return_host_vmware_performance_values($vmname, 'cpu', ('usagemhz.average'));
  1955.             if (defined($values))
  1956.             {
  1957.                 my $value = simplify_number(convert_number($$values[0][0]->value));
  1958.                 $np->add_perfdata(label => "cpu_usagemhz", value => $value, uom => 'Mhz', threshold => $np->threshold);
  1959.                 $output = "\"$vmname\" cpu usage=" . $value . " MHz";
  1960.                 $res = $np->check_threshold(check => $value);
  1961.             }
  1962.         }
  1963.         elsif ($subcommand eq "WAIT")
  1964.         {
  1965.             $values = return_host_vmware_performance_values($vmname, 'cpu', ('wait.summation:*'));
  1966.             if (defined($values))
  1967.             {
  1968.                 my $value = simplify_number(convert_number($$values[0][0]->value));
  1969.                 $np->add_perfdata(label => "cpu_wait", value => $value, uom => 'ms', threshold => $np->threshold);
  1970.                 $output = "\"$vmname\" cpu wait=" . $value . " ms";
  1971.                 $res = $np->check_threshold(check => $value);
  1972.             }
  1973.         }
  1974.         elsif ($subcommand eq "READY")
  1975.         {
  1976.             $values = return_host_vmware_performance_values($vmname, 'cpu', ('ready.summation:*'));
  1977.             if (defined($values))
  1978.             {
  1979.                 my $value = simplify_number(convert_number($$values[0][0]->value));
  1980.                 $np->add_perfdata(label => "cpu_ready", value => $value, uom => 'ms', threshold => $np->threshold);
  1981.                 $output = "\"$vmname\" cpu ready=" . $value . " ms";
  1982.                 $res = $np->check_threshold(check => $value);
  1983.             }
  1984.         }
  1985.         else
  1986.         {
  1987.             $res = CRITICAL;
  1988.             $output = "HOST-VM CPU - unknown subcommand\n" . $np->opts->_help;
  1989.         }
  1990.     }
  1991.     else
  1992.     {
  1993.         $values = return_host_vmware_performance_values($vmname, 'cpu', ('usagemhz.average', 'usage.average', 'wait.summation:*', 'ready.summation:*'));
  1994.         if (defined($values))
  1995.         {
  1996.             my $value1 = simplify_number(convert_number($$values[0][0]->value));
  1997.             my $value2 = simplify_number(convert_number($$values[0][1]->value) * 0.01);
  1998.             my $value3 = simplify_number(convert_number($$values[0][2]->value));
  1999.             my $value4 = simplify_number(convert_number($$values[0][3]->value));
  2000.             $np->add_perfdata(label => "cpu_usagemhz", value => $value1, uom => 'Mhz', threshold => $np->threshold);
  2001.             $np->add_perfdata(label => "cpu_usage", value => $value2, uom => '%', threshold => $np->threshold);
  2002.             $np->add_perfdata(label => "cpu_wait", value => $value3, uom => 'ms', threshold => $np->threshold);
  2003.             $np->add_perfdata(label => "cpu_ready", value => $value4, uom => 'ms', threshold => $np->threshold);
  2004.             $res = OK;
  2005.             $output = "\"$vmname\" cpu usage=" . $value1 . " MHz(" . $value2 . "%), wait=" . $value3 . " ms, ready=" . $value4 . " ms";
  2006.         }
  2007.     }

  2008.     return ($res, $output);
  2009. }

  2010. sub vm_mem_info
  2011. {
  2012.     my ($vmname, $np, $subcommand) = @_;

  2013.     my $res = CRITICAL;
  2014.     my $output = 'HOST-VM MEM Unknown error';

  2015.     if (defined($subcommand))
  2016.     {
  2017.         if ($subcommand eq "USAGE")
  2018.         {
  2019.             $values = return_host_vmware_performance_values($vmname, 'mem', ('usage.average'));
  2020.             if (defined($values))
  2021.             {
  2022.                 my $value = simplify_number(convert_number($$values[0][0]->value) * 0.01);
  2023.                 $np->add_perfdata(label => "mem_usage", value => $value, uom => '%', threshold => $np->threshold);
  2024.                 $output = "\"$vmname\" mem usage=" . $value . " %";
  2025.                 $res = $np->check_threshold(check => $value);
  2026.             }
  2027.         }
  2028.         elsif ($subcommand eq "USAGEMB")
  2029.         {
  2030.             $values = return_host_vmware_performance_values($vmname, 'mem', ('consumed.average'));
  2031.             if (defined($values))
  2032.             {
  2033.                 my $value = simplify_number(convert_number($$values[0][0]->value) / 1024);
  2034.                 $np->add_perfdata(label => "mem_usagemb", value => $value, uom => 'MB', threshold => $np->threshold);
  2035.                 $output = "\"$vmname\" mem usage=" . $value . " MB";
  2036.                 $res = $np->check_threshold(check => $value);
  2037.             }
  2038.         }
  2039.         elsif ($subcommand eq "SWAP")
  2040.         {
  2041.             $values = return_host_vmware_performance_values($vmname, 'mem', ('swapped.average'));
  2042.             if (defined($values))
  2043.             {
  2044.                 my $value = simplify_number(convert_number($$values[0][0]->value) / 1024);
  2045.                 $np->add_perfdata(label => "mem_swap", value => $value, uom => 'MB', threshold => $np->threshold);
  2046.                 $output = "\"$vmname\" swap usage=" . $value . " MB";
  2047.                 $res = $np->check_threshold(check => $value);
  2048.             }
  2049.         }
  2050.         elsif ($subcommand eq "SWAPIN")
  2051.         {
  2052.             $values = return_host_vmware_performance_values($vmname, 'mem', ('swapin.average'));
  2053.             if (defined($values))
  2054.             {
  2055.                 my $value = simplify_number(convert_number($$values[0][0]->value) / 1024);
  2056.                 $np->add_perfdata(label => "mem_swapin", value => $value, uom => 'MB', threshold => $np->threshold);
  2057.                 $output = "\"$vmname\" swapin=" . $value . " MB";
  2058.                 $res = $np->check_threshold(check => $value);
  2059.             }
  2060.         }
  2061.         elsif ($subcommand eq "SWAPOUT")
  2062.         {
  2063.             $values = return_host_vmware_performance_values($vmname, 'mem', ('swapout.average'));
  2064.             if (defined($values))
  2065.             {
  2066.                 my $value = simplify_number(convert_number($$values[0][0]->value) / 1024);
  2067.                 $np->add_perfdata(label => "mem_swapout", value => $value, uom => 'MB', threshold => $np->threshold);
  2068.                 $output = "\"$vmname\" swapout=" . $value . " MB";
  2069.                 $res = $np->check_threshold(check => $value);
  2070.             }
  2071.         }
  2072.         elsif ($subcommand eq "OVERHEAD")
  2073.         {
  2074.             $values = return_host_vmware_performance_values($vmname, 'mem', ('overhead.average'));
  2075.             if (defined($values))
  2076.             {
  2077.                 my $value = simplify_number(convert_number($$values[0][0]->value) / 1024);
  2078.                 $np->add_perfdata(label => "mem_overhead", value => $value, uom => 'MB', threshold => $np->threshold);
  2079.                 $output = "\"$vmname\" mem overhead=" . $value . " MB";
  2080.                 $res = $np->check_threshold(check => $value);
  2081.             }
  2082.         }
  2083.         elsif ($subcommand eq "OVERALL")
  2084.         {
  2085.             $values = return_host_vmware_performance_values($vmname, 'mem', ('consumed.average', 'overhead.average'));
  2086.             if (defined($values))
  2087.             {
  2088.                 my $value = simplify_number((convert_number($$values[0][0]->value) + convert_number($$values[0][1]->value)) / 1024);
  2089.                 $np->add_perfdata(label => "mem_overall", value => $value, uom => 'MB', threshold => $np->threshold);
  2090.                 $output = "\"$vmname\" mem overall=" . $value . " MB";
  2091.                 $res = $np->check_threshold(check => $value);
  2092.             }
  2093.         }
  2094.         elsif ($subcommand eq "ACTIVE")
  2095.         {
  2096.             $values = return_host_vmware_performance_values($vmname, 'mem', ('active.average'));
  2097.             if (defined($values))
  2098.             {
  2099.                 my $value = simplify_number(convert_number($$values[0][0]->value) / 1024);
  2100.                 $np->add_perfdata(label => "mem_active", value => $value, uom => 'MB', threshold => $np->threshold);
  2101.                 $output = "\"$vmname\" mem active=" . $value . " MB";
  2102.                 $res = $np->check_threshold(check => $value);
  2103.             }
  2104.         }
  2105.         elsif ($subcommand eq "MEMCTL")
  2106.         {
  2107.             $values = return_host_vmware_performance_values($vmname, 'mem', ('vmmemctl.average'));
  2108.             if (defined($values))
  2109.             {
  2110.                 my $value = simplify_number(convert_number($$values[0][0]->value) / 1024);
  2111.                 $np->add_perfdata(label => "mem_memctl", value => $value, uom => 'MB', threshold => $np->threshold);
  2112.                 $output = "\"$vmname\" mem memctl=" . $value . " MB";
  2113.                 $res = $np->check_threshold(check => $value);
  2114.             }
  2115.         }
  2116.         else
  2117.         {
  2118.             $res = CRITICAL;
  2119.             $output = "HOST-VM MEM - unknown subcommand\n" . $np->opts->_help;
  2120.         }
  2121.     }
  2122.     else
  2123.     {
  2124.         $values = return_host_vmware_performance_values($vmname, 'mem', ('consumed.average', 'usage.average', 'overhead.average', 'active.average', 'swapped.average', 'swapin.average', 'swapout.average', 'vmmemctl.average'));
  2125.         if (defined($values))
  2126.         {
  2127.             my $value1 = simplify_number(convert_number($$values[0][0]->value) / 1024);
  2128.             my $value2 = simplify_number(convert_number($$values[0][1]->value) * 0.01);
  2129.             my $value3 = simplify_number(convert_number($$values[0][2]->value) / 1024);
  2130.             my $value4 = simplify_number(convert_number($$values[0][3]->value) / 1024);
  2131.             my $value5 = simplify_number(convert_number($$values[0][4]->value) / 1024);
  2132.             my $value6 = simplify_number(convert_number($$values[0][5]->value) / 1024);
  2133.             my $value7 = simplify_number(convert_number($$values[0][6]->value) / 1024);
  2134.             my $value8 = simplify_number(convert_number($$values[0][7]->value) / 1024);
  2135.             $np->add_perfdata(label => "mem_usagemb", value => $value1, uom => 'MB', threshold => $np->threshold);
  2136.             $np->add_perfdata(label => "mem_usage", value => $value2, uom => '%', threshold => $np->threshold);
  2137.             $np->add_perfdata(label => "mem_overhead", value => $value3, uom => 'MB', threshold => $np->threshold);
  2138.             $np->add_perfdata(label => "mem_active", value => $value4, uom => 'MB', threshold => $np->threshold);
  2139.             $np->add_perfdata(label => "mem_swap", value => $value5, uom => 'MB', threshold => $np->threshold);
  2140.             $np->add_perfdata(label => "mem_swapin", value => $value6, uom => 'MB', threshold => $np->threshold);
  2141.             $np->add_perfdata(label => "mem_swapout", value => $value7, uom => 'MB', threshold => $np->threshold);
  2142.             $np->add_perfdata(label => "mem_memctl", value => $value8, uom => 'MB', threshold => $np->threshold);
  2143.             $res = OK;
  2144.             $output = "\"$vmname\" mem usage=" . $value1 . " MB(" . $value2 . "%), overhead=" . $value3 . " MB, active=" . $value4 . " MB, swapped=" . $value5 . " MB, swapin=" . $value6 . " MB, swapout=" . $value7 . " MB, memctl=" . $value8 . " MB";
  2145.         }
  2146.     }

  2147.     return ($res, $output);
  2148. }

  2149. sub vm_net_info
  2150. {
  2151.     my ($vmname, $np, $subcommand) = @_;

  2152.     my $res = CRITICAL;
  2153.     my $output = 'HOST-VM NET Unknown error';

  2154.     if (defined($subcommand))
  2155.     {
  2156.         if ($subcommand eq "USAGE")
  2157.         {
  2158.             $values = return_host_vmware_performance_values($vmname, 'net', ('usage.average:*'));
  2159.             if (defined($values))
  2160.             {
  2161.                 my $value = simplify_number(convert_number($$values[0][0]->value));
  2162.                 $np->add_perfdata(label => "net_usage", value => $value, uom => 'KBps', threshold => $np->threshold);
  2163.                 $output = "\"$vmname\" net usage=" . $value . " KBps";
  2164.                 $res = $np->check_threshold(check => $value);
  2165.             }
  2166.         }
  2167.         elsif ($subcommand eq "RECEIVE")
  2168.         {
  2169.             $values = return_host_vmware_performance_values($vmname, 'net', ('received.average:*'));
  2170.             if (defined($values))
  2171.             {
  2172.                 my $value = simplify_number(convert_number($$values[0][0]->value));
  2173.                 $np->add_perfdata(label => "net_receive", value => $value, uom => 'KBps', threshold => $np->threshold);
  2174.                 $output = "\"$vmname\" net receive=" . $value . " KBps";
  2175.                 $res = $np->check_threshold(check => $value);
  2176.             }
  2177.         }
  2178.         elsif ($subcommand eq "SEND")
  2179.         {
  2180.             $values = return_host_vmware_performance_values($vmname, 'net', ('transmitted.average:*'));
  2181.             if (defined($values))
  2182.             {
  2183.                 my $value = simplify_number(convert_number($$values[0][0]->value));
  2184.                 $np->add_perfdata(label => "net_send", value => $value, uom => 'KBps', threshold => $np->threshold);
  2185.                 $output = "\"$vmname\" net send=" . $value . " KBps";
  2186.                 $res = $np->check_threshold(check => $value);
  2187.             }
  2188.         }
  2189.         else
  2190.         {
  2191.             $res = CRITICAL;
  2192.             $output = "HOST-VM NET - unknown subcommand\n" . $np->opts->_help;
  2193.         }
  2194.     }
  2195.     else
  2196.     {
  2197.         $values = return_host_vmware_performance_values($vmname, 'net', ('received.average:*', 'transmitted.average:*'));
  2198.         if (defined($values))
  2199.         {
  2200.             my $value1 = simplify_number(convert_number($$values[0][0]->value));
  2201.             my $value2 = simplify_number(convert_number($$values[0][1]->value));
  2202.             $np->add_perfdata(label => "net_receive", value => $value1, uom => 'KBps', threshold => $np->threshold);
  2203.             $np->add_perfdata(label => "net_send", value => $value2, uom => 'KBps', threshold => $np->threshold);
  2204.             $res = OK;
  2205.             $output = "\"$vmname\" net receive=" . $value1 . " KBps, send=" . $value2 . " KBps";
  2206.         }
  2207.     }

  2208.     return ($res, $output);
  2209. }

  2210. sub vm_disk_io_info
  2211. {
  2212.     my ($vmname, $np, $subcommand) = @_;

  2213.     my $res = CRITICAL;
  2214.     my $output = 'HOST-VM IO Unknown error';

  2215.     if (defined($subcommand))
  2216.     {
  2217.         if ($subcommand eq "USAGE")
  2218.         {
  2219.             $values = return_host_vmware_performance_values($vmname, 'disk', ('usage.average:*'));
  2220.             if (defined($values))
  2221.             {
  2222.                 my $value = simplify_number(convert_number($$values[0][0]->value) / 1024);
  2223.                 $np->add_perfdata(label => "io_usage", value => $value, uom => 'MB', threshold => $np->threshold);
  2224.                 $output = "\"$vmname\" io usage=" . $value . " MB";
  2225.                 $res = $np->check_threshold(check => $value);
  2226.             }
  2227.         }
  2228.         elsif ($subcommand eq "READ")
  2229.         {
  2230.             $values = return_host_vmware_performance_values($vmname, 'disk', ('read.average:*'));
  2231.             if (defined($values))
  2232.             {
  2233.                 my $value = simplify_number(convert_number($$values[0][0]->value) / 1024);
  2234.                 $np->add_perfdata(label => "io_read", value => $value, uom => 'MB/s', threshold => $np->threshold);
  2235.                 $output = "\"$vmname\" io read=" . $value . " MB/s";
  2236.                 $res = $np->check_threshold(check => $value);
  2237.             }
  2238.         }
  2239.         elsif ($subcommand eq "WRITE")
  2240.         {
  2241.             $values = return_host_vmware_performance_values($vmname, 'disk', ('write.average:*'));
  2242.             if (defined($values))
  2243.             {
  2244.                 my $value = simplify_number(convert_number($$values[0][0]->value) / 1024);
  2245.                 $np->add_perfdata(label => "io_write", value => $value, uom => 'MB/s', threshold => $np->threshold);
  2246.                 $output = "\"$vmname\" io write=" . $value . " MB/s";
  2247.                 $res = $np->check_threshold(check => $value);
  2248.             }
  2249.         }
  2250.         else
  2251.         {
  2252.             $res = CRITICAL;
  2253.             $output = "HOST IO - unknown subcommand\n" . $np->opts->_help;
  2254.         }
  2255.     }
  2256.     else
  2257.     {
  2258.         $values = return_host_vmware_performance_values($vmname, 'disk', ('usage.average:*', 'read.average:*', 'write.average:*'));
  2259.         if (defined($values))
  2260.         {
  2261.             my $value1 = simplify_number(convert_number($$values[0][0]->value) / 1024);
  2262.             my $value2 = simplify_number(convert_number($$values[0][1]->value) / 1024);
  2263.             my $value3 = simplify_number(convert_number($$values[0][2]->value) / 1024);
  2264.             $np->add_perfdata(label => "io_usage", value => $value1, uom => 'MB', threshold => $np->threshold);
  2265.             $np->add_perfdata(label => "io_read", value => $value2, uom => 'MB/s', threshold => $np->threshold);
  2266.             $np->add_perfdata(label => "io_write", value => $value3, uom => 'MB/s', threshold => $np->threshold);
  2267.             $res = OK;
  2268.             $output = "\"$vmname\" io usage=" . $value1 . " MB, read=" . $value2 . " MB/s, write=" . $value3 . " MB/s";
  2269.         }
  2270.     }

  2271.     return ($res, $output);
  2272. }

  2273. sub vm_runtime_info
  2274. {
  2275.     my ($vmname, $np, $subcommand) = @_;

  2276.     my $res = CRITICAL;
  2277.     my $output = 'HOST-VM RUNTIME Unknown error';
  2278.     my $runtime;
  2279.     my $vm_view = Vim::find_entity_view(view_type => 'VirtualMachine', filter => {name => $vmname}, properties => ['name', 'runtime', 'overallStatus', 'guest', 'configIssue']);
  2280.     die "VMware machine \"" . $vmname . "\" does not exist\n" if (!defined($vm_view));
  2281.     $runtime = $vm_view->runtime;

  2282.     if (defined($subcommand))
  2283.     {
  2284.         if ($subcommand eq "CON")
  2285.         {
  2286.             $output = "\"$vmname\" connection state=" . $runtime->connectionState->val;
  2287.             $res = OK if ($runtime->connectionState->val eq "connected");
  2288.         }
  2289.         elsif ($subcommand eq "CPU")
  2290.         {
  2291.             $output = "\"$vmname\" max cpu=" . $runtime->maxCpuUsage . " MHz";
  2292.             $res = OK;
  2293.         }
  2294.         elsif ($subcommand eq "MEM")
  2295.         {
  2296.             $output = "\"$vmname\" max mem=" . $runtime->maxMemoryUsage . " MB";
  2297.             $res = OK;
  2298.         }
  2299.         elsif ($subcommand eq "STATE")
  2300.         {
  2301.             my %vm_state_strings = ("poweredOn" => "UP", "poweredOff" => "DOWN", "suspended" => "SUSPENDED");
  2302.             my $state = $vm_state_strings{$runtime->powerState->val};
  2303.             $output = "\"$vmname\" run state=" . $state;
  2304.             $res = OK if ($state eq "UP");
  2305.         }
  2306.         elsif ($subcommand eq "STATUS")
  2307.         {
  2308.             my $status = $vm_view->overallStatus->val;
  2309.             $output = "\"$vmname\" overall status=" . $status;
  2310.             $res = check_health_state($status);
  2311.         }
  2312.         elsif ($subcommand eq "CONSOLECONNECTIONS")
  2313.         {
  2314.             $output = "\"$vmname\" console connections=" . $runtime->numMksConnections;
  2315.             $res = $np->check_threshold(check => $runtime->numMksConnections);
  2316.         }
  2317.         elsif ($subcommand eq "GUEST")
  2318.         {
  2319.             my %vm_guest_state = ("running" => "Running", "notRunning" => "Not running", "shuttingDown" => "Shutting down", "resetting" => "Resetting", "standby" => "Standby", "unknown" => "Unknown");
  2320.             my $state = $vm_guest_state{$vm_view->guest->guestState};
  2321.             $output = "\"$vmname\" guest state=" . $state;
  2322.             $res = OK if ($state eq "Running");
  2323.         }
  2324.         elsif ($subcommand eq "TOOLS")
  2325.         {
  2326.             my $tools_status;
  2327.             my $tools_runstate;
  2328.             my $tools_version;
  2329.             $tools_runstate = $vm_view->guest->toolsRunningStatus if (exists($vm_view->guest->{toolsRunningStatus}) && defined($vm_view->guest->toolsRunningStatus));
  2330.             $tools_version = $vm_view->guest->toolsVersionStatus if (exists($vm_view->guest->{toolsVersionStatus}) && defined($vm_view->guest->toolsVersionStatus));

  2331.             if (defined($tools_runstate) || defined($tools_version))
  2332.             {
  2333.                 my %vm_tools_strings = ("guestToolsCurrent" => "Newest", "guestToolsNeedUpgrade" => "Old", "guestToolsNotInstalled" => "Not installed", "guestToolsUnmanaged" => "Unmanaged", "guestToolsExecutingScripts" => "Starting", "guestToolsNotRunning" => "Not running", "guestToolsRunning" => "Running");
  2334.                 $tools_status = $vm_tools_strings{$tools_runstate} . "-" if (defined($tools_runstate));
  2335.                 $tools_status .= $vm_tools_strings{$tools_version} . "-" if (defined($tools_version));
  2336.                 chop($tools_status);
  2337.                 $res = OK if (($tools_status eq "Running-Newest") || ($tools_status eq "Running-Unmanaged"));
  2338.             }
  2339.             else
  2340.             {
  2341.                 my %vm_tools_strings = ("toolsNotInstalled" => "Not installed", "toolsNotRunning" => "Not running", "toolsOk" => "OK", "toolsOld" => "Old", "notDefined" => "Not defined");
  2342.                 $tools_status = $vm_view->guest->toolsStatus;
  2343.                 if (defined($tools_status))
  2344.                 {
  2345.                     $tools_status = $vm_tools_strings{$tools_status->val};
  2346.                 }
  2347.                 else
  2348.                 {
  2349.                     $tools_status = $vm_tools_strings{"notDefined"};
  2350.                 }
  2351.                 $res = OK if ($tools_status eq "OK");
  2352.             }
  2353.             $output = "\"$vmname\" tools status=" . $tools_status;
  2354.         }
  2355.         elsif ($subcommand eq "ISSUES")
  2356.         {
  2357.             my $issues = $vm_view->configIssue;

  2358.             if (defined($issues))
  2359.             {
  2360.                 $output = "\"$vmname\": ";
  2361.                 foreach (@$issues)
  2362.                 {
  2363.                     $output .= $_->fullFormattedMessage . "(caused by " . $_->userName . "); ";
  2364.                 }
  2365.             }
  2366.             else
  2367.             {
  2368.                 $res = OK;
  2369.                 $output = "\"$vmname\" has no config issues";
  2370.             }
  2371.         }
  2372.         else
  2373.         {
  2374.             $res = CRITICAL;
  2375.             $output = "HOST-VM RUNTIME - unknown subcommand\n" . $np->opts->_help;
  2376.         }
  2377.     }
  2378.     else
  2379.     {
  2380.         my %vm_state_strings = ("poweredOn" => "UP", "poweredOff" => "DOWN", "suspended" => "SUSPENDED");
  2381.         my %vm_tools_status = ("toolsNotInstalled" => "Not installed", "toolsNotRunning" => "Not running", "toolsOk" => "OK", "toolsOld" => "Old");
  2382.         my %vm_guest_state = ("running" => "Running", "notRunning" => "Not running", "shuttingDown" => "Shutting down", "resetting" => "Resetting", "standby" => "Standby", "unknown" => "Unknown");
  2383.         $res = OK;
  2384.         $output = "\"$vmname\" status=" . $vm_view->overallStatus->val . ", run state=" . $vm_state_strings{$runtime->powerState->val} . ", guest state=" . $vm_guest_state{$vm_view->guest->guestState} . ", max cpu=" . $runtime->maxCpuUsage . " MHz, max mem=" . $runtime->maxMemoryUsage . " MB, console connections=" . $runtime->numMksConnections . ", tools status=" . $vm_tools_status{$vm_view->guest->toolsStatus->val} . ", ";
  2385.         my $issues = $vm_view->configIssue;
  2386.         if (defined($issues))
  2387.         {
  2388.             $output .= @$issues . " config issue(s)";
  2389.         }
  2390.         else
  2391.         {
  2392.             $output .= "has no config issues";
  2393.         }
  2394.     }

  2395.     return ($res, $output);
  2396. }

  2397. #==========================================================================| DC |============================================================================#

  2398. sub return_cluster_DRS_recommendations {
  2399.     my ($np, $cluster_name) = @_;
  2400.     my $res = OK;
  2401.     my $output;
  2402.     my @clusters;

  2403.     if (defined($cluster_name))
  2404.     {
  2405.         my $cluster = Vim::find_entity_view(view_type => 'ClusterComputeResource', filter => $cluster_name, properties => ['name', 'recommendation']);
  2406.         die "cluster \"" . $$cluster_name{"name"} . "\" does not exist\n" if (!defined($cluster));
  2407.         push(@clusters, $cluster);
  2408.     }
  2409.     else
  2410.     {
  2411.         my $cluster = Vim::find_entity_views(view_type => 'ClusterComputeResource', properties => ['name', 'recommendation']);
  2412.         die "Runtime error\n" if (!defined($cluster));
  2413.         die "There are no clusters\n" if (!@$cluster);
  2414.         @clusters = @$cluster;
  2415.     }

  2416.     my $rec_count = 0;
  2417.     foreach my $cluster_view (@clusters)
  2418.     {
  2419.         my ($recommends) = $cluster_view->recommendation;
  2420.         if (defined($recommends))
  2421.         {
  2422.             my $value = 0;
  2423.             foreach my $recommend (@$recommends)
  2424.             {
  2425.                 $value = $recommend->rating if ($recommend->rating > $value);
  2426.                 $output .= "(" . $recommend->rating . ") " . $recommend->reason . " : " . $recommend->reasonText . "; ";
  2427.             }
  2428.             $rec_count += @$recommends;
  2429.             $res = $np->check_threshold(check => $value);
  2430.         }
  2431.     }

  2432.     if (defined($output))
  2433.     {
  2434.         $output = "Recommendations:" . $output;
  2435.     }
  2436.     else
  2437.     {
  2438.         $output = "No recommendations";
  2439.     }

  2440.     $np->add_perfdata(label => "recommendations", value => $rec_count);

  2441.     return ($res, $output);
  2442. }

  2443. sub dc_cpu_info
  2444. {
  2445.     my ($np, $subcommand, $addopts) = @_;

  2446.     my $res = CRITICAL;
  2447.     my $output = 'DC CPU Unknown error';

  2448.     my $quickStats;
  2449.     $quickStats = $addopts =~ m/(^|\s|\t|,)\Qquickstats\E($|\s|\t|,)/ if (defined($addopts));

  2450.     if (defined($subcommand))
  2451.     {
  2452.         if ($subcommand eq "USAGE")
  2453.         {
  2454.             my $value;
  2455.             if (defined($quickStats))
  2456.             {
  2457.                 my $host_views = Vim::find_entity_views(view_type => 'HostSystem', properties => ['name', 'summary.hardware', 'summary.quickStats']);
  2458.                 die "Runtime error\n" if (!defined($host_views));
  2459.                 die "Datacenter does not contain any hosts\n" if (!@$host_views);
  2460.                 foreach my $host_view (@$host_views)
  2461.                 {
  2462.                     $values = $host_view->get_property('summary.quickStats');
  2463.                     my $hardinfo = $host_view->get_property('summary.hardware');
  2464.                     die "Can not retrieve required information from Host '" . $host_view->name . "'\n" if !(exists($values->{overallCpuUsage}) && defined($hardinfo));
  2465.                     $value += $values->overallCpuUsage / ($hardinfo->numCpuCores * $hardinfo->cpuMhz) * 100;
  2466.                 }
  2467.                 $value = simplify_number($value / @$host_views);
  2468.             }
  2469.             else
  2470.             {
  2471.                 $values = return_dc_performance_values('cpu', ('usage.average'));
  2472.                 grep($value += convert_number($$_[0]->value) * 0.01, @$values) if (defined($values));
  2473.                 $value = simplify_number($value / @$values) if (defined($value));
  2474.             }
  2475.             if (defined($value))
  2476.             {
  2477.                 $np->add_perfdata(label => "cpu_usage", value => $value, uom => '%', threshold => $np->threshold);
  2478.                 $output = "cpu usage=" . $value . " %";
  2479.                 $res = $np->check_threshold(check => $value);
  2480.             }
  2481.         }
  2482.         elsif ($subcommand eq "USAGEMHZ")
  2483.         {
  2484.             my $value;
  2485.             if (defined($quickStats))
  2486.             {
  2487.                 my $host_views = Vim::find_entity_views(view_type => 'HostSystem', properties => ['name', 'summary.quickStats']);
  2488.                 die "Runtime error\n" if (!defined($host_views));
  2489.                 die "Datacenter does not contain any hosts\n" if (!@$host_views);
  2490.                 foreach my $host_view (@$host_views)
  2491.                 {
  2492.                     $values = $host_view->get_property('summary.quickStats');
  2493.                     die "Can not retrieve required information from Host '" . $host_view->name . "'\n" if !(exists($values->{overallCpuUsage}));
  2494.                     $value += $values->overallCpuUsage;
  2495.                 }
  2496.                 $value = simplify_number($value);
  2497.             }
  2498.             else
  2499.             {
  2500.                 $values = return_dc_performance_values('cpu', ('usagemhz.average'));
  2501.                 grep($value += convert_number($$_[0]->value), @$values);
  2502.                 $value = simplify_number($value) if (defined($value));
  2503.             }
  2504.             if (defined($value))
  2505.             {
  2506.                 $np->add_perfdata(label => "cpu_usagemhz", value => $value, uom => 'Mhz', threshold => $np->threshold);
  2507.                 $output = "cpu usagemhz=" . $value . " MHz";
  2508.                 $res = $np->check_threshold(check => $value);
  2509.             }
  2510.         }
  2511.         else
  2512.         {
  2513.             $res = CRITICAL;
  2514.             $output = "DC CPU - unknown subcommand\n" . $np->opts->_help;
  2515.         }
  2516.     }
  2517.     else
  2518.     {
  2519.         my $value1 = 0;
  2520.         my $value2 = 0;
  2521.         if (defined($quickStats))
  2522.         {
  2523.             my $host_views = Vim::find_entity_views(view_type => 'HostSystem', properties => ['name', 'summary.hardware', 'summary.quickStats']);
  2524.             die "Runtime error\n" if (!defined($host_views));
  2525.             die "Datacenter does not contain any hosts\n" if (!@$host_views);
  2526.             foreach my $host_view (@$host_views)
  2527.             {
  2528.                 $values = $host_view->get_property('summary.quickStats');
  2529.                 my $hardinfo = $host_view->get_property('summary.hardware');
  2530.                 die "Can not retrieve required information from Host '" . $host_view->name . "'\n" if !(exists($values->{overallCpuUsage}) && defined($hardinfo));
  2531.                 $value1 += $values->overallCpuUsage;
  2532.                 $value2 += $values->overallCpuUsage / ($hardinfo->numCpuCores * $hardinfo->cpuMhz) * 100;
  2533.             }
  2534.             $value1 = simplify_number($value1);
  2535.             $value2 = simplify_number($value2 / @$host_views);
  2536.         }
  2537.         else
  2538.         {
  2539.             $values = return_dc_performance_values('cpu', ('usagemhz.average', 'usage.average'));
  2540.             grep($value1 += convert_number($$_[0]->value), @$values);
  2541.             grep($value2 += convert_number($$_[1]->value) * 0.01, @$values);
  2542.             $value1 = simplify_number($value1);
  2543.             $value2 = simplify_number($value2 / @$values);
  2544.         }
  2545.         if (defined($value1) && defined($value2))
  2546.         {
  2547.             $np->add_perfdata(label => "cpu_usagemhz", value => $value1, uom => 'Mhz', threshold => $np->threshold);
  2548.             $np->add_perfdata(label => "cpu_usage", value => $value2, uom => '%', threshold => $np->threshold);
  2549.             $res = OK;
  2550.             $output = "cpu usage=" . $value1 . " MHz (" . $value2 . "%)";
  2551.         }
  2552.     }

  2553.     return ($res, $output);
  2554. }

  2555. sub dc_mem_info
  2556. {
  2557.     my ($np, $subcommand, $addopts) = @_;

  2558.     my $res = CRITICAL;
  2559.     my $output = 'DC MEM Unknown error';

  2560.     my $quickStats;
  2561.     $quickStats = $addopts =~ m/(^|\s|\t|,)\Qquickstats\E($|\s|\t|,)/ if (defined($addopts));

  2562.     if (defined($subcommand))
  2563.     {
  2564.         if ($subcommand eq "USAGE")
  2565.         {
  2566.             my $value;
  2567.             if (defined($quickStats))
  2568.             {
  2569.                 my $host_views = Vim::find_entity_views(view_type => 'HostSystem', properties => ['name', 'summary.hardware', 'summary.quickStats']);
  2570.                 die "Runtime error\n" if (!defined($host_views));
  2571.                 die "Datacenter does not contain any hosts\n" if (!@$host_views);
  2572.                 foreach my $host_view (@$host_views)
  2573.                 {
  2574.                     $values = $host_view->get_property('summary.quickStats');
  2575.                     my $hardinfo = $host_view->get_property('summary.hardware');
  2576.                     die "Can not retrieve required information from Host '" . $host_view->name . "'\n" if !(exists($values->{overallMemoryUsage}) && defined($hardinfo));
  2577.                     $value += $values->overallMemoryUsage / ($hardinfo->memorySize / 1024 / 1024) * 100;
  2578.                 }
  2579.                 $value = simplify_number($value);
  2580.             }
  2581.             else
  2582.             {
  2583.                 $values = return_dc_performance_values('mem', ('usage.average'));
  2584.                 grep($value += convert_number($$_[0]->value) * 0.01, @$values);
  2585.                 $value = simplify_number($value / @$values) if (defined($value));
  2586.             }
  2587.             if (defined($value))
  2588.             {
  2589.                 $np->add_perfdata(label => "mem_usage", value => $value, uom => '%', threshold => $np->threshold);
  2590.                 $output = "mem usage=" . $value . " %";
  2591.                 $res = $np->check_threshold(check => $value);
  2592.             }
  2593.         }
  2594.         elsif ($subcommand eq "USAGEMB")
  2595.         {
  2596.             my $value;
  2597.             if (defined($quickStats))
  2598.             {
  2599.                 my $host_views = Vim::find_entity_views(view_type => 'HostSystem', properties => ['name', 'summary.quickStats']);
  2600.                 die "Runtime error\n" if (!defined($host_views));
  2601.                 die "Datacenter does not contain any hosts\n" if (!@$host_views);
  2602.                 foreach my $host_view (@$host_views)
  2603.                 {
  2604.                     $values = $host_view->get_property('summary.quickStats');
  2605.                     die "Can not retrieve required information from Host '" . $host_view->name . "'\n" if !(exists($values->{overallMemoryUsage}));
  2606.                     $value += $values->overallMemoryUsage;
  2607.                 }
  2608.                 $value = simplify_number($value);
  2609.             }
  2610.             else
  2611.             {
  2612.                 $values = return_dc_performance_values('mem', ('consumed.average'));
  2613.                 grep($value += convert_number($$_[0]->value) / 1024, @$values);
  2614.                 $value = simplify_number($value) if (defined($value));
  2615.             }
  2616.             if (defined($value))
  2617.             {
  2618.                 $np->add_perfdata(label => "mem_usagemb", value => $value, uom => 'MB', threshold => $np->threshold);
  2619.                 $output = "mem usage=" . $value . " MB";
  2620.                 $res = $np->check_threshold(check => $value);
  2621.             }
  2622.         }
  2623.         elsif ($subcommand eq "SWAP")
  2624.         {
  2625.             $values = return_dc_performance_values('mem', ('swapused.average'));
  2626.             if (defined($values))
  2627.             {
  2628.                 my $value = 0;
  2629.                 grep($value += convert_number($$_[0]->value) / 1024, @$values);
  2630.                 $value = simplify_number($value);
  2631.                 $np->add_perfdata(label => "mem_swap", value => $value, uom => 'MB', threshold => $np->threshold);
  2632.                 $output = "swap usage=" . $value . " MB";
  2633.                 $res = $np->check_threshold(check => $value);
  2634.             }
  2635.         }
  2636.         elsif ($subcommand eq "OVERHEAD")
  2637.         {
  2638.             $values = return_dc_performance_values('mem', ('overhead.average'));
  2639.             if (defined($values))
  2640.             {
  2641.                 my $value = 0;
  2642.                 grep($value += convert_number($$_[0]->value) / 1024, @$values);
  2643.                 $value = simplify_number($value);
  2644.                 $np->add_perfdata(label => "mem_overhead", value => $value, uom => 'MB', threshold => $np->threshold);
  2645.                 $output = "overhead=" . $value . " MB";
  2646.                 $res = $np->check_threshold(check => $value);
  2647.             }
  2648.         }
  2649.         elsif ($subcommand eq "OVERALL")
  2650.         {
  2651.             $values = return_dc_performance_values('mem', ('consumed.average', 'overhead.average'));
  2652.             if (defined($values))
  2653.             {
  2654.                 my $value = 0;
  2655.                 grep($value += (convert_number($$_[0]->value) + convert_number($$_[1]->value)) / 1024, @$values);
  2656.                 $value = simplify_number($value);
  2657.                 $np->add_perfdata(label => "mem_overall", value => $value, uom => 'MB', threshold => $np->threshold);
  2658.                 $output = "overall=" . $value . " MB";
  2659.                 $res = $np->check_threshold(check => $value);
  2660.             }
  2661.         }
  2662.         elsif ($subcommand eq "MEMCTL")
  2663.         {
  2664.             $values = return_dc_performance_values('mem', ('vmmemctl.average'));
  2665.             if (defined($values))
  2666.             {
  2667.                 my $value = 0;
  2668.                 grep($value += convert_number($$_[0]->value) / 1024, @$values);
  2669.                 $value = simplify_number($value);
  2670.                 $np->add_perfdata(label => "mem_memctl", value => $value, uom => 'MB', threshold => $np->threshold);
  2671.                 $output = "memctl=" . $value . " MB";
  2672.                 $res = $np->check_threshold(check => $value);
  2673.             }
  2674.         }
  2675.         else
  2676.         {
  2677.             $res = CRITICAL;
  2678.             $output = "DC MEM - unknown subcommand\n" . $np->opts->_help;
  2679.         }
  2680.     }
  2681.     else
  2682.     {
  2683.         $values = return_dc_performance_values('mem', ('consumed.average', 'usage.average', 'overhead.average', 'swapused.average', 'vmmemctl.average'));
  2684.         if (defined($values))
  2685.         {
  2686.             my $value1 = 0;
  2687.             my $value2 = 0;
  2688.             my $value3 = 0;
  2689.             my $value4 = 0;
  2690.             my $value5 = 0;
  2691.             grep($value1 += convert_number($$_[0]->value) / 1024, @$values);
  2692.             grep($value2 += convert_number($$_[1]->value) * 0.01, @$values);
  2693.             grep($value3 += convert_number($$_[2]->value) / 1024, @$values);
  2694.             grep($value4 += convert_number($$_[3]->value) / 1024, @$values);
  2695.             grep($value5 += convert_number($$_[4]->value) / 1024, @$values);
  2696.             $value1 = simplify_number($value1);
  2697.             $value2 = simplify_number($value2 / @$values);
  2698.             $value3 = simplify_number($value3);
  2699.             $value4 = simplify_number($value4);
  2700.             $value5 = simplify_number($value5);
  2701.             $np->add_perfdata(label => "mem_usagemb", value => $value1, uom => 'MB', threshold => $np->threshold);
  2702.             $np->add_perfdata(label => "mem_usage", value => $value2, uom => '%', threshold => $np->threshold);
  2703.             $np->add_perfdata(label => "mem_overhead", value => $value3, uom => 'MB', threshold => $np->threshold);
  2704.             $np->add_perfdata(label => "mem_swap", value => $value4, uom => 'MB', threshold => $np->threshold);
  2705.             $np->add_perfdata(label => "mem_memctl", value => $value5, uom => 'MB', threshold => $np->threshold);
  2706.             $res = OK;
  2707.             $output = "mem usage=" . $value1 . " MB (" . $value2 . "%), overhead=" . $value3 . " MB, swapped=" . $value4 . " MB, memctl=" . $value5 . " MB";
  2708.         }
  2709.     }

  2710.     return ($res, $output);
  2711. }

  2712. sub dc_net_info
  2713. {
  2714.     my ($np, $subcommand) = @_;

  2715.     my $res = CRITICAL;
  2716.     my $output = 'DC NET Unknown error';

  2717.     if (defined($subcommand))
  2718.     {
  2719.         if ($subcommand eq "USAGE")
  2720.         {
  2721.             $values = return_dc_performance_values('net', ('usage.average:*'));
  2722.             if (defined($values))
  2723.             {
  2724.                 my $value = 0;
  2725.                 grep($value += convert_number($$_[0]->value), @$values);
  2726.                 $value = simplify_number($value);
  2727.                 $np->add_perfdata(label => "net_usage", value => $value, uom => 'KBps', threshold => $np->threshold);
  2728.                 $output = "net usage=" . $value . " KBps";
  2729.                 $res = $np->check_threshold(check => $value);
  2730.             }
  2731.         }
  2732.         elsif ($subcommand eq "RECEIVE")
  2733.         {
  2734.             $values = return_dc_performance_values('net', ('received.average:*'));
  2735.             if (defined($values))
  2736.             {
  2737.                 my $value = 0;
  2738.                 grep($value += convert_number($$_[0]->value), @$values);
  2739.                 $value = simplify_number($value);
  2740.                 $np->add_perfdata(label => "net_receive", value => $value, uom => 'KBps', threshold => $np->threshold);
  2741.                 $output = "net receive=" . $value . " KBps";
  2742.                 $res = $np->check_threshold(check => $value);
  2743.             }
  2744.         }
  2745.         elsif ($subcommand eq "SEND")
  2746.         {
  2747.             $values = return_dc_performance_values('net', ('transmitted.average:*'));
  2748.             if (defined($values))
  2749.             {
  2750.                 my $value = 0;
  2751.                 grep($value += convert_number($$_[0]->value), @$values);
  2752.                 $value = simplify_number($value);
  2753.                 $np->add_perfdata(label => "net_send", value => $value, uom => 'KBps', threshold => $np->threshold);
  2754.                 $output = "net send=" . $value . " KBps";
  2755.                 $res = $np->check_threshold(check => $value);
  2756.             }
  2757.         }
  2758.         else
  2759.         {
  2760.             $res = CRITICAL;
  2761.             $output = "DC NET - unknown subcommand\n" . $np->opts->_help;
  2762.         }
  2763.     }
  2764.     else
  2765.     {
  2766.         $values = return_dc_performance_values('net', ('received.average:*', 'transmitted.average:*'));
  2767.         if (defined($values))
  2768.         {
  2769.             my $value1 = 0;
  2770.             my $value2 = 0;
  2771.             grep($value1 += convert_number($$_[0]->value), @$values);
  2772.             grep($value2 += convert_number($$_[1]->value), @$values);
  2773.             $value1 = simplify_number($value1);
  2774.             $value2 = simplify_number($value2);
  2775.             $np->add_perfdata(label => "net_receive", value => $value1, uom => 'KBps', threshold => $np->threshold);
  2776.             $np->add_perfdata(label => "net_send", value => $value2, uom => 'KBps', threshold => $np->threshold);
  2777.             $res = OK;
  2778.             $output = "net receive=" . $value1 . " KBps, send=" . $value2 . " KBps";
  2779.         }
  2780.     }

  2781.     return ($res, $output);
  2782. }

  2783. sub dc_list_vm_volumes_info
  2784. {
  2785.     my ($np, $subcommand, $blacklist, $perc, $addopts) = @_;

  2786.     my $host_views = Vim::find_entity_views(view_type => 'HostSystem', properties => ['name', 'datastore']);
  2787.     die "Runtime error\n" if (!defined($host_views));
  2788.     die "Datacenter does not contain any hosts\n" if (!@$host_views);

  2789.     my @datastores;
  2790.     foreach my $host (@$host_views)
  2791.     {
  2792.         push(@datastores, @{$host->datastore});
  2793.     }
  2794.     return datastore_volumes_info(\@datastores, $np, $subcommand, $blacklist, $perc, $addopts);
  2795. }

  2796. sub dc_disk_io_info
  2797. {
  2798.     my ($np, $subcommand) = @_;

  2799.     my $res = CRITICAL;
  2800.     my $output = 'DC IO Unknown error';

  2801.     if (defined($subcommand))
  2802.     {
  2803.         if ($subcommand eq "ABORTED")
  2804.         {
  2805.             $values = return_dc_performance_values('disk', ('commandsAborted.summation:*'));
  2806.             if (defined($values))
  2807.             {
  2808.                 my $value = 0;
  2809.                 grep($value += convert_number($$_[0]->value), @$values);
  2810.                 $value = simplify_number($value, 0);
  2811.                 $np->add_perfdata(label => "io_aborted", value => $value, threshold => $np->threshold);
  2812.                 $output = "io commands aborted=" . $value;
  2813.                 $res = $np->check_threshold(check => $value);
  2814.             }
  2815.         }
  2816.         elsif ($subcommand eq "RESETS")
  2817.         {
  2818.             $values = return_dc_performance_values('disk', ('busResets.summation:*'));
  2819.             if (defined($values))
  2820.             {
  2821.                 my $value = 0;
  2822.                 grep($value += convert_number($$_[0]->value), @$values);
  2823.                 $value = simplify_number($value, 0);
  2824.                 $np->add_perfdata(label => "io_busresets", value => $value, threshold => $np->threshold);
  2825.                 $output = "io bus resets=" . $value;
  2826.                 $res = $np->check_threshold(check => $value);
  2827.             }
  2828.         }
  2829.         elsif ($subcommand eq "READ")
  2830.         {
  2831.             $values = return_dc_performance_values('disk', ('totalReadLatency.average:*'));
  2832.             if (defined($values))
  2833.             {
  2834.                 my $value = 0;
  2835.                 grep($value += convert_number($$_[0]->value), @$values);
  2836.                 $value = simplify_number($value, 0);
  2837.                 $np->add_perfdata(label => "io_read", value => $value, uom => 'ms', threshold => $np->threshold);
  2838.                 $output = "io read latency=" . $value . " ms";
  2839.                 $res = $np->check_threshold(check => $value);
  2840.             }
  2841.         }
  2842.         elsif ($subcommand eq "WRITE")
  2843.         {
  2844.             $values = return_dc_performance_values('disk', ('totalWriteLatency.average:*'));
  2845.             if (defined($values))
  2846.             {
  2847.                 my $value = 0;
  2848.                 grep($value += convert_number($$_[0]->value), @$values);
  2849.                 $value = simplify_number($value, 0);
  2850.                 $np->add_perfdata(label => "io_write", value => $value, uom => 'ms', threshold => $np->threshold);
  2851.                 $output = "io write latency=" . $value . " ms";
  2852.                 $res = $np->check_threshold(check => $value);
  2853.             }
  2854.         }
  2855.         elsif ($subcommand eq "KERNEL")
  2856.         {
  2857.             $values = return_dc_performance_values('disk', ('kernelLatency.average:*'));
  2858.             if (defined($values))
  2859.             {
  2860.                 my $value = 0;
  2861.                 grep($value += convert_number($$_[0]->value), @$values);
  2862.                 $value = simplify_number($value, 0);
  2863.                 $np->add_perfdata(label => "io_kernel", value => $value, uom => 'ms', threshold => $np->threshold);
  2864.                 $output = "io kernel latency=" . $value . " ms";
  2865.                 $res = $np->check_threshold(check => $value);
  2866.             }
  2867.         }
  2868.         elsif ($subcommand eq "DEVICE")
  2869.         {
  2870.             $values = return_dc_performance_values('disk', ('deviceLatency.average:*'));
  2871.             if (defined($values))
  2872.             {
  2873.                 my $value = 0;
  2874.                 grep($value += convert_number($$_[0]->value), @$values);
  2875.                 $value = simplify_number($value, 0);
  2876.                 $np->add_perfdata(label => "io_device", value => $value, uom => 'ms', threshold => $np->threshold);
  2877.                 $output = "io device latency=" . $value . " ms";
  2878.                 $res = $np->check_threshold(check => $value);
  2879.             }
  2880.         }
  2881.         elsif ($subcommand eq "QUEUE")
  2882.         {
  2883.             $values = return_dc_performance_values('disk', ('queueLatency.average:*'));
  2884.             if (defined($values))
  2885.             {
  2886.                 my $value = 0;
  2887.                 grep($value += convert_number($$_[0]->value), @$values);
  2888.                 $value = simplify_number($value, 0);
  2889.                 $np->add_perfdata(label => "io_queue", value => $value, uom => 'ms', threshold => $np->threshold);
  2890.                 $output = "io queue latency=" . $value . " ms";
  2891.                 $res = $np->check_threshold(check => $value);
  2892.             }
  2893.         }
  2894.         else
  2895.         {
  2896.             $res = CRITICAL;
  2897.             $output = "DC IO - unknown subcommand\n" . $np->opts->_help;
  2898.         }
  2899.     }
  2900.     else
  2901.     {
  2902.         $values = return_dc_performance_values('disk', ('commandsAborted.summation:*', 'busResets.summation:*', 'totalReadLatency.average:*', 'totalWriteLatency.average:*', 'kernelLatency.average:*', 'deviceLatency.average:*', 'queueLatency.average:*'));
  2903.         if (defined($values))
  2904.         {
  2905.             my $value1 = 0;
  2906.             my $value2 = 0;
  2907.             my $value3 = 0;
  2908.             my $value4 = 0;
  2909.             my $value5 = 0;
  2910.             my $value6 = 0;
  2911.             my $value7 = 0;
  2912.             grep($value1 += convert_number($$_[0]->value), @$values);
  2913.             grep($value2 += convert_number($$_[1]->value), @$values);
  2914.             grep($value3 += convert_number($$_[2]->value), @$values);
  2915.             grep($value4 += convert_number($$_[3]->value), @$values);
  2916.             grep($value5 += convert_number($$_[4]->value), @$values);
  2917.             grep($value6 += convert_number($$_[5]->value), @$values);
  2918.             grep($value7 += convert_number($$_[6]->value), @$values);
  2919.             $value1 = simplify_number($value1, 0);
  2920.             $value2 = simplify_number($value2, 0);
  2921.             $value3 = simplify_number($value3, 0);
  2922.             $value4 = simplify_number($value4, 0);
  2923.             $value5 = simplify_number($value5, 0);
  2924.             $value6 = simplify_number($value6, 0);
  2925.             $value7 = simplify_number($value7, 0);
  2926.             $np->add_perfdata(label => "io_aborted", value => $value1, threshold => $np->threshold);
  2927.             $np->add_perfdata(label => "io_busresets", value => $value2, threshold => $np->threshold);
  2928.             $np->add_perfdata(label => "io_read", value => $value3, uom => 'ms', threshold => $np->threshold);
  2929.             $np->add_perfdata(label => "io_write", value => $value4, uom => 'ms', threshold => $np->threshold);
  2930.             $np->add_perfdata(label => "io_kernel", value => $value5, uom => 'ms', threshold => $np->threshold);
  2931.             $np->add_perfdata(label => "io_device", value => $value6, uom => 'ms', threshold => $np->threshold);
  2932.             $np->add_perfdata(label => "io_queue", value => $value7, uom => 'ms', threshold => $np->threshold);
  2933.             $res = OK;
  2934.             $output = "io commands aborted=" . $value1 . ", io bus resets=" . $value2 . ", io read latency=" . $value3 . " ms, write latency=" . $value4 . " ms, kernel latency=" . $value5 . " ms, device latency=" . $value6 . " ms, queue latency=" . $value7 ." ms";
  2935.         }
  2936.     }

  2937.     return ($res, $output);
  2938. }

  2939. sub dc_runtime_info
  2940. {
  2941.     my ($np, $subcommand, $blacklist) = @_;

  2942.     my $res = CRITICAL;
  2943.     my $output = 'DC RUNTIME Unknown error';
  2944.     my $runtime;
  2945.     my $dc_view = Vim::find_entity_view(view_type => 'Datacenter', properties => ['name', 'overallStatus', 'configIssue']);

  2946.     die "There are no Datacenter\n" if (!defined($dc_view));

  2947.     if (defined($subcommand))
  2948.     {
  2949.         if (($subcommand eq "LIST") || ($subcommand eq "LISTVM"))
  2950.         {
  2951.             my %vm_state_strings = ("poweredOn" => "UP", "poweredOff" => "DOWN", "suspended" => "SUSPENDED");
  2952.             my $vm_views = Vim::find_entity_views(view_type => 'VirtualMachine', properties => ['name', 'runtime']);
  2953.             die "Runtime error\n" if (!defined($vm_views));
  2954.             die "There are no VMs.\n" if (!@$vm_views);
  2955.             my $up = 0;
  2956.             $output = '';

  2957.             foreach my $vm (@$vm_views) {
  2958.                 my $vm_state = $vm_state_strings{$vm->runtime->powerState->val};
  2959.                 if ($vm_state eq "UP")
  2960.                 {
  2961.                     $up++;
  2962.                     $output .= $vm->name . "(UP), ";
  2963.                 }
  2964.                 else
  2965.                 {
  2966.                     $output = $vm->name . "(" . $vm_state . "), " . $output;
  2967.                 }
  2968.             }

  2969.             chop($output);
  2970.             chop($output);
  2971.             $res = OK;
  2972.             $output = $up . "/" . @$vm_views . " VMs up: " . $output;
  2973.             $np->add_perfdata(label => "vmcount", value => $up, uom => 'units', threshold => $np->threshold);
  2974.             $res = $np->check_threshold(check => $up) if (defined($np->threshold));
  2975.         }
  2976.         elsif ($subcommand eq "LISTHOST")
  2977.         {
  2978.             my %host_state_strings = ("unknown" => "UNKNOWN", "poweredOn" => "UP", "poweredOff" => "DOWN", "suspended" => "SUSPENDED", "standBy" => "STANDBY", "MaintenanceMode" => "Maintenance Mode");
  2979.             my $host_views = Vim::find_entity_views(view_type => 'HostSystem', properties => ['name', 'runtime.powerState']);
  2980.             die "Runtime error\n" if (!defined($host_views));
  2981.             die "There are no VMs.\n" if (!@$host_views);
  2982.             my $up = 0;
  2983.             my $unknown = 0;
  2984.             $output = '';

  2985.             foreach my $host (@$host_views) {
  2986.                 $host->update_view_data(['name', 'runtime.powerState']);
  2987.                 my $host_state = $host_state_strings{$host->get_property('runtime.powerState')->val};
  2988.                 $unknown += $host_state eq "UNKNOWN";
  2989.                 if ($host_state eq "UP") {
  2990.                     $up++;
  2991.                     $output .= $host->name . "(UP), ";
  2992.                 } else
  2993.                 {
  2994.                     $output = $host->name . "(" . $host_state . "), " . $output;
  2995.                 }
  2996.             }

  2997.             chop($output);
  2998.             chop($output);
  2999.             $res = OK;
  3000.             $output = $up . "/" . @$host_views . " Hosts up: " . $output;
  3001.             $np->add_perfdata(label => "hostcount", value => $up, uom => 'units', threshold => $np->threshold);
  3002.             $res = $np->check_threshold(check => $up) if (defined($np->threshold));
  3003.             $res = UNKNOWN if ($res == OK && $unknown);
  3004.         }
  3005.         elsif ($subcommand eq "TOOLS")
  3006.         {
  3007.             my $vm_views = Vim::find_entity_views(view_type => 'VirtualMachine', properties => ['name', 'runtime.powerState', 'summary.guest']);
  3008.             die "Runtime error\n" if (!defined($vm_views));
  3009.             die "There are no VMs.\n" if (!@$vm_views);
  3010.             $output = '';
  3011.             my $tools_ok = 0;
  3012.             my $vms_up = 0;
  3013.             foreach my $vm (@$vm_views) {
  3014.                 my $name = $vm->name;
  3015.                 if (defined($blacklist))
  3016.                 {
  3017.                     next if ($blacklist =~ m/(^|\s|\t|,)\Q$name\E($|\s|\t|,)/);
  3018.                 }
  3019.                 if ($vm->get_property('runtime.powerState')->val eq "poweredOn")
  3020.                 {
  3021.                     my $vm_guest = $vm->get_property('summary.guest');
  3022.                     my $tools_status;
  3023.                     my $tools_runstate;
  3024.                     my $tools_version;
  3025.                     $tools_runstate = $vm_guest->toolsRunningStatus if (exists($vm_guest->{toolsRunningStatus}) &&