check_esx3.pl: Added timeshift argument, which could fix 'UNKNOWN error' issues for...
[nagios/op5plugins.git] / check_esx3.pl
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 <>
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
12 # Discussions are directed to the mailing list ,
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 .
26 #
27
28 use strict;
29 use warnings;
30 use vars qw($PROGNAME $VERSION $output $values $result);
31 use Nagios::Plugin;
32 use File::Basename;
33 my $perl_module_instructions="
34 Download the latest version of Perl Toolkit from VMware support page. 
35 In this example we use VMware-vSphere-SDK-for-Perl-4.0.0-161974.x86_64.tar.gz,
36 but the instructions should apply to newer versions as well.
37   
38 Upload the file to your op5 Monitor server's /root dir and execute:
39
40     cd /root
41     tar xvzf VMware-vSphere-SDK-for-Perl-4.0.0-161974.x86_64.tar.gz
42     cd vmware-vsphere-cli-distrib/
43     ./vmware-install.pl
44   
45 Follow the on screen instructions, described below:
46
47   \"Creating a new vSphere CLI installer database using the tar4 format.
48
49   Installing vSphere CLI.
50
51   Installing version 161974 of vSphere CLI
52
53   You must read and accept the vSphere CLI End User License Agreement to
54   continue.
55   Press enter to display it.\" 
56   
57     
58
59   \"Read through the License Agreement\" 
60   \"Do you accept? (yes/no) 
61   
62     yes
63
64
65   \"The following Perl modules were found on the system but may be too old to work
66   with VIPerl:
67   
68   Crypt::SSLeay
69   Compress::Zlib\"
70   
71   \"In which directory do you want to install the executable files? [/usr/bin]\"
72
73     
74
75   \"Please wait while copying vSphere CLI files...
76
77   The installation of vSphere CLI 4.0.0 build-161974 for Linux completed
78   successfully. You can decide to remove this software from your system at any
79   time by invoking the following command:
80   \"/usr/bin/vmware-uninstall-vSphere-CLI.pl\".
81   
82   This installer has successfully installed both vSphere CLI and the vSphere SDK
83   for Perl.
84   Enjoy,
85   
86   --the VMware team\"
87
88 Note: \"Crypt::SSLeay\" and \"Compress::Zlib\" are not needed for check_esx3 to work.  
89 ";
90
91
92 eval { 
93         require VMware::VIRuntime
94 } 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");
95
96 $PROGNAME = basename($0);
97 $VERSION = '0.5.0';
98
99 my $np = Nagios::Plugin->new(
100   usage => "Usage: %s -D  | -H  [ -N  ]\n"
101     . "    -u  -p  | -f \n"
102     . "    -l  [ -s  ]\n"
103     . "    [ -x  ] [ -o  ]\n"
104     . "    [ -t  ] [ -w  ] [ -c  ]\n"
105     . '    [ -V ] [ -h ]',
106   version => $VERSION,
107   plugin  => $PROGNAME,
108   shortname => uc($PROGNAME),
109   blurb => 'VMWare Infrastructure plugin',
110   extra   => "Supported commands(^ means blank or not specified parameter) :\n"
111     . "    Common options for VM, Host and DC :\n"
112     . "        * cpu - shows cpu info\n"
113     . "            + usage - CPU usage in percentage\n"
114     . "            + usagemhz - CPU usage in MHz\n"
115     . "            ^ all cpu info\n"
116     . "        * mem - shows mem info\n"
117     . "            + usage - mem usage in percentage\n"
118     . "            + usagemb - mem usage in MB\n"
119     . "            + swap - swap mem usage in MB\n"
120     . "            + overhead - additional mem used by VM Server in MB\n"
121     . "            + overall - overall mem used by VM Server in MB\n"
122     . "            + memctl - mem used by VM memory control driver(vmmemctl) that controls ballooning\n"
123     . "            ^ all mem info\n"
124     . "        * net - shows net info\n"
125     . "            + usage - overall network usage in KBps(Kilobytes per Second) \n"
126     . "            + receive - receive in KBps(Kilobytes per Second) \n"
127     . "            + send - send in KBps(Kilobytes per Second) \n"
128     . "            ^ all net info\n"
129     . "        * io - shows disk io info\n"
130     . "            + read - read latency in ms (totalReadLatency.average)\n"
131     . "            + write - write latency in ms (totalWriteLatency.average)\n"
132     . "            ^ all disk io info\n"
133     . "        * runtime - shows runtime info\n"
134     . "            + status - overall host status (gray/green/red/yellow)\n"
135     . "            + issues - all issues for the host\n"
136     . "            ^ all runtime info\n"
137     . "    VM specific :\n"
138     . "        * cpu - shows cpu info\n"
139     . "            + wait - CPU wait time in ms\n"
140     . "            + ready - CPU ready time in ms\n"
141     . "        * mem - shows mem info\n"
142     . "            + swapin - swapin mem usage in MB\n"
143     . "            + swapout - swapout mem usage in MB\n"
144     . "            + active - active mem usage in MB\n"
145     . "        * io - shows disk I/O info\n"
146     . "            + usage - overall disk usage in MB/s\n"
147     . "        * runtime - shows runtime info\n"
148     . "            + con - connection state\n"
149     . "            + cpu - allocated CPU in MHz\n"
150     . "            + mem - allocated mem in MB\n"
151     . "            + state - virtual machine state (UP, DOWN, SUSPENDED)\n"
152     . "            + consoleconnections - console connections to VM\n"
153     . "            + guest - guest OS status, needs VMware Tools\n"
154     . "            + tools - VMWare Tools status\n"
155     . "    Host specific :\n"
156     . "        * net - shows net info\n"
157     . "            + nic - makes sure all active NICs are plugged in\n"
158     . "        * io - shows disk io info\n"
159     . "            + aborted - aborted commands count\n"
160     . "            + resets - bus resets count\n"
161     . "            + kernel - kernel latency in ms\n"
162     . "            + device - device latency in ms\n"
163     . "            + queue - queue latency in ms\n"
164     . "        * vmfs - shows Datastore info\n"
165     . "            + (name) - free space info for datastore with name (name)\n"
166     . "            ^ all datastore info\n"
167     . "        * runtime - shows runtime info\n"
168     . "            + con - connection state\n"
169     . "            + health - checks cpu/storage/memory/sensor status\n"
170     . "            + maintenance - shows whether host is in maintenance mode\n"
171     . "            + list(vm) - list of VMWare machines and their statuses\n"
172     . "        * service - shows Host service info\n"
173     . "            + (names) - check the state of one or several services specified by (names), syntax for (names):,,...,\n"
174     . "            ^ show all services\n"
175     . "        * storage - shows Host storage info\n"
176     . "            + adapter - list bus adapters\n"
177     . "            + lun - list SCSI logical units\n"
178     . "            + path - list logical unit paths\n"
179     . "    DC specific :\n"
180     . "        * io - shows disk io info\n"
181     . "            + aborted - aborted commands count\n"
182     . "            + resets - bus resets count\n"
183     . "            + kernel - kernel latency in ms\n"
184     . "            + device - device latency in ms\n"
185     . "            + queue - queue latency in ms\n"
186     . "        * vmfs - shows Datastore info\n"
187     . "            + (name) - free space info for datastore with name (name)\n"
188     . "            ^ all datastore info\n"
189     . "        * runtime - shows runtime info\n"
190     . "            + list(vm) - list of VMWare machines and their statuses\n"
191     . "            + listhost - list of VMWare esx host servers and their statuses\n"
192     . "            + tools - VMWare Tools status\n"
193     . "        * recommendations - shows recommendations for cluster\n"
194     . "            + (name) - recommendations for cluster with name (name)\n"
195     . "            ^ all clusters recommendations\n"
196     . "\n\nCopyright (c) 2008 op5",
197   timeout => 30,
198 );
199
200 $np->add_arg(
201   spec => 'host|H=s',
202   help => "-H, --host=\n"
203     . '   ESX or ESXi hostname.',
204   required => 0,
205 );
206
207 $np->add_arg(
208   spec => 'cluster|C=s',
209   help => "-C, --cluster=\n"
210     . '   ESX or ESXi clustername.',
211   required => 0,
212 );
213
214 $np->add_arg(
215   spec => 'datacenter|D=s',
216   help => "-D, --datacenter=\n"
217     . '   Datacenter hostname.',
218   required => 0,
219 );
220
221 $np->add_arg(
222   spec => 'name|N=s',
223   help => "-N, --name=\n"
224     . '   Virtual machine name.',
225   required => 0,
226 );
227
228 $np->add_arg(
229   spec => 'username|u=s',
230   help => "-u, --username=\n"
231     . '   Username to connect with.',
232   required => 0,
233 );
234
235 $np->add_arg(
236   spec => 'password|p=s',
237   help => "-p, --password=\n"
238     . '   Password to use with the username.',
239   required => 0,
240 );
241
242 $np->add_arg(
243   spec => 'authfile|f=s',
244   help => "-f, --authfile=\n"
245     . "   Authentication file with login and password. File syntax :\n"
246     . "   username=\n"
247     . '   password=',
248   required => 0,
249 );
250
251 $np->add_arg(
252   spec => 'warning|w=s',
253   help => "-w, --warning=THRESHOLD\n"
254     . "   Warning threshold. See\n"
255     . "   http://nagiosplug.sourceforge.net/developer-guidelines.html#THRESHOLDFORMAT\n"
256     . '   for the threshold format.',
257   required => 0,
258 );
259
260 $np->add_arg(
261   spec => 'critical|c=s',
262   help => "-c, --critical=THRESHOLD\n"
263     . "   Critical threshold. See\n"
264     . "   http://nagiosplug.sourceforge.net/developer-guidelines.html#THRESHOLDFORMAT\n"
265     . '   for the threshold format.',
266   required => 0,
267 );
268
269 $np->add_arg(
270   spec => 'command|l=s',
271   help => "-l, --command=COMMAND\n"
272     . '   Specify command type (CPU, MEM, NET, IO, VMFS, RUNTIME, ...)',
273   required => 1,
274 );
275
276 $np->add_arg(
277   spec => 'subcommand|s=s',
278   help => "-s, --subcommand=SUBCOMMAND\n"
279     . '   Specify subcommand',
280   required => 0,
281 );
282
283 $np->add_arg(
284   spec => 'sessionfile|S=s',
285   help => "-S, --sessionfile=SESSIONFILE\n"
286     . '   Specify a filename to store sessions for faster authentication',
287   required => 0,
288 );
289
290 $np->add_arg(
291   spec => 'exclude|x=s',
292   help => "-x, --exclude=\n"
293     . '   Specify black list',
294   required => 0,
295 );
296
297 $np->add_arg(
298   spec => 'options|o=s',
299   help => "-o, --options= \n"
300     . '   Specify additional command options',
301   required => 0,
302 );
303
304 $np->getopts;
305
306 my $host = $np->opts->host;
307 my $cluster = $np->opts->cluster;
308 my $datacenter = $np->opts->datacenter;
309 my $vmname = $np->opts->name;
310 my $username = $np->opts->username;
311 my $password = $np->opts->password;
312 my $authfile = $np->opts->authfile;
313 my $warning = $np->opts->warning;
314 my $critical = $np->opts->critical;
315 my $command = $np->opts->command;
316 my $subcommand = $np->opts->subcommand;
317 my $sessionfile = $np->opts->sessionfile;
318 my $blacklist = $np->opts->exclude;
319 my $addopts = $np->opts->options;
320 my $percw;
321 my $percc;
322 $output = "Unknown ERROR!";
323 $result = CRITICAL;
324
325 if (defined($subcommand))
326 {
327         $subcommand = undef if ($subcommand eq '');
328 }
329
330 if (defined($critical))
331 {
332         ($percc, $critical) = check_percantage($critical);
333         $critical = undef if ($critical eq '');
334 }
335
336 if (defined($warning))
337 {
338         ($percw, $warning) = check_percantage($warning);
339         $warning = undef if ($warning eq '');
340 }
341
342 $np->set_thresholds(critical => $critical, warning => $warning);
343
344 eval
345 {
346         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)));
347         die "Both threshold values must be the same units\n" if (($percw && !$percc && defined($critical)) || (!$percw && $percc && defined($warning)));
348         if (defined($authfile))
349         {
350                 open (AUTH_FILE, $authfile) || die "Unable to open auth file \"$authfile\"\n";
351                 while(  ) {
352                         if(s/^[ \t]*username[ \t]*=//){
353                                 s/^\s+//;s/\s+$//;
354                                 $username = $_;
355                         }
356                         if(s/^[ \t]*password[ \t]*=//){
357                                 s/^\s+//;s/\s+$//;
358                                 $password = $_;
359                         }
360                 }
361                 die "Auth file must contain both username and password\n" if (!(defined($username) && defined($password)));
362         }
363
364         my $host_address;
365
366         if (defined($datacenter))
367         {
368                 $host_address = $datacenter;
369         }
370         elsif (defined($host))
371         {
372                 $host_address = $host;
373         }
374         else
375         {
376                 $np->nagios_exit(CRITICAL, "No Host or Datacenter specified");
377         }
378
379         $host_address .= ":443" if (index($host_address, ":") == -1);
380         $host_address = "https://" . $host_address . "/sdk/webService";
381
382         if (defined($sessionfile) and -e $sessionfile)
383         {
384                 Opts::set_option("sessionfile", $sessionfile);
385                 eval {
386                         Util::connect($host_address, $username, $password);
387                         die "Connected host doesn't match reqested once\n" if (Opts::get_option("url") ne $host_address);
388                 };
389                 if ($@) {
390                         Opts::set_option("sessionfile", undef);
391                         Util::connect($host_address, $username, $password);
392                 }
393         }
394         else
395         {
396                 Util::connect($host_address, $username, $password);
397         }
398
399         if (defined($sessionfile))
400         {
401                 Vim::save_session(session_file => $sessionfile);
402         }
403         $command = uc($command);
404         if (defined($vmname))
405         {
406                 if ($command eq "CPU")
407                 {
408                         ($result, $output) = vm_cpu_info($vmname, $np, local_uc($subcommand));
409                 }
410                 elsif ($command eq "MEM")
411                 {
412                         ($result, $output) = vm_mem_info($vmname, $np, local_uc($subcommand));
413                 }
414                 elsif ($command eq "NET")
415                 {
416                         ($result, $output) = vm_net_info($vmname, $np, local_uc($subcommand));
417                 }
418                 elsif ($command eq "IO")
419                 {
420                         ($result, $output) = vm_disk_io_info($vmname, $np, local_uc($subcommand));
421                 }
422                 elsif ($command eq "RUNTIME")
423                 {
424                         ($result, $output) = vm_runtime_info($vmname, $np, local_uc($subcommand));
425                 }
426                 else
427                 {
428                         $output = "Unknown HOST-VM command\n" . $np->opts->_help;
429                         $result = CRITICAL;
430                 }
431         }
432         elsif (defined($host))
433         {
434                 my $esx;
435                 $esx = {name => $host} if (defined($datacenter));
436                 if ($command eq "CPU")
437                 {
438                         ($result, $output) = host_cpu_info($esx, $np, local_uc($subcommand), $addopts);
439                 }
440                 elsif ($command eq "MEM")
441                 {
442                         ($result, $output) = host_mem_info($esx, $np, local_uc($subcommand), $addopts);
443                 }
444                 elsif ($command eq "NET")
445                 {
446                         ($result, $output) = host_net_info($esx, $np, local_uc($subcommand));
447                 }
448                 elsif ($command eq "IO")
449                 {
450                         ($result, $output) = host_disk_io_info($esx, $np, local_uc($subcommand));
451                 }
452                 elsif ($command eq "VMFS")
453                 {
454                         ($result, $output) = host_list_vm_volumes_info($esx, $np, $subcommand, $blacklist, $percc || $percw, $addopts);
455                 }
456                 elsif ($command eq "RUNTIME")
457                 {
458                         ($result, $output) = host_runtime_info($esx, $np, local_uc($subcommand), $blacklist);
459                 }
460                 elsif ($command eq "SERVICE")
461                 {
462                         ($result, $output) = host_service_info($esx, $np, $subcommand);
463                 }
464                 elsif ($command eq "STORAGE")
465                 {
466                         ($result, $output) = host_storage_info($esx, $np, local_uc($subcommand), $blacklist);
467                 }
468                 else
469                 {
470                         $output = "Unknown HOST command\n" . $np->opts->_help;
471                         $result = CRITICAL;
472                 }
473         }
474         elsif (defined($cluster))
475         {
476                 if ($command eq "CPU")
477                 {
478                         ($result, $output) = cluster_cpu_info($cluster, $np, local_uc($subcommand));
479                 }
480                 elsif ($command eq "MEM")
481                 {
482                         ($result, $output) = cluster_mem_info($cluster, $np, local_uc($subcommand), $addopts);
483                 }
484                 elsif ($command eq "CLUSTER")
485                 {
486                         ($result, $output) = cluster_cluster_info($cluster, $np, local_uc($subcommand));
487                 }
488                 elsif ($command eq "VMFS")
489                 {
490                         ($result, $output) = cluster_list_vm_volumes_info($cluster, $np, $subcommand, $blacklist, $percc || $percw, $addopts);
491                 }
492                 elsif ($command eq "RUNTIME")
493                 {
494                         ($result, $output) = cluster_runtime_info($cluster, $np, local_uc($subcommand), $blacklist);
495                 }
496                 else
497                 {
498                         $output = "Unknown CLUSTER command\n" . $np->opts->_help;
499                         $result = CRITICAL;
500                 }
501         }
502         else
503         {
504                 if ($command eq "RECOMMENDATIONS")
505                 {
506                         my $cluster_name;
507                         $cluster_name = {name => $subcommand} if (defined($subcommand));
508                         ($result, $output) = return_cluster_DRS_recommendations($np, $cluster_name);
509                 }
510                 elsif ($command eq "CPU")
511                 {
512                         ($result, $output) = dc_cpu_info($np, local_uc($subcommand), $addopts);
513                 }
514                 elsif ($command eq "MEM")
515                 {
516                         ($result, $output) = dc_mem_info($np, local_uc($subcommand), $addopts);
517                 }
518                 elsif ($command eq "NET")
519                 {
520                         ($result, $output) = dc_net_info($np, local_uc($subcommand));
521                 }
522                 elsif ($command eq "IO")
523                 {
524                         ($result, $output) = dc_disk_io_info($np, local_uc($subcommand));
525                 }
526                 elsif ($command eq "VMFS")
527                 {
528                         ($result, $output) = dc_list_vm_volumes_info($np, $subcommand, $blacklist, $percc || $percw, $addopts);
529                 }
530                 elsif ($command eq "RUNTIME")
531                 {
532                         ($result, $output) = dc_runtime_info($np, local_uc($subcommand), $blacklist);
533                 }
534                 else
535                 {
536                         $output = "Unknown HOST command\n" . $np->opts->_help;
537                         $result = CRITICAL;
538                 }               
539         }
540 };
541 if ($@)
542 {
543         if (uc(ref($@)) eq "HASH")
544         {
545                 $output = $@->{msg};
546                 $result = $@->{code};
547         }
548         else
549         {
550                 $output = $@ . "";
551                 $result = CRITICAL;
552         }
553 }
554
555 Util::disconnect();
556 $np->nagios_exit($result, $output);
557
558 #######################################################################################################################################################################
559
560 sub get_key_metrices {
561         my ($perfmgr_view, $group, @names) = @_;
562
563         my $perfCounterInfo = $perfmgr_view->perfCounter;
564         my @counters;
565
566         die "Insufficient rights to access perfcounters\n" if (!defined($perfCounterInfo));
567
568         foreach (@$perfCounterInfo) {
569                 if ($_->groupInfo->key eq $group) {
570                         my $cur_name = $_->nameInfo->key . "." . $_->rollupType->val;
571                         foreach my $index (0..@names-1)
572                         {
573                                 if ($names[$index] =~ /$cur_name/)
574                                 {
575                                         $names[$index] =~ /(\w+).(\w+):*(.*)/;
576                                         $counters[$index] = PerfMetricId->new(counterId => $_->key, instance => $3);
577                                 }
578                         }
579                 }
580         }
581
582         return \@counters;
583 }
584
585 sub generic_performance_values {
586         my ($views, $group, @list) = @_;
587         my $counter = 0;
588         my @values = ();
589         my $amount = @list;
590         my $perfMgr = Vim::get_view(mo_ref => Vim::get_service_content()->perfManager, properties => [ 'perfCounter' ]);
591         my $metrices = get_key_metrices($perfMgr, $group, @list);
592
593         my @perf_query_spec = ();
594         push(@perf_query_spec, PerfQuerySpec->new(entity => $_, metricId => $metrices, format => 'csv', intervalId => 20, maxSample => 1)) foreach (@$views);
595         my $perf_data = $perfMgr->QueryPerf(querySpec => \@perf_query_spec);
596         $amount *= @$perf_data;
597
598         while (@$perf_data)
599         {
600                 my $unsorted = shift(@$perf_data)->value;
601                 my @host_values = ();
602
603                 foreach my $id (@$unsorted)
604                 {
605                         foreach my $index (0..@$metrices-1)
606                         {
607                                 if ($id->id->counterId == $$metrices[$index]->counterId)
608                                 {
609                                         $counter++ if (!defined($host_values[$index]));
610                                         $host_values[$index] = $id;
611                                 }
612                         }
613                 }
614                 push(@values, \@host_values);
615         }
616         return undef if ($counter != $amount || $counter == 0);
617         return \@values;
618 }
619
620 sub return_host_performance_values {
621         my $values;
622         my $host_name = shift(@_);
623         my $host_view = Vim::find_entity_views(view_type => 'HostSystem', filter => $host_name, properties => [ 'name', 'runtime.inMaintenanceMode' ]); # Added properties named argument.
624         die "Runtime error\n" if (!defined($host_view));
625         die "Host \"" . $$host_name{"name"} . "\" does not exist\n" if (!@$host_view);
626         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");
627         $values = generic_performance_values($host_view, @_);
628
629         return undef if ($@);
630         return ($host_view, $values);
631 }
632
633 sub return_host_vmware_performance_values {
634         my $values;
635         my $vmname = shift(@_);
636         my $vm_view = Vim::find_entity_views(view_type => 'VirtualMachine', filter => {name => "$vmname"}, properties => [ 'name', 'runtime.powerState' ]);
637         die "Runtime error\n" if (!defined($vm_view));
638         die "VMware machine \"" . $vmname . "\" does not exist\n" if (!@$vm_view);
639         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");
640         $values = generic_performance_values($vm_view, @_);
641
642         return $@ if ($@);
643         return ($vm_view, $values);
644 }
645
646 sub return_dc_performance_values {
647         my $values;
648         my $host_views = Vim::find_entity_views(view_type => 'HostSystem', properties => [ 'name' ]);
649         die "Runtime error\n" if (!defined($host_views));
650         die "Datacenter does not contain any hosts\n" if (!@$host_views);
651         $values = generic_performance_values($host_views, @_);
652
653         return undef if ($@);
654         return ($host_views, $values);
655 }
656
657 sub return_cluster_performance_values {
658         my $values;
659         my $cluster_name = shift(@_);
660         my $cluster_view = Vim::find_entity_views(view_type => 'ClusterComputeResource', filter => { name => "$cluster_name" }, properties => [ 'name' ]); # Added properties named argument.
661         die "Runtime error\n" if (!defined($cluster_view));
662         die "Cluster \"" . $cluster_name . "\" does not exist\n" if (!@$cluster_view);
663         $values = generic_performance_values($cluster_view, @_);
664
665         return undef if ($@);
666         return $values;
667 }
668
669 # Temporary solution to overcome zeros in network output
670 sub return_host_temporary_vc_4_1_network_performance_values {
671         my @values;
672         my ($host_name, @list) = @_;
673
674         my $host_view = Vim::find_entity_views(view_type => 'HostSystem', filter => $host_name, properties => [ 'name', 'runtime.inMaintenanceMode', 'summary.config.product.version' ]); # Added properties named argument.
675         die "Runtime error\n" if (!defined($host_view));
676         die "Host \"" . $$host_name{"name"} . "\" does not exist\n" if (!@$host_view);
677         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");
678         my $software_version = $$host_view[0]->get_property('summary.config.product.version');
679         return undef if (substr($software_version, 0, 4) ne '4.1.');
680
681         my $perfMgr = Vim::get_view(mo_ref => Vim::get_service_content()->perfManager, properties => [ 'perfCounter' ]);
682         my $metrices = get_key_metrices($perfMgr, 'net', @list);
683
684         my $amount = @list;
685         my @perf_query_spec = ();
686         push(@perf_query_spec, PerfQuerySpec->new(entity => $_, metricId => $metrices, format => 'csv', intervalId => 20, maxSample => 1)) foreach (@$host_view);
687         my $perf_data = $perfMgr->QueryPerf(querySpec => \@perf_query_spec);
688         $amount *= @$perf_data;
689
690         my $counter = 0;
691         while (@$perf_data)
692         {
693                 my $unsorted = shift(@$perf_data)->value;
694                 my @host_values = ();
695
696                 foreach my $id (@$unsorted)
697                 {
698                         foreach my $index (0..@$metrices-1)
699                         {
700                                 if ($id->id->counterId == $$metrices[$index]->counterId)
701                                 {
702                                         if (!defined($host_values[$index]))
703                                         {
704                                                 $counter++;
705                                                 $host_values[$index] = bless({ 'value' => '0' }, "PerfMetricSeriesCSV");
706                                         }
707                                         $host_values[$index]{"value"} += convert_number($id->value) if ($id->id->instance ne '');
708                                 }
709                         }
710                 }
711                 push(@values, \@host_values);
712         }
713
714         return undef if ($counter != $amount || $counter == 0 || $@);
715         return ($host_view, \@values);
716 }
717 # Remove as soon as possible
718
719 sub local_uc
720 {
721         my ($val) = shift(@_);
722         return defined($val)?uc($val):undef;
723 }
724
725 sub simplify_number
726 {
727         my ($number, $cnt) = @_;
728         $cnt = 2 if (!defined($cnt));
729         return sprintf("%.${cnt}f", "$number");
730 }
731
732 sub convert_number
733 {
734         my @vals = split(/,/, shift(@_));
735         return shift(@vals) if ($vals[-1] < 0);
736         return pop(@vals);
737 }
738
739 sub check_percantage
740 {
741         my ($number) = shift(@_);
742         my $perc = $number =~ s/\%//;
743         return ($perc, $number);
744 }
745
746 sub check_health_state
747 {
748         my ($state) = shift(@_);
749         my $res = UNKNOWN;
750
751         if (uc($state) eq "GREEN") {
752                 $res = OK
753         } elsif (uc($state) eq "YELLOW") {
754                 $res = WARNING;
755         } elsif (uc($state) eq "RED") {
756                 $res = CRITICAL;
757         }
758         
759         return $res;
760 }
761
762 sub format_issue {
763         my ($issue) = shift(@_);
764
765         my $output = '';
766
767         if (defined($issue->datacenter))
768         {
769                 $output .= 'Datacenter "' . $issue->datacenter->name . '", ';
770         }
771         if (defined($issue->host))
772         {
773                 $output .= 'Host "' . $issue->host->name . '", ';
774         }
775         if (defined($issue->vm))
776         {
777                 $output .= 'VM "' . $issue->vm->name . '", ';
778         }
779         if (defined($issue->computeResource))
780         {
781                 $output .= 'Compute Resource "' . $issue->computeResource->name . '", ';
782         }
783         if (exists($issue->{dvs}) && defined($issue->dvs))
784         {
785                 # Since vSphere API 4.0
786                 $output .= 'Virtual Switch "' . $issue->dvs->name . '", ';
787         }
788         if (exists($issue->{ds}) && defined($issue->ds))
789         {
790                 # Since vSphere API 4.0
791                 $output .= 'Datastore "' . $issue->ds->name . '", ';
792         }
793         if (exists($issue->{net}) && defined($issue->net))
794         {
795                 # Since vSphere API 4.0
796                 $output .= 'Network "' . $issue->net->name . '" ';
797         }
798
799         $output =~ s/, $/ /;
800         $output .= ": " . $issue->fullFormattedMessage;
801         $output .= "(caused by " . $issue->userName . ")" if ($issue->userName ne "");
802
803         return $output;
804 }
805
806 sub datastore_volumes_info
807 {
808         my ($datastore, $np, $subcommand, $blacklist, $perc, $addopts) = @_;
809
810         my $res = OK;
811         my $output = '';
812
813         my $usedflag;
814         my $briefflag;
815         my $regexpflag;
816         my $blackregexpflag;
817         $usedflag = $addopts =~ m/(^|\s|\t|,)\Qused\E($|\s|\t|,)/ if (defined($addopts));
818         $briefflag = $addopts =~ m/(^|\s|\t|,)\Qbrief\E($|\s|\t|,)/ if (defined($addopts));
819         $regexpflag = $addopts =~ m/(^|\s|\t|,)\Qregexp\E($|\s|\t|,)/ if (defined($addopts));
820         $blackregexpflag = $addopts =~ m/(^|\s|\t|,)\Qblacklistregexp\E($|\s|\t|,)/ if (defined($addopts));
821
822         die "Blacklist is supported only in generic check or regexp subcheck\n" if (defined($subcommand) && defined($blacklist) && !defined($regexpflag));
823
824         if (defined($regexpflag) && defined($subcommand))
825         {
826                 eval
827                 {
828                         qr{$subcommand};
829                 };
830                 if ($@)
831                 {
832                         $@ =~ s/ at.*line.*\.//;
833                         die $@;
834                 }
835         }
836
837         my $state;
838         foreach my $ref_store (@{$datastore})
839         {
840                 my $store = Vim::get_view(mo_ref => $ref_store, properties => ['summary', 'info']);
841                 my $name = $store->summary->name;
842                 if (!defined($subcommand) || ($name eq $subcommand) || (defined($regexpflag) && $name =~ /$subcommand/))
843                 {
844                         if (defined($blacklist))
845                         {
846                                 next if ($blackregexpflag?$name =~ /$blacklist/:$blacklist =~ m/(^|\s|\t|,)\Q$name\E($|\s|\t|,)/);
847                         }
848
849                         if ($store->summary->accessible)
850                         {
851                                 my $value1 = simplify_number(convert_number($store->summary->freeSpace) / 1024 / 1024);
852                                 my $value2 = convert_number($store->summary->capacity);
853                                 $value2 = simplify_number(convert_number($store->info->freeSpace) / $value2 * 100) if ($value2 > 0);
854
855                                 if ($usedflag)
856                                 {
857                                         $value1 = simplify_number(convert_number($store->summary->capacity) / 1024 / 1024) - $value1;
858                                         $value2 = 100 - $value2;
859                                 }
860
861                                 $state = $np->check_threshold(check => $perc?$value2:$value1);
862                                 $res = Nagios::Plugin::Functions::max_state($res, $state);
863                                 $np->add_perfdata(label => $name, value => $perc?$value2:$value1, uom => $perc?'%':'MB', threshold => $np->threshold);
864                                 $output .= $name . "=". $value1 . " MB (" . $value2 . "%), " if (!$briefflag || $state != OK);
865                         }
866                         else
867                         {
868                                 $res = CRITICAL;
869                                 $output .= $name . " is not accessible, ";
870                         }
871                         last if (!$regexpflag && defined($subcommand) && ($name eq $subcommand));
872                         $blacklist .= $blackregexpflag?"|^$name\$":",$name";
873                 }
874         }
875
876         if ($output)
877         {
878                 chop($output);
879                 chop($output);
880                 $output = "Storages : " . $output;
881         }
882         else
883         {
884                 if ($briefflag)
885                 {
886                         $output = "There are no alerts";
887                 }
888                 else
889                 {
890                         $res = WARNING;
891                         $output = defined($subcommand)?$regexpflag? "No matching volumes for regexp \"$subcommand\" found":"No volume named \"$subcommand\" found":"There are no volumes";
892                 }
893         }
894
895         return ($res, $output);
896 }
897
898 #=====================================================================| HOST |============================================================================#
899
900 sub host_cpu_info
901 {
902         my ($host, $np, $subcommand, $addopts) = @_;
903
904         my $res = CRITICAL;
905         my $output = 'HOST CPU Unknown error';
906
907         my $quickStats;
908         $quickStats = $addopts =~ m/(^|\s|\t|,)\Qquickstats\E($|\s|\t|,)/ if (defined($addopts));
909
910         if (defined($subcommand))
911         {
912                 if ($subcommand eq "USAGE")
913                 {
914                         my $value;
915                         if (defined($quickStats))
916                         {
917                                 my $host_view = Vim::find_entity_view(view_type => 'HostSystem', filter => $host, properties => ['name', 'runtime.inMaintenanceMode', 'summary.hardware', 'summary.quickStats']);
918                                 die "Host \"" . $$host{"name"} . "\" does not exist\n" if (!defined($host_view));
919                                 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");
920                                 $values = $host_view->get_property('summary.quickStats');
921                                 my $hardinfo = $host_view->get_property('summary.hardware');
922                                 $value = simplify_number($values->overallCpuUsage / ($hardinfo->numCpuCores * $hardinfo->cpuMhz) * 100) if exists($values->{overallCpuUsage}) && defined($hardinfo);
923                         }
924                         else
925                         {
926                                 $values = return_host_performance_values($host, 'cpu', ('usage.average'));
927                                 $value = simplify_number(convert_number($$values[0][0]->value) * 0.01) if (defined($values));
928                         }
929                         if (defined($value))
930                         {
931                                 $np->add_perfdata(label => "cpu_usage", value => $value, uom => '%', threshold => $np->threshold);
932                                 $output = "cpu usage=" . $value . " %"; 
933                                 $res = $np->check_threshold(check => $value);
934                         }
935                 }
936                 elsif ($subcommand eq "USAGEMHZ")
937                 {
938                         my $value;
939                         if (defined($quickStats))
940                         {
941                                 my $host_view = Vim::find_entity_view(view_type => 'HostSystem', filter => $host, properties => ['name', 'runtime.inMaintenanceMode', 'summary.quickStats']);
942                                 die "Host \"" . $$host{"name"} . "\" does not exist\n" if (!defined($host_view));
943                                 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");
944                                 $values = $host_view->get_property('summary.quickStats');
945                                 $value = simplify_number($values->overallCpuUsage) if exists($values->{overallCpuUsage});
946                         }
947                         else
948                         {
949                                 $values = return_host_performance_values($host, 'cpu', ('usagemhz.average'));
950                                 $value = simplify_number(convert_number($$values[0][0]->value)) if (defined($values));
951                         }
952                         if (defined($value))
953                         {
954                                 $np->add_perfdata(label => "cpu_usagemhz", value => $value, uom => 'Mhz', threshold => $np->threshold);
955                                 $output = "cpu usagemhz=" . $value . " MHz";
956                                 $res = $np->check_threshold(check => $value);
957                         }
958                 }
959                 else
960                 {
961                         $res = CRITICAL;
962                         $output = "HOST CPU - unknown subcommand\n" . $np->opts->_help;
963                 }
964         }
965         else
966         {
967                 my $value1;
968                 my $value2;
969                 if (defined($quickStats))
970                 {
971                         my $host_view = Vim::find_entity_view(view_type => 'HostSystem', filter => $host, properties => ['name', 'runtime.inMaintenanceMode', 'summary.hardware', 'summary.quickStats']);
972                         die "Host \"" . $$host{"name"} . "\" does not exist\n" if (!defined($host_view));
973                         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");
974                         $values = $host_view->get_property('summary.quickStats');
975                         my $hardinfo = $host_view->get_property('summary.hardware');
976                         if (exists($values->{overallCpuUsage}) && defined($hardinfo))
977                         {
978                                 $value1 = simplify_number($values->overallCpuUsage);
979                                 $value2 = simplify_number($values->overallCpuUsage / ($hardinfo->numCpuCores * $hardinfo->cpuMhz) * 100);
980                         }
981                 }
982                 else
983                 {
984                         $values = return_host_performance_values($host, 'cpu', ('usagemhz.average', 'usage.average'));
985                         if ($values) {
986                                 $value1 = simplify_number(convert_number($$values[0][0]->value));
987                                 $value2 = simplify_number(convert_number($$values[0][1]->value) * 0.01);
988                         }
989                 }
990                 if (defined($value1) && defined($value2))
991                 {
992                         $np->add_perfdata(label => "cpu_usagemhz", value => $value1, uom => 'Mhz', threshold => $np->threshold);
993                         $np->add_perfdata(label => "cpu_usage", value => $value2, uom => '%', threshold => $np->threshold);
994                         $res = OK;
995                         $output = "cpu usage=" . $value1 . " MHz (" . $value2 . "%)";
996                 }
997         }
998
999         return ($res, $output);
1000 }
1001
1002 sub host_mem_info
1003 {
1004         my ($host, $np, $subcommand, $addopts) = @_;
1005
1006         my $res = CRITICAL;
1007         my $output = 'HOST MEM Unknown error';
1008
1009         my $quickStats;
1010         my $outputlist;
1011         $quickStats = $addopts =~ m/(^|\s|\t|,)\Qquickstats\E($|\s|\t|,)/ if (defined($addopts));
1012         $outputlist = $addopts =~ m/(^|\s|\t|,)\Qlistvm\E($|\s|\t|,)/ if (defined($addopts));
1013
1014         if (defined($subcommand))
1015         {
1016                 if ($subcommand eq "USAGE")
1017                 {
1018                         my $value;
1019                         if (defined($quickStats))
1020                         {
1021                                 my $host_view = Vim::find_entity_view(view_type => 'HostSystem', filter => $host, properties => ['name', 'runtime.inMaintenanceMode', 'summary.hardware', 'summary.quickStats']);
1022                                 die "Host \"" . $$host{"name"} . "\" does not exist\n" if (!defined($host_view));
1023                                 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");
1024                                 $values = $host_view->get_property('summary.quickStats');
1025                                 my $hardinfo = $host_view->get_property('summary.hardware');
1026                                 $value = simplify_number($values->overallMemoryUsage / ($hardinfo->memorySize / 1024 / 1024) * 100) if exists($values->{overallMemoryUsage}) && defined($hardinfo);
1027                         }
1028                         else
1029                         {
1030                                 $values = return_host_performance_values($host, 'mem', ('usage.average'));
1031                                 $value = simplify_number(convert_number($$values[0][0]->value) * 0.01) if (defined($values));
1032                         }
1033                         if (defined($value))
1034                         {
1035                                 $np->add_perfdata(label => "mem_usage", value => $value, uom => '%', threshold => $np->threshold);
1036                                 $output = "mem usage=" . $value . " %"; 
1037                                 $res = $np->check_threshold(check => $value);
1038                         }
1039                 }
1040                 elsif ($subcommand eq "USAGEMB")
1041                 {
1042                         my $value;
1043                         if (defined($quickStats))
1044                         {
1045                                 my $host_view = Vim::find_entity_view(view_type => 'HostSystem', filter => $host, properties => ['name', 'runtime.inMaintenanceMode', 'summary.quickStats']);
1046                                 die "Host \"" . $$host{"name"} . "\" does not exist\n" if (!defined($host_view));
1047                                 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");
1048                                 $values = $host_view->get_property('summary.quickStats');
1049                                 $value = simplify_number($values->overallMemoryUsage) if exists($values->{overallMemoryUsage});
1050                         }
1051                         else
1052                         {
1053                                 $values = return_host_performance_values($host, 'mem', ('consumed.average'));
1054                                 $value = simplify_number(convert_number($$values[0][0]->value) / 1024) if (defined($values));
1055                         }
1056                         if (defined($value))
1057                         {
1058                                 $np->add_perfdata(label => "mem_usagemb", value => $value, uom => 'MB', threshold => $np->threshold);
1059                                 $output = "mem usage=" . $value . " MB";
1060                                 $res = $np->check_threshold(check => $value);
1061                         }
1062                 }
1063                 elsif ($subcommand eq "SWAP")
1064                 {
1065                         my $host_view;
1066                         ($host_view, $values) = return_host_performance_values($host, 'mem', ('swapused.average'));
1067                         if (defined($values))
1068                         {
1069                                 my $value = simplify_number(convert_number($$values[0][0]->value) / 1024);
1070                                 $np->add_perfdata(label => "mem_swap", value => $value, uom => 'MB', threshold => $np->threshold);
1071                                 $output = "swap usage=" . $value . " MB: ";
1072                                 $res = $np->check_threshold(check => $value);
1073                                 if ($res != OK && $outputlist)
1074                                 {
1075                                         my $vm_views = Vim::find_entity_views(view_type => 'VirtualMachine', begin_entity => $$host_view[0], properties => ['name', 'runtime.powerState']);
1076                                         die "Runtime error\n" if (!defined($vm_views));
1077                                         die "There are no VMs.\n" if (!@$vm_views);
1078                                         my @vms = ();
1079                                         foreach my $vm (@$vm_views)
1080                                         {
1081                                                 push(@vms, $vm) if ($vm->get_property('runtime.powerState')->val eq "poweredOn");
1082                                         }
1083                                         $values = generic_performance_values(\@vms, 'mem', ('swapped.average'));
1084                                         if (defined($values))
1085                                         {
1086                                                 foreach my $index (0..@vms-1) {
1087                                                         my $value = simplify_number(convert_number($$values[$index][0]->value) / 1024);
1088                                                         $output .= $vms[$index]->name . " (" . $value . "MB), " if ($value > 0);
1089                                                 }
1090                                         }
1091                                 }
1092                                 chop($output);
1093                                 chop($output);
1094                         }
1095                 }
1096                 elsif ($subcommand eq "OVERHEAD")
1097                 {
1098                         $values = return_host_performance_values($host, 'mem', ('overhead.average'));
1099                         if (defined($values))
1100                         {
1101                                 my $value = simplify_number(convert_number($$values[0][0]->value) / 1024);
1102                                 $np->add_perfdata(label => "mem_overhead", value => $value, uom => 'MB', threshold => $np->threshold);
1103                                 $output = "overhead=" . $value . " MB";
1104                                 $res = $np->check_threshold(check => $value);
1105                         }
1106                 }
1107                 elsif ($subcommand eq "OVERALL")
1108                 {
1109                         $values = return_host_performance_values($host, 'mem', ('consumed.average', 'overhead.average'));
1110                         if (defined($values))
1111                         {
1112                                 my $value = simplify_number((convert_number($$values[0][0]->value) + convert_number($$values[0][1]->value)) / 1024);
1113                                 $np->add_perfdata(label => "mem_overhead", value =>  $value, uom => 'MB', threshold => $np->threshold);
1114                                 $output = "overall=" . $value . " MB";
1115                                 $res = $np->check_threshold(check => $value);
1116                         }
1117                 }
1118                 elsif ($subcommand eq "MEMCTL")
1119                 {
1120                         my $host_view;
1121                         ($host_view, $values) = return_host_performance_values($host, 'mem', ('vmmemctl.average'));
1122                         if (defined($values))
1123                         {
1124                                 my $value = simplify_number(convert_number($$values[0][0]->value) / 1024);
1125                                 $np->add_perfdata(label => "mem_memctl", value => $value, uom => 'MB', threshold => $np->threshold);
1126                                 $output = "memctl=" . $value . " MB: ";
1127                                 $res = $np->check_threshold(check => $value);
1128                                 if ($res != OK && $outputlist)
1129                                 {
1130                                         my $vm_views = Vim::find_entity_views(view_type => 'VirtualMachine', begin_entity => $$host_view[0], properties => ['name', 'runtime.powerState']);
1131                                         die "Runtime error\n" if (!defined($vm_views));
1132                                         die "There are no VMs.\n" if (!@$vm_views);
1133                                         my @vms = ();
1134                                         foreach my $vm (@$vm_views)
1135                                         {
1136                                                 push(@vms, $vm) if ($vm->get_property('runtime.powerState')->val eq "poweredOn");
1137                                         }
1138                                         $values = generic_performance_values(\@vms, 'mem', ('vmmemctl.average'));
1139                                         if (defined($values))
1140                                         {
1141                                                 foreach my $index (0..@vms-1) {
1142                                                         my $value = simplify_number(convert_number($$values[$index][0]->value) / 1024);
1143                                                         $output .= $vms[$index]->name . " (" . $value . "MB), " if ($value > 0);
1144                                                 }
1145                                         }
1146                                 }
1147                                 chop($output);
1148                                 chop($output);
1149                         }
1150                 }
1151                 else
1152                 {
1153                         $res = CRITICAL;
1154                         $output = "HOST MEM - unknown subcommand\n" . $np->opts->_help;
1155                 }
1156         }
1157         else
1158         {
1159                 $values = return_host_performance_values($host, 'mem', ('consumed.average', 'usage.average', 'overhead.average', 'swapused.average', 'vmmemctl.average'));
1160                 if (defined($values))
1161                 {
1162                         my $value1 = simplify_number(convert_number($$values[0][0]->value) / 1024);
1163                         my $value2 = simplify_number(convert_number($$values[0][1]->value) * 0.01);
1164                         my $value3 = simplify_number(convert_number($$values[0][2]->value) / 1024);
1165                         my $value4 = simplify_number(convert_number($$values[0][3]->value) / 1024);
1166                         my $value5 = simplify_number(convert_number($$values[0][4]->value) / 1024);
1167                         $np->add_perfdata(label => "mem_usagemb", value => $value1, uom => 'MB', threshold => $np->threshold);
1168                         $np->add_perfdata(label => "mem_usage", value => $value2, uom => '%', threshold => $np->threshold);
1169                         $np->add_perfdata(label => "mem_overhead", value => $value3, uom => 'MB', threshold => $np->threshold);
1170                         $np->add_perfdata(label => "mem_swap", value => $value4, uom => 'MB', threshold => $np->threshold);
1171                         $np->add_perfdata(label => "mem_memctl", value => $value5, uom => 'MB', threshold => $np->threshold);
1172                         $res = OK;
1173                         $output = "mem usage=" . $value1 . " MB (" . $value2 . "%), overhead=" . $value3 . " MB, swapped=" . $value4 . " MB, memctl=" . $value5 . " MB";
1174                 }
1175         }
1176
1177         return ($res, $output);
1178 }
1179
1180 sub host_net_info
1181 {
1182         my ($host, $np, $subcommand) = @_;
1183
1184         my $res = CRITICAL;
1185         my $output = 'HOST NET Unknown error';
1186         
1187         if (defined($subcommand))
1188         {
1189                 if ($subcommand eq "USAGE")
1190                 {
1191                         $values = return_host_temporary_vc_4_1_network_performance_values($host, ('received.average:*', 'transmitted.average:*'));
1192                         if ($values)
1193                         {
1194                                 $$values[0][0]{"value"} += $$values[0][1]{"value"};
1195                         }
1196                         else
1197                         {
1198                                 $values = return_host_performance_values($host, 'net', ('usage.average'));
1199                         }
1200                         if (defined($values))
1201                         {
1202                                 my $value = simplify_number(convert_number($$values[0][0]->value));
1203                                 $np->add_perfdata(label => "net_usage", value => $value, uom => 'KBps', threshold => $np->threshold);
1204                                 $output = "net usage=" . $value . " KBps";
1205                                 $res = $np->check_threshold(check => $value);
1206                         }
1207                 }
1208                 elsif ($subcommand eq "RECEIVE")
1209                 {
1210                         $values = return_host_temporary_vc_4_1_network_performance_values($host, ('received.average:*'));
1211                         $values = return_host_performance_values($host, 'net', ('received.average')) if (!$values);
1212                         if (defined($values))
1213                         {
1214                                 my $value = simplify_number(convert_number($$values[0][0]->value));
1215                                 $np->add_perfdata(label => "net_receive", value => $value, uom => 'KBps', threshold => $np->threshold);
1216                                 $output = "net receive=" . $value . " KBps";
1217                                 $res = $np->check_threshold(check => $value);
1218                         }
1219                 }
1220                 elsif ($subcommand eq "SEND")
1221                 {
1222                         $values = return_host_temporary_vc_4_1_network_performance_values($host, ('transmitted.average:*'));
1223                         $values = return_host_performance_values($host, 'net', ('transmitted.average')) if (!$values);
1224                         if (defined($values))
1225                         {
1226                                 my $value = simplify_number(convert_number($$values[0][0]->value));
1227                                 $np->add_perfdata(label => "net_send", value => $value, uom => 'KBps', threshold => $np->threshold);
1228                                 $output = "net send=" . $value . " KBps";
1229                                 $res = $np->check_threshold(check => $value);
1230                         }
1231                 }
1232                 elsif ($subcommand eq "NIC")
1233                 {
1234                         my $host_view = Vim::find_entity_view(view_type => 'HostSystem', filter => $host, properties => ['name', 'configManager.networkSystem', 'runtime.inMaintenanceMode']);
1235                         die "Host \"" . $$host{"name"} . "\" does not exist\n" if (!defined($host_view));
1236                         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");
1237                         my $network_system = Vim::get_view(mo_ref => $host_view->get_property('configManager.networkSystem') , properties => ['networkInfo']);
1238                         $network_system->update_view_data(['networkInfo']);
1239                         my $network_config = $network_system->networkInfo;
1240                         die "Host \"" . $$host{"name"} . "\" has no network info in the API.\n" if (!defined($network_config));
1241
1242                         $output = "";
1243                         $res = OK;
1244                         my $OKCount = 0;
1245                         my $BadCount = 0;
1246                         my @switches = ();
1247
1248                         # create a hash of NIC info to facilitate easy lookups
1249                         my %NIC = ();
1250                         foreach (@{$network_config->pnic})
1251                         {
1252                                 $NIC{$_->key} = $_;
1253                         }
1254
1255                         push(@switches, $network_config->vswitch) if (exists($network_config->{vswitch}));
1256                         push(@switches, $network_config->proxySwitch) if (exists($network_config->{proxySwitch}));
1257
1258                         # see which NICs are actively part of a switch
1259                         foreach my $switch (@switches)
1260                         {
1261                                 foreach (@{$switch})
1262                                 {
1263                                         # get list of physical nics
1264                                         if (defined($_->pnic)){
1265                                                 foreach my $nic_key (@{$_->pnic})
1266                                                 {
1267                                                         if (!defined($NIC{$nic_key}->linkSpeed))
1268                                                         {
1269                                                                 $output .= ", " if ($output);
1270                                                                 $output .= $NIC{$nic_key}->device . " is unplugged";
1271                                                                 $res = CRITICAL;
1272                                                                 $BadCount++;
1273                                                         }
1274                                                         else
1275                                                         {
1276                                                                 $OKCount++;
1277                                                         }
1278                                                 }
1279                                         }
1280                                 }
1281                         }
1282
1283                         if (!$BadCount)
1284                         {
1285                                 $output = "All $OKCount NICs are connected";
1286                         }
1287                         else
1288                         {
1289                                 $output = $BadCount ."/" . ($BadCount + $OKCount) . " NICs are disconnected: " . $output;
1290                         }
1291                         $np->add_perfdata(label => "OK_NICs", value => $OKCount);
1292                         $np->add_perfdata(label => "Bad_NICs", value => $BadCount);
1293                 }
1294                 else
1295                 {
1296                         $res = CRITICAL;
1297                         $output = "HOST NET - unknown subcommand\n" . $np->opts->_help;
1298                 }
1299         }
1300         else
1301         {
1302                 my $host_view;
1303                 ($host_view, $values) = return_host_performance_values($host, 'net', ('received.average', 'transmitted.average'));
1304                 $output = '';
1305                 if (defined($values))
1306                 {
1307                         my $value1 = simplify_number(convert_number($$values[0][0]->value));
1308                         my $value2 = simplify_number(convert_number($$values[0][1]->value));
1309                         $np->add_perfdata(label => "net_receive", value => $value1, uom => 'KBps', threshold => $np->threshold);
1310                         $np->add_perfdata(label => "net_send", value => $value2, uom => 'KBps', threshold => $np->threshold);
1311                         $res = OK;
1312                         $output = "net receive=" . $value1 . " KBps, send=" . $value2 . " KBps, ";
1313                 }
1314                 $host_view = $$host_view[0];
1315                 $host_view->update_view_data(['configManager.networkSystem']);
1316                 my $network_system = Vim::get_view(mo_ref => $host_view->get_property('configManager.networkSystem') , properties => ['networkInfo']);
1317                 $network_system->update_view_data(['networkInfo']);
1318                 my $network_config = $network_system->networkInfo;
1319                 if (defined($network_config))
1320                 {
1321                         my $OKCount = 0;
1322                         my $BadCount = 0;
1323
1324                         # create a hash of NIC info to facilitate easy lookups
1325                         my %NIC = ();
1326                         foreach (@{$network_config->pnic})
1327                         {
1328                                 $NIC{$_->key} = $_;
1329                         }
1330
1331                         my $nic_output = '';
1332                         my @switches = ();
1333
1334                         push(@switches, $network_config->vswitch) if (exists($network_config->{vswitch}));
1335                         push(@switches, $network_config->proxySwitch) if (exists($network_config->{proxySwitch}));
1336
1337                         # see which NICs are actively part of a switch
1338                         foreach my $switch (@switches)
1339                         {
1340                                 foreach (@{$switch})
1341                                 {
1342                                         # get list of physical nics
1343                                         if (defined($_->pnic)){
1344                                                 foreach my $nic_key (@{$_->pnic})
1345                                                 {
1346                                                         if (!defined($NIC{$nic_key}->linkSpeed))
1347                                                         {
1348                                                                 $nic_output .= ", " if ($output);
1349                                                                 $nic_output .= $NIC{$nic_key}->device . " is unplugged";
1350                                                                 $res = CRITICAL;
1351                                                                 $BadCount++;
1352                                                         }
1353                                                         else
1354                                                         {
1355                                                                 $OKCount++;
1356                                                         }
1357                                                 }
1358                                         }
1359                                 }
1360                         }
1361
1362                         if (!$BadCount)
1363                         {
1364                                 $output .= "all $OKCount NICs are connected";
1365                         }
1366                         else
1367                         {
1368                                 $output .= $BadCount ."/" . ($BadCount + $OKCount) . " NICs are disconnected: " . $nic_output;
1369                         }
1370                         $np->add_perfdata(label => "OK_NICs", value => $OKCount);
1371                         $np->add_perfdata(label => "Bad_NICs", value => $BadCount);
1372                 }
1373         }
1374
1375         return ($res, $output);
1376 }
1377
1378 sub host_disk_io_info
1379 {
1380         my ($host, $np, $subcommand) = @_;
1381
1382         my $res = CRITICAL;
1383         my $output = 'HOST IO Unknown error';
1384
1385         if (defined($subcommand))
1386         {
1387                 if ($subcommand eq "ABORTED")
1388                 {
1389                         $values = return_host_performance_values($host, 'disk', ('commandsAborted.summation:*'));
1390                         if (defined($values))
1391                         {
1392                                 my $value = simplify_number(convert_number($$values[0][0]->value), 0);
1393                                 $np->add_perfdata(label => "io_aborted", value => $value, threshold => $np->threshold);
1394                                 $output = "io commands aborted=" . $value;
1395                                 $res = $np->check_threshold(check => $value);
1396                         }
1397                 }
1398                 elsif ($subcommand eq "RESETS")
1399                 {
1400                         $values = return_host_performance_values($host, 'disk', ('busResets.summation:*'));
1401                         if (defined($values))
1402                         {
1403                                 my $value = simplify_number(convert_number($$values[0][0]->value), 0);
1404                                 $np->add_perfdata(label => "io_busresets", value => $value, threshold => $np->threshold);
1405                                 $output = "io bus resets=" . $value;
1406                                 $res = $np->check_threshold(check => $value);
1407                         }
1408                 }
1409                 elsif ($subcommand eq "READ")
1410                 {
1411                         $values = return_host_performance_values($host, 'disk', ('totalReadLatency.average:*'));
1412                         if (defined($values))
1413                         {
1414                                 my $value = simplify_number(convert_number($$values[0][0]->value), 0);
1415                                 $np->add_perfdata(label => "io_read", value => $value, uom => 'ms', threshold => $np->threshold);
1416                                 $output = "io read latency=" . $value . " ms";
1417                                 $res = $np->check_threshold(check => $value);
1418                         }
1419                 }
1420                 elsif ($subcommand eq "WRITE")
1421                 {
1422                         $values = return_host_performance_values($host, 'disk', ('totalWriteLatency.average:*'));
1423                         if (defined($values))
1424                         {
1425                                 my $value = simplify_number(convert_number($$values[0][0]->value), 0);
1426                                 $np->add_perfdata(label => "io_write", value => $value, uom => 'ms', threshold => $np->threshold);
1427                                 $output = "io write latency=" . $value . " ms";
1428                                 $res = $np->check_threshold(check => $value);
1429                         }
1430                 }
1431                 elsif ($subcommand eq "KERNEL")
1432                 {
1433                         $values = return_host_performance_values($host, 'disk', ('kernelLatency.average:*'));
1434                         if (defined($values))
1435                         {
1436                                 my $value = simplify_number(convert_number($$values[0][0]->value), 0);
1437                                 $np->add_perfdata(label => "io_kernel", value => $value, uom => 'ms', threshold => $np->threshold);
1438                                 $output = "io kernel latency=" . $value . " ms";
1439                                 $res = $np->check_threshold(check => $value);
1440                         }
1441                 }
1442                 elsif ($subcommand eq "DEVICE")
1443                 {
1444                         $values = return_host_performance_values($host, 'disk', ('deviceLatency.average:*'));
1445                         if (defined($values))
1446                         {
1447                                 my $value = simplify_number(convert_number($$values[0][0]->value), 0);
1448                                 $np->add_perfdata(label => "io_device", value => $value, uom => 'ms', threshold => $np->threshold);
1449                                 $output = "io device latency=" . $value . " ms";
1450                                 $res = $np->check_threshold(check => $value);
1451                         }
1452                 }
1453                 elsif ($subcommand eq "QUEUE")
1454                 {
1455                         $values = return_host_performance_values($host, 'disk', ('queueLatency.average:*'));
1456                         if (defined($values))
1457                         {
1458                                 my $value = simplify_number(convert_number($$values[0][0]->value), 0);
1459                                 $np->add_perfdata(label => "io_queue", value => $value, uom => 'ms', threshold => $np->threshold);
1460                                 $output = "io queue latency=" . $value . " ms";
1461                                 $res = $np->check_threshold(check => $value);
1462                         }
1463                 }
1464                 else
1465                 {
1466                         $res = CRITICAL;
1467                         $output = "HOST IO - unknown subcommand\n" . $np->opts->_help;
1468                 }
1469         }
1470         else
1471         {
1472                 $values = return_host_performance_values($host, 'disk', ('commandsAborted.summation:*', 'busResets.summation:*', 'totalReadLatency.average:*', 'totalWriteLatency.average:*', 'kernelLatency.average:*', 'deviceLatency.average:*', 'queueLatency.average:*'));
1473                 if (defined($values))
1474                 {
1475                         my $value1 = simplify_number(convert_number($$values[0][0]->value), 0);
1476                         my $value2 = simplify_number(convert_number($$values[0][1]->value), 0);
1477                         my $value3 = simplify_number(convert_number($$values[0][2]->value), 0);
1478                         my $value4 = simplify_number(convert_number($$values[0][3]->value), 0);
1479                         my $value5 = simplify_number(convert_number($$values[0][4]->value), 0);
1480                         my $value6 = simplify_number(convert_number($$values[0][5]->value), 0);
1481                         my $value7 = simplify_number(convert_number($$values[0][6]->value), 0);
1482                         $np->add_perfdata(label => "io_aborted", value => $value1, threshold => $np->threshold);
1483                         $np->add_perfdata(label => "io_busresets", value => $value2, threshold => $np->threshold);
1484                         $np->add_perfdata(label => "io_read", value => $value3, uom => 'ms', threshold => $np->threshold);
1485                         $np->add_perfdata(label => "io_write", value => $value4, uom => 'ms', threshold => $np->threshold);
1486                         $np->add_perfdata(label => "io_kernel", value => $value5, uom => 'ms', threshold => $np->threshold);
1487                         $np->add_perfdata(label => "io_device", value => $value6, uom => 'ms', threshold => $np->threshold);
1488                         $np->add_perfdata(label => "io_queue", value => $value7, uom => 'ms', threshold => $np->threshold);
1489                         $res = OK;
1490                         $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";
1491                 }
1492         }
1493
1494         return ($res, $output);
1495 }
1496
1497 sub host_list_vm_volumes_info
1498 {
1499         my ($host, $np, $subcommand, $blacklist, $perc, $addopts) = @_;
1500
1501         my $host_view = Vim::find_entity_view(view_type => 'HostSystem', filter => $host, properties => ['name', 'datastore', 'runtime.inMaintenanceMode']);
1502         die "Host \"" . $$host{"name"} . "\" does not exist\n" if (!defined($host_view));
1503         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");
1504         die "Insufficient rights to access Datastores on the Host\n" if (!defined($host_view->datastore));
1505
1506         return datastore_volumes_info($host_view->datastore, $np, $subcommand, $blacklist, $perc, $addopts);
1507 }
1508
1509 sub host_runtime_info
1510 {
1511         my ($host, $np, $subcommand, $blacklist) = @_;
1512
1513         my $res = CRITICAL;
1514         my $output = 'HOST RUNTIME Unknown error';
1515         my $runtime;
1516         my $host_view = Vim::find_entity_view(view_type => 'HostSystem', filter => $host, properties => ['name', 'runtime', 'overallStatus', 'configIssue']);
1517         die "Host \"" . $$host{"name"} . "\" does not exist\n" if (!defined($host_view));
1518         $host_view->update_view_data(['name', 'runtime', 'overallStatus', 'configIssue']);
1519         $runtime = $host_view->runtime;
1520         die {msg => ("NOTICE: \"" . $host_view->name . "\" is in maintenance mode, check skipped\n"), code => OK} if ($runtime->inMaintenanceMode);
1521
1522         if (defined($subcommand))
1523         {
1524                 if ($subcommand eq "CON")
1525                 {
1526                         $output = "connection state=" . $runtime->connectionState->val;
1527                         $res = OK if (uc($runtime->connectionState->val) eq "CONNECTED");
1528                 }
1529                 elsif ($subcommand eq "HEALTH")
1530                 {
1531                         my $OKCount = 0;
1532                         my $AlertCount = 0;
1533                         my ($cpuStatusInfo, $storageStatusInfo, $memoryStatusInfo, $numericSensorInfo);
1534
1535                         $res = UNKNOWN;
1536
1537                         if(defined($runtime->healthSystemRuntime))
1538                         {
1539                                 $cpuStatusInfo = $runtime->healthSystemRuntime->hardwareStatusInfo->cpuStatusInfo;
1540                                 $storageStatusInfo = $runtime->healthSystemRuntime->hardwareStatusInfo->storageStatusInfo;
1541                                 $memoryStatusInfo = $runtime->healthSystemRuntime->hardwareStatusInfo->memoryStatusInfo;
1542                                 $numericSensorInfo = $runtime->healthSystemRuntime->systemHealthInfo->numericSensorInfo;
1543
1544                                 $output = '';
1545
1546                                 if (defined($cpuStatusInfo))
1547                                 {
1548                                         foreach (@$cpuStatusInfo)
1549                                         {
1550                                                 # print "CPU Name = ". $_->name .", Label = ". $_->status->label . ", Summary = ". $_->status->summary . ", Key = ". $_->status->key . "\n";
1551                                                 my $state = check_health_state($_->status->key);
1552                                                 if ($state != OK)
1553                                                 {
1554                                                         $res = Nagios::Plugin::Functions::max_state($res, $state);
1555                                                         $output .= ", " if ($output);
1556                                                         $output .= $_->name . ": " . $_->status->summary;
1557                                                         $AlertCount++;
1558                                                 }
1559                                                 else
1560                                                 {
1561                                                         $OKCount++;
1562                                                 }
1563                                         }
1564                                 }
1565
1566                                 if (defined($storageStatusInfo))
1567                                 {
1568                                         foreach (@$storageStatusInfo)
1569                                         {
1570                                                 # print "Storage Name = ". $_->name .", Label = ". $_->status->label . ", Summary = ". $_->status->summary . ", Key = ". $_->status->key . "\n";
1571                                                 my $state = check_health_state($_->status->key);
1572                                                 if ($state != OK)
1573                                                 {
1574                                                         $res = Nagios::Plugin::Functions::max_state($res, $state);
1575                                                         $output .= ", " if ($output);
1576                                                         $output .= "Storage " . $_->name . ": " . $_->status->summary;
1577                                                         $AlertCount++;
1578                                                 }
1579                                                 else
1580                                                 {
1581                                                         $OKCount++;
1582                                                 }
1583                                         }
1584                                 }
1585
1586                                 if (defined($memoryStatusInfo))
1587                                 {
1588                                         foreach (@$memoryStatusInfo)
1589                                         {
1590                                                 # print "Memory Name = ". $_->name .", Label = ". $_->status->label . ", Summary = ". $_->status->summary . ", Key = ". $_->status->key . "\n";
1591                                                 my $state = check_health_state($_->status->key);
1592                                                 if ($state != OK)
1593                                                 {
1594                                                         $res = Nagios::Plugin::Functions::max_state($res, $state);
1595                                                         $output .= ", " if ($output);
1596                                                         $output .= "Memory: " . $_->status->summary;
1597                                                         $AlertCount++;
1598                                                 }
1599                                                 else
1600                                                 {
1601                                                         $OKCount++;
1602                                                 }
1603                                         }
1604                                 }
1605
1606                                 if (defined($numericSensorInfo))
1607                                 {
1608                                         foreach (@$numericSensorInfo)
1609                                         {
1610                                                 # print "Sensor Name = ". $_->name .", Type = ". $_->sensorType . ", Label = ". $_->healthState->label . ", Summary = ". $_->healthState->summary . ", Key = " . $_->healthState->key . "\n";
1611                                                 my $state = check_health_state($_->healthState->key);
1612                                                 if ($state != OK)
1613                                                 {
1614                                                         $res = Nagios::Plugin::Functions::max_state($res, $state);
1615                                                         $output .= ", " if ($output);
1616                                                         $output .= $_->sensorType . " sensor " . $_->name . ": ".$_->healthState->summary;
1617                                                         $AlertCount++;
1618                                                 }
1619                                                 else
1620                                                 {
1621                                                         $OKCount++;
1622                                                 }
1623                                         }
1624                                 }
1625
1626                                 if ($output)
1627                                 {
1628                                         $output = "$AlertCount health issue(s) found: $output";
1629                                 }
1630                                 else
1631                                 {
1632                                         $output = "All $OKCount health checks are Green";
1633                                         $res = OK;
1634                                 }
1635                         }
1636                         else
1637                         {
1638                                 $res = "System health status unavailable";
1639                         }
1640
1641                         $np->add_perfdata(label => "Alerts", value => $AlertCount);
1642                 }
1643                 elsif ($subcommand eq "MAINTENANCE")
1644                 {
1645                         my %host_maintenance_state = (0 => "no", 1 => "yes");
1646                         $output = "maintenance=" . $host_maintenance_state{$runtime->inMaintenanceMode};
1647                         $res = OK;
1648                 }
1649                 elsif (($subcommand eq "LIST") || ($subcommand eq "LISTVM"))
1650                 {
1651                         my %vm_state_strings = ("poweredOn" => "UP", "poweredOff" => "DOWN", "suspended" => "SUSPENDED");
1652                         my $vm_views = Vim::find_entity_views(view_type => 'VirtualMachine', begin_entity => $host_view, properties => ['name', 'runtime']);
1653                         die "Runtime error\n" if (!defined($vm_views));
1654                         die "There are no VMs.\n" if (!@$vm_views);
1655                         my $up = 0;
1656                         $output = '';
1657
1658                         foreach my $vm (@$vm_views)
1659                         {
1660                                 my $vm_state = $vm_state_strings{$vm->runtime->powerState->val};
1661                                 if ($vm_state eq "UP")
1662                                 {
1663                                         $up++;
1664                                         $output .= $vm->name . "(OK), ";
1665                                 }
1666                                 else
1667                                 {
1668                                         $output = $vm->name . "(" . $vm_state . "), " . $output;
1669                                 }
1670                         }
1671
1672                         chop($output);
1673                         chop($output);
1674                         $res = OK;
1675                         $output = $up . "/" . @$vm_views . " VMs up: " . $output;
1676                         $np->add_perfdata(label => "vmcount", value => $up, uom => 'units', threshold => $np->threshold);
1677                         $res = $np->check_threshold(check => $up) if (defined($np->threshold));
1678                 }
1679                 elsif ($subcommand eq "STATUS")
1680                 {
1681                         my $status = $host_view->overallStatus->val;
1682                         $output = "overall status=" . $status;
1683                         $res = check_health_state($status);
1684                 }
1685                 elsif ($subcommand eq "ISSUES")
1686                 {
1687                         my $issues = $host_view->configIssue;
1688
1689                         $output = '';
1690                         if (defined($issues))
1691                         {
1692                                 foreach (@$issues)
1693                                 {
1694                                         if (defined($blacklist))
1695                                         {
1696                                                 my $name = ref($_);
1697                                                 next if ($blacklist =~ m/(^|\s|\t|,)\Q$name\E($|\s|\t|,)/);
1698                                         }
1699                                         $output .= format_issue($_) . "; ";
1700                                 }
1701                         }
1702
1703                         if ($output eq '')
1704                         {
1705                                 $res = OK;
1706                                 $output = 'No config issues';
1707                         }
1708                 }
1709                 else
1710                 {
1711                         $res = CRITICAL;
1712                         $output = "HOST RUNTIME - unknown subcommand\n" . $np->opts->_help;
1713                 }
1714         }
1715         else
1716         {
1717                 my %host_maintenance_state = (0 => "no", 1 => "yes");
1718                 my $vm_views = Vim::find_entity_views(view_type => 'VirtualMachine', begin_entity => $host_view, properties => ['name', 'runtime']);
1719                 my $up = 0;
1720
1721                 die "Runtime error\n" if (!defined($vm_views));
1722                 if (@$vm_views)
1723                 {
1724                         foreach my $vm (@$vm_views)
1725                         {
1726                                 $up += $vm->runtime->powerState->val eq "poweredOn";
1727                         }
1728                         $output = $up . "/" . @$vm_views . " VMs up";
1729                 }
1730                 else
1731                 {
1732                         $output = "No VMs installed";
1733                 }
1734                 $np->add_perfdata(label => "vmcount", value => $up, uom => 'units', threshold => $np->threshold);
1735
1736                 my $AlertCount = 0;
1737                 my $SensorCount = 0;
1738                 my ($cpuStatusInfo, $storageStatusInfo, $memoryStatusInfo, $numericSensorInfo);
1739                 if(defined($runtime->healthSystemRuntime))
1740                 {
1741                         $cpuStatusInfo = $runtime->healthSystemRuntime->hardwareStatusInfo->cpuStatusInfo;
1742                         $storageStatusInfo = $runtime->healthSystemRuntime->hardwareStatusInfo->storageStatusInfo;
1743                         $memoryStatusInfo = $runtime->healthSystemRuntime->hardwareStatusInfo->memoryStatusInfo;
1744                         $numericSensorInfo = $runtime->healthSystemRuntime->systemHealthInfo->numericSensorInfo;
1745                 }
1746
1747                 if (defined($cpuStatusInfo))
1748                 {
1749                         foreach (@$cpuStatusInfo)
1750                         {
1751                                 $SensorCount++;
1752                                 $AlertCount++ if (check_health_state($_->status->key) != OK);
1753                         }
1754                 }
1755
1756                 if (defined($storageStatusInfo))
1757                 {
1758                         foreach (@$storageStatusInfo)
1759                         {
1760                                 $SensorCount++;
1761                                 $AlertCount++ if (check_health_state($_->status->key) != OK);
1762                         }
1763                 }
1764
1765                 if (defined($memoryStatusInfo))
1766                 {
1767                         foreach (@$memoryStatusInfo)
1768                         {
1769                                 $SensorCount++;
1770                                 $AlertCount++ if (check_health_state($_->status->key) != OK);
1771                         }
1772                 }
1773
1774                 if (defined($numericSensorInfo))
1775                 {
1776                         foreach (@$numericSensorInfo)
1777                         {
1778                                 $SensorCount++;
1779                                 $AlertCount++ if (check_health_state($_->healthState->key) != OK);
1780                         }
1781                 }
1782
1783                 $res = OK;
1784                 $output .= ", overall status=" . $host_view->overallStatus->val . ", connection state=" . $runtime->connectionState->val . ", maintenance=" . $host_maintenance_state{$runtime->inMaintenanceMode} . ", ";
1785
1786                 if ($AlertCount)
1787                 {
1788                         $output .= "$AlertCount health issue(s), ";
1789                 }
1790                 else
1791                 {
1792                         $output .= "All $SensorCount health checks are Green, ";
1793                 }
1794                 $np->add_perfdata(label => "health_issues", value => $AlertCount);
1795
1796                 my $issues = $host_view->configIssue;
1797                 if (defined($issues))
1798                 {
1799                         $output .= @$issues . " config issue(s)";
1800                         $np->add_perfdata(label => "config_issues", value => "" . @$issues);
1801                 }
1802                 else
1803                 {
1804                         $output .= "no config issues";
1805                         $np->add_perfdata(label => "config_issues", value => 0);
1806                 }
1807         }
1808
1809         return ($res, $output);
1810 }
1811
1812 sub host_service_info
1813 {
1814         my ($host, $np, $subcommand) = @_;
1815
1816         my $res = CRITICAL;
1817         my $output = 'HOST RUNTIME Unknown error';
1818         my $host_view = Vim::find_entity_view(view_type => 'HostSystem', filter => $host, properties => ['name', 'configManager', 'runtime.inMaintenanceMode']);
1819         die "Host \"" . $$host{"name"} . "\" does not exist\n" if (!defined($host_view));
1820         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");
1821
1822         my $services = Vim::get_view(mo_ref => $host_view->configManager->serviceSystem, properties => ['serviceInfo'])->serviceInfo->service;
1823
1824         if (defined($subcommand))
1825         {
1826                 $subcommand = ',' . $subcommand . ',';
1827                 $output = '';
1828                 foreach (@$services)
1829                 {
1830                         my $srvname = $_->key;
1831                         if ($subcommand =~ s/,$srvname,/,/g)
1832                         {
1833                                 while ($subcommand =~ s/,$srvname,/,/g){};
1834                                 $output .= $srvname . ", " if (!$_->running);
1835                         }
1836                 }
1837                 $subcommand =~ s/^,//;
1838                 chop($subcommand);
1839
1840                 if ($subcommand ne '')
1841                 {
1842                         $res = UNKNOWN;
1843                         $output = "unknown services : $subcommand";
1844                 }
1845                 elsif ($output eq '')
1846                 {
1847                         $res = OK;
1848                         $output = "All services are in their apropriate state.";
1849                 }
1850                 else
1851                 {
1852                         chop($output);
1853                         chop($output);
1854                         $output .= " are down";
1855                 }
1856         }
1857         else
1858         {
1859                 my %service_state = (0 => "down", 1 => "up");
1860                 $res = OK;
1861                 $output = "services : ";
1862                 $output .= $_->key . " (" . $service_state{$_->running} . "), " foreach (@$services);
1863                 chop($output);
1864                 chop($output);
1865         }
1866
1867         return ($res, $output);
1868 }
1869
1870 sub host_storage_info
1871 {
1872         my ($host, $np, $subcommand, $blacklist) = @_;
1873
1874         my $count = 0;
1875         my $res = CRITICAL;
1876         my $output = 'HOST RUNTIME Unknown error';
1877         my $host_view = Vim::find_entity_view(view_type => 'HostSystem', filter => $host, properties => ['name', 'configManager', 'runtime.inMaintenanceMode']);
1878         die "Host \"" . $$host{"name"} . "\" does not exist\n" if (!defined($host_view));
1879         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");
1880
1881         my $storage = Vim::get_view(mo_ref => $host_view->configManager->storageSystem, properties => ['storageDeviceInfo']);
1882
1883         if (defined($subcommand))
1884         {
1885                 if ($subcommand eq "ADAPTER")
1886                 {
1887                         $output = "";
1888                         $res = OK;
1889                         foreach my $dev (@{$storage->storageDeviceInfo->hostBusAdapter})
1890                         {
1891                                 my $name = $dev->device;
1892                                 my $status = $dev->status;
1893                                 if (defined($blacklist))
1894                                 {
1895                                         my $key = $dev->key;
1896                                         if (($blacklist =~ m/(^|\s|\t|,)\Q$name\E($|\s|\t|,)/) || ($blacklist =~ m/(^|\s|\t|,)\Q$key\E($|\s|\t|,)/))
1897                                         {
1898                                                 $count++;
1899                                                 $status = "ignored";
1900                                         }
1901                                 }
1902                                 $count ++ if (uc($status) eq "ONLINE");
1903                                 $res = UNKNOWN if (uc($status) eq "UNKNOWN");
1904                                 $output .= $name . " (" . $status . "); ";
1905                         }
1906                         my $state = $np->check_threshold(check => $count);
1907                         $res = $state if ($state != OK);
1908                         $np->add_perfdata(label => "adapters", value => $count, uom => 'units', threshold => $np->threshold);
1909                 }
1910                 elsif ($subcommand eq "LUN")
1911                 {
1912                         $output = "";
1913                         $res = OK;
1914                         my $state = OK; # For unkonwn or other statuses
1915                         foreach my $scsi (@{$storage->storageDeviceInfo->scsiLun})
1916                         {
1917                                 my $name = "";
1918                                 if (exists($scsi->{displayName}))
1919                                 {
1920                                         $name = $scsi->displayName;
1921                                 }
1922                                 elsif (exists($scsi->{canonicalName}))
1923                                 {
1924                                         $name = $scsi->canonicalName;
1925                                 }
1926                                 else
1927                                 {
1928                                         $name = $scsi->deviceName;
1929                                 }
1930                                 $state = OK;
1931
1932                                 my $operationState;
1933                                 if (defined($blacklist) && ($blacklist =~ m/(^|\s|\t|,)\Q$name\E($|\s|\t|,)/))
1934                                 {
1935                                         $operationState = "ignored";
1936                                 }
1937                                 else
1938                                 {
1939                                         $operationState = join("-", @{$scsi->operationalState});
1940                                         foreach (@{$scsi->operationalState})
1941                                         {
1942                                                 if (uc($_) eq "OK")
1943                                                 {
1944                                                         # $state = OK;
1945                                                 }
1946                                                 elsif (uc($_) eq "UNKNOWN")
1947                                                 {
1948                                                         $res = UNKNOWN;
1949                                                 }
1950                                                 elsif (uc($_) eq "UNKNOWNSTATE")
1951                                                 {
1952                                                         $res = UNKNOWN;
1953                                                 }
1954                                                 else
1955                                                 {
1956                                                         $state = CRITICAL;
1957                                                 }
1958                                         }
1959                                 }
1960
1961                                 $count++ if ($state == OK);
1962                                 $output .= $name . " <" . $operationState . ">; ";
1963                         }
1964                         $np->add_perfdata(label => "LUNs", value => $count, uom => 'units', threshold => $np->threshold);
1965                         $state = $np->check_threshold(check => $count);
1966                         $res = $state if ($state != OK);
1967                 }
1968                 elsif ($subcommand eq "PATH")
1969                 {
1970                         if (exists($storage->storageDeviceInfo->{multipathInfo}))
1971                         {
1972                                 $output = "";
1973                                 $res = OK;
1974                                 foreach my $lun (@{$storage->storageDeviceInfo->multipathInfo->lun})
1975                                 {
1976                                         foreach my $path (@{$lun->path})
1977                                         {
1978                                                 my $status = UNKNOWN; # For unknown or other statuses
1979                                                 my $pathState = "unknown";
1980                                                 my $name = $path->name;
1981
1982                                                 if (exists($path->{state}))
1983                                                 {
1984                                                         $pathState = $path->state;
1985                                                 }
1986                                                 else
1987                                                 {
1988                                                         $pathState = $path->pathState;
1989                                                 }
1990
1991                                                 if (defined($blacklist) && ($blacklist =~ m/(^|\s|\t|,)\Q$name\E($|\s|\t|,)/))
1992                                                 {
1993                                                         $pathState = "ignored";
1994                                                         $count++;
1995                                                 }
1996
1997                                                 $count++ if (uc($pathState) eq "ACTIVE");
1998                                                 $res = UNKNOWN if (uc($pathState) eq "UNKNOWN");
1999                                                 $output .= $name . " <" . $pathState . ">; ";
2000                                         }
2001                                 }
2002                                 $np->add_perfdata(label => "paths", value => $count, uom => 'units', threshold => $np->threshold);
2003                                 my $state = $np->check_threshold(check => $count);
2004                                 $res = $state if ($state != OK);
2005                         }
2006                         else
2007                         {
2008                                 $output = "path info is unavailable on this host";
2009                                 $res = UNKNOWN;
2010                         }
2011                 }
2012                 else
2013                 {
2014                         $res = CRITICAL;
2015                         $output = "HOST STORAGE - unknown subcommand\n" . $np->opts->_help;
2016                 }
2017         }
2018         else
2019         {
2020                 my $status = UNKNOWN;
2021                 my $state = OK;
2022                 $output = "";
2023                 $res = OK;
2024                 foreach my $dev (@{$storage->storageDeviceInfo->hostBusAdapter})
2025                 {
2026                         $status = UNKNOWN;
2027                         if (uc($dev->status) eq "ONLINE")
2028                         {
2029                                 $status = OK;
2030                                 $count++;
2031                         }
2032                         elsif (uc($dev->status) eq "OFFLINE")
2033                         {
2034                                 $status = CRITICAL;
2035                         }
2036                         elsif (uc($dev->status) eq "FAULT")
2037                         {
2038                                 $status = CRITICAL;
2039                         }
2040                         else
2041                         {
2042                                 $res = UNKNOWN;
2043                         }
2044                         $state = Nagios::Plugin::Functions::max_state($state, $status);
2045                 }
2046                 $np->add_perfdata(label => "adapters", value => $count, uom => 'units', threshold => $np->threshold);
2047                 $output .= $count . "/" . @{$storage->storageDeviceInfo->hostBusAdapter} . " adapters online, ";
2048
2049                 $count = 0;
2050                 foreach my $scsi (@{$storage->storageDeviceInfo->scsiLun})
2051                 {
2052                         $status = UNKNOWN;
2053                         foreach (@{$scsi->operationalState})
2054                         {
2055                                 if (uc($_) eq "OK")
2056                                 {
2057                                         $status = OK;
2058                                         $count++;
2059                                 }
2060                                 elsif (uc($_) eq "ERROR")
2061                                 {
2062                                         $status = CRITICAL;
2063                                 }
2064                                 elsif (uc($_) eq "UNKNOWNSTATE")
2065                                 {
2066                                         $status = UNKNOWN;
2067                                 }
2068                                 elsif (uc($_) eq "OFF")
2069                                 {
2070                                         $status = CRITICAL;
2071                                 }
2072                                 elsif (uc($_) eq "QUIESCED")
2073                                 {
2074                                         $status = WARNING;
2075                                 }
2076                                 elsif (uc($_) eq "DEGRADED")
2077                                 {
2078                                         $status = WARNING;
2079                                 }
2080                                 elsif (uc($_) eq "LOSTCOMMUNICATION")
2081                                 {
2082                                         $status = CRITICAL;
2083                                 }
2084                                 else
2085                                 {
2086                                         $res = UNKNOWN;
2087                                         $status = UNKNOWN;
2088                                 }
2089                                 $state = Nagios::Plugin::Functions::max_state($state, $status);
2090                         }
2091                 }
2092                 $np->add_perfdata(label => "LUNs", value => $count, uom => 'units', threshold => $np->threshold);
2093                 $output .= $count . "/" . @{$storage->storageDeviceInfo->scsiLun} . " LUNs ok, ";
2094
2095                 if (exists($storage->storageDeviceInfo->{multipathInfo}))
2096                 {
2097                         $count = 0;
2098                         my $amount = 0;
2099                         foreach my $lun (@{$storage->storageDeviceInfo->multipathInfo->lun})
2100                         {
2101                                 foreach my $path (@{$lun->path})
2102                                 {
2103                                         my $status = UNKNOWN; # For unkonwn or other statuses
2104                                         my $pathState = "unknown";
2105                                         if (exists($path->{state}))
2106                                         {
2107                                                 $pathState = $path->state;
2108                                         }
2109                                         else
2110                                         {
2111                                                 $pathState = $path->pathState;
2112                                         }
2113
2114                                         $status = UNKNOWN;
2115                                         if (uc($pathState) eq "ACTIVE")
2116                                         {
2117                                                 $status = OK;
2118                                                 $count++;
2119                                         }
2120                                         elsif (uc($pathState) eq "DISABLED")
2121                                         {
2122                                                 $status = WARNING;
2123                                         }
2124                                         elsif (uc($pathState) eq "STANDBY")
2125                                         {
2126                                                 $status = WARNING;
2127                                         }
2128                                         elsif (uc($pathState) eq "DEAD")
2129                                         {
2130                                                 $status = CRITICAL;
2131                                         }
2132                                         else
2133                                         {
2134                                                 $res = UNKNOWN;
2135                                                 $status = UNKNOWN;
2136                                         }
2137                                         $state = Nagios::Plugin::Functions::max_state($state, $status);
2138                                         $amount++;
2139                                 }
2140                         }
2141                         $np->add_perfdata(label => "paths", value => $count, uom => 'units', threshold => $np->threshold);
2142                         $output .= $count . "/" . $amount . " paths active";
2143                 }
2144                 else
2145                 {
2146                         $output .= "no path info";
2147                 }
2148
2149                 $res = $state if ($state != OK);
2150         }
2151
2152         return ($res, $output);
2153 }
2154 #==========================================================================| VM |============================================================================#
2155
2156 sub vm_cpu_info
2157 {
2158         my ($vmname, $np, $subcommand) = @_;
2159
2160         my $res = CRITICAL;
2161         my $output = 'HOST-VM CPU Unknown error';
2162
2163         if (defined($subcommand))
2164         {
2165                 if ($subcommand eq "USAGE")
2166                 {
2167                         $values = return_host_vmware_performance_values($vmname, 'cpu', ('usage.average'));
2168                         if (defined($values))
2169                         {
2170                                 my $value = simplify_number(convert_number($$values[0][0]->value) * 0.01);
2171                                 $np->add_perfdata(label => "cpu_usage", value => $value, uom => '%', threshold => $np->threshold);
2172                                 $output = "\"$vmname\" cpu usage=" . $value . " %"; 
2173                                 $res = $np->check_threshold(check => $value);
2174                         }
2175                 }
2176                 elsif ($subcommand eq "USAGEMHZ")
2177                 {
2178                         $values = return_host_vmware_performance_values($vmname, 'cpu', ('usagemhz.average'));
2179                         if (defined($values))
2180                         {
2181                                 my $value = simplify_number(convert_number($$values[0][0]->value));
2182                                 $np->add_perfdata(label => "cpu_usagemhz", value => $value, uom => 'Mhz', threshold => $np->threshold);
2183                                 $output = "\"$vmname\" cpu usage=" . $value . " MHz";
2184                                 $res = $np->check_threshold(check => $value);
2185                         }
2186                 }
2187                 elsif ($subcommand eq "WAIT")
2188                 {
2189                         $values = return_host_vmware_performance_values($vmname, 'cpu', ('wait.summation:*'));
2190                         if (defined($values))
2191                         {
2192                                 my $value = simplify_number(convert_number($$values[0][0]->value));
2193                                 $np->add_perfdata(label => "cpu_wait", value => $value, uom => 'ms', threshold => $np->threshold);
2194                                 $output = "\"$vmname\" cpu wait=" . $value . " ms";
2195                                 $res = $np->check_threshold(check => $value);
2196                         }
2197                 }
2198                 elsif ($subcommand eq "READY")
2199                 {
2200                         $values = return_host_vmware_performance_values($vmname, 'cpu', ('ready.summation:*'));
2201                         if (defined($values))
2202                         {
2203                                 my $value = simplify_number(convert_number($$values[0][0]->value));
2204                                 $np->add_perfdata(label => "cpu_ready", value => $value, uom => 'ms', threshold => $np->threshold);
2205                                 $output = "\"$vmname\" cpu ready=" . $value . " ms";
2206                                 $res = $np->check_threshold(check => $value);
2207                         }
2208                 }
2209                 else
2210                 {
2211                         $res = CRITICAL;
2212                         $output = "HOST-VM CPU - unknown subcommand\n" . $np->opts->_help;
2213                 }
2214         }
2215         else
2216         {
2217                 $values = return_host_vmware_performance_values($vmname, 'cpu', ('usagemhz.average', 'usage.average', 'wait.summation:*', 'ready.summation:*'));
2218                 if (defined($values))
2219                 {
2220                         my $value1 = simplify_number(convert_number($$values[0][0]->value));
2221                         my $value2 = simplify_number(convert_number($$values[0][1]->value) * 0.01);
2222                         my $value3 = simplify_number(convert_number($$values[0][2]->value));
2223                         my $value4 = simplify_number(convert_number($$values[0][3]->value));
2224                         $np->add_perfdata(label => "cpu_usagemhz", value => $value1, uom => 'Mhz', threshold => $np->threshold);
2225                         $np->add_perfdata(label => "cpu_usage", value => $value2, uom => '%', threshold => $np->threshold);
2226                         $np->add_perfdata(label => "cpu_wait", value => $value3, uom => 'ms', threshold => $np->threshold);
2227                         $np->add_perfdata(label => "cpu_ready", value => $value4, uom => 'ms', threshold => $np->threshold);
2228                         $res = OK;
2229                         $output = "\"$vmname\" cpu usage=" . $value1 . " MHz(" . $value2 . "%), wait=" . $value3 . " ms, ready=" . $value4 . " ms";
2230                 }
2231         }
2232
2233         return ($res, $output);
2234 }
2235
2236 sub vm_mem_info
2237 {
2238         my ($vmname, $np, $subcommand) = @_;
2239
2240         my $res = CRITICAL;
2241         my $output = 'HOST-VM MEM Unknown error';
2242
2243         if (defined($subcommand))
2244         {
2245                 if ($subcommand eq "USAGE")
2246                 {
2247                         $values = return_host_vmware_performance_values($vmname, 'mem', ('usage.average'));
2248                         if (defined($values))
2249                         {
2250                                 my $value = simplify_number(convert_number($$values[0][0]->value) * 0.01);
2251                                 $np->add_perfdata(label => "mem_usage", value => $value, uom => '%', threshold => $np->threshold);
2252                                 $output = "\"$vmname\" mem usage=" . $value . " %"; 
2253                                 $res = $np->check_threshold(check => $value);
2254                         }
2255                 }
2256                 elsif ($subcommand eq "USAGEMB")
2257                 {
2258                         $values = return_host_vmware_performance_values($vmname, 'mem', ('consumed.average'));
2259                         if (defined($values))
2260                         {
2261                                 my $value = simplify_number(convert_number($$values[0][0]->value) / 1024);
2262                                 $np->add_perfdata(label => "mem_usagemb", value => $value, uom => 'MB', threshold => $np->threshold);
2263                                 $output = "\"$vmname\" mem usage=" . $value . " MB";
2264                                 $res = $np->check_threshold(check => $value);
2265                         }
2266                 }
2267                 elsif ($subcommand eq "SWAP")
2268                 {
2269                         $values = return_host_vmware_performance_values($vmname, 'mem', ('swapped.average'));
2270                         if (defined($values))
2271                         {
2272                                 my $value = simplify_number(convert_number($$values[0][0]->value) / 1024);
2273                                 $np->add_perfdata(label => "mem_swap", value => $value, uom => 'MB', threshold => $np->threshold);
2274                                 $output = "\"$vmname\" swap usage=" . $value . " MB";
2275                                 $res = $np->check_threshold(check => $value);
2276                         }
2277                 }
2278                 elsif ($subcommand eq "SWAPIN")
2279                 {
2280                         $values = return_host_vmware_performance_values($vmname, 'mem', ('swapin.average'));
2281                         if (defined($values))
2282                         {
2283                                 my $value = simplify_number(convert_number($$values[0][0]->value) / 1024);
2284                                 $np->add_perfdata(label => "mem_swapin", value => $value, uom => 'MB', threshold => $np->threshold);
2285                                 $output = "\"$vmname\" swapin=" . $value . " MB";
2286                                 $res = $np->check_threshold(check => $value);
2287                         }
2288                 }
2289                 elsif ($subcommand eq "SWAPOUT")
2290                 {
2291                         $values = return_host_vmware_performance_values($vmname, 'mem', ('swapout.average'));
2292                         if (defined($values))
2293                         {
2294                                 my $value = simplify_number(convert_number($$values[0][0]->value) / 1024);
2295                                 $np->add_perfdata(label => "mem_swapout", value => $value, uom => 'MB', threshold => $np->threshold);
2296                                 $output = "\"$vmname\" swapout=" . $value . " MB";
2297                                 $res = $np->check_threshold(check => $value);
2298                         }
2299                 }
2300                 elsif ($subcommand eq "OVERHEAD")
2301                 {
2302                         $values = return_host_vmware_performance_values($vmname, 'mem', ('overhead.average'));
2303                         if (defined($values))
2304                         {
2305                                 my $value = simplify_number(convert_number($$values[0][0]->value) / 1024);
2306                                 $np->add_perfdata(label => "mem_overhead", value => $value, uom => 'MB', threshold => $np->threshold);
2307                                 $output = "\"$vmname\" mem overhead=" . $value . " MB";
2308                                 $res = $np->check_threshold(check => $value);
2309                         }
2310                 }
2311                 elsif ($subcommand eq "OVERALL")
2312                 {
2313                         $values = return_host_vmware_performance_values($vmname, 'mem', ('consumed.average', 'overhead.average'));
2314                         if (defined($values))
2315                         {
2316                                 my $value = simplify_number((convert_number($$values[0][0]->value) + convert_number($$values[0][1]->value)) / 1024);
2317                                 $np->add_perfdata(label => "mem_overall", value => $value, uom => 'MB', threshold => $np->threshold);
2318                                 $output = "\"$vmname\" mem overall=" . $value . " MB";
2319                                 $res = $np->check_threshold(check => $value);
2320                         }
2321                 }
2322                 elsif ($subcommand eq "ACTIVE")
2323                 {
2324                         $values = return_host_vmware_performance_values($vmname, 'mem', ('active.average'));
2325                         if (defined($values))
2326                         {
2327                                 my $value = simplify_number(convert_number($$values[0][0]->value) / 1024);
2328                                 $np->add_perfdata(label => "mem_active", value => $value, uom => 'MB', threshold => $np->threshold);
2329                                 $output = "\"$vmname\" mem active=" . $value . " MB";
2330                                 $res = $np->check_threshold(check => $value);
2331                         }
2332                 }
2333                 elsif ($subcommand eq "MEMCTL")
2334                 {
2335                         $values = return_host_vmware_performance_values($vmname, 'mem', ('vmmemctl.average'));
2336                         if (defined($values))
2337                         {
2338                                 my $value = simplify_number(convert_number($$values[0][0]->value) / 1024);
2339                                 $np->add_perfdata(label => "mem_memctl", value => $value, uom => 'MB', threshold => $np->threshold);
2340                                 $output = "\"$vmname\" mem memctl=" . $value . " MB";
2341                                 $res = $np->check_threshold(check => $value);
2342                         }
2343                 }
2344                 else
2345                 {
2346                         $res = CRITICAL;
2347                         $output = "HOST-VM MEM - unknown subcommand\n" . $np->opts->_help;
2348                 }
2349         }
2350         else
2351         {
2352                 $values = return_host_vmware_performance_values($vmname, 'mem', ('consumed.average', 'usage.average', 'overhead.average', 'active.average', 'swapped.average', 'swapin.average', 'swapout.average', 'vmmemctl.average'));
2353                 if (defined($values))
2354                 {
2355                         my $value1 = simplify_number(convert_number($$values[0][0]->value) / 1024);
2356                         my $value2 = simplify_number(convert_number($$values[0][1]->value) * 0.01);
2357                         my $value3 = simplify_number(convert_number($$values[0][2]->value) / 1024);
2358                         my $value4 = simplify_number(convert_number($$values[0][3]->value) / 1024);
2359                         my $value5 = simplify_number(convert_number($$values[0][4]->value) / 1024);
2360                         my $value6 = simplify_number(convert_number($$values[0][5]->value) / 1024);
2361                         my $value7 = simplify_number(convert_number($$values[0][6]->value) / 1024);
2362                         my $value8 = simplify_number(convert_number($$values[0][7]->value) / 1024);
2363                         $np->add_perfdata(label => "mem_usagemb", value => $value1, uom => 'MB', threshold => $np->threshold);
2364                         $np->add_perfdata(label => "mem_usage", value => $value2, uom => '%', threshold => $np->threshold);
2365                         $np->add_perfdata(label => "mem_overhead", value => $value3, uom => 'MB', threshold => $np->threshold);
2366                         $np->add_perfdata(label => "mem_active", value => $value4, uom => 'MB', threshold => $np->threshold);
2367                         $np->add_perfdata(label => "mem_swap", value => $value5, uom => 'MB', threshold => $np->threshold);
2368                         $np->add_perfdata(label => "mem_swapin", value => $value6, uom => 'MB', threshold => $np->threshold);
2369                         $np->add_perfdata(label => "mem_swapout", value => $value7, uom => 'MB', threshold => $np->threshold);
2370                         $np->add_perfdata(label => "mem_memctl", value => $value8, uom => 'MB', threshold => $np->threshold);
2371                         $res = OK;
2372                         $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";
2373                 }
2374         }
2375
2376         return ($res, $output);
2377 }
2378
2379 sub vm_net_info
2380 {
2381         my ($vmname, $np, $subcommand) = @_;
2382
2383         my $res = CRITICAL;
2384         my $output = 'HOST-VM NET Unknown error';
2385
2386         if (defined($subcommand))
2387         {
2388                 if ($subcommand eq "USAGE")
2389                 {
2390                         $values = return_host_vmware_performance_values($vmname, 'net', ('usage.average:*'));
2391                         if (defined($values))
2392                         {
2393                                 my $value = simplify_number(convert_number($$values[0][0]->value));
2394                                 $np->add_perfdata(label => "net_usage", value => $value, uom => 'KBps', threshold => $np->threshold);
2395                                 $output = "\"$vmname\" net usage=" . $value . " KBps"; 
2396                                 $res = $np->check_threshold(check => $value);
2397                         }
2398                 }
2399                 elsif ($subcommand eq "RECEIVE")
2400                 {
2401                         $values = return_host_vmware_performance_values($vmname, 'net', ('received.average:*'));
2402                         if (defined($values))
2403                         {
2404                                 my $value = simplify_number(convert_number($$values[0][0]->value));
2405                                 $np->add_perfdata(label => "net_receive", value => $value, uom => 'KBps', threshold => $np->threshold);
2406                                 $output = "\"$vmname\" net receive=" . $value . " KBps"; 
2407                                 $res = $np->check_threshold(check => $value);
2408                         }
2409                 }
2410                 elsif ($subcommand eq "SEND")
2411                 {
2412                         $values = return_host_vmware_performance_values($vmname, 'net', ('transmitted.average:*'));
2413                         if (defined($values))
2414                         {
2415                                 my $value = simplify_number(convert_number($$values[0][0]->value));
2416                                 $np->add_perfdata(label => "net_send", value => $value, uom => 'KBps', threshold => $np->threshold);
2417                                 $output = "\"$vmname\" net send=" . $value . " KBps"; 
2418                                 $res = $np->check_threshold(check => $value);
2419                         }
2420                 }
2421                 else
2422                 {
2423                         $res = CRITICAL;
2424                         $output = "HOST-VM NET - unknown subcommand\n" . $np->opts->_help;
2425                 }
2426         }
2427         else
2428         {
2429                 $values = return_host_vmware_performance_values($vmname, 'net', ('received.average:*', 'transmitted.average:*'));
2430                 if (defined($values))
2431                 {
2432                         my $value1 = simplify_number(convert_number($$values[0][0]->value));
2433                         my $value2 = simplify_number(convert_number($$values[0][1]->value));
2434                         $np->add_perfdata(label => "net_receive", value => $value1, uom => 'KBps', threshold => $np->threshold);
2435                         $np->add_perfdata(label => "net_send", value => $value2, uom => 'KBps', threshold => $np->threshold);
2436                         $res = OK;
2437                         $output = "\"$vmname\" net receive=" . $value1 . " KBps, send=" . $value2 . " KBps";
2438                 }
2439         }
2440
2441         return ($res, $output);
2442 }
2443
2444 sub vm_disk_io_info
2445 {
2446         my ($vmname, $np, $subcommand) = @_;
2447
2448         my $res = CRITICAL;
2449         my $output = 'HOST-VM IO Unknown error';
2450
2451         if (defined($subcommand))
2452         {
2453                 if ($subcommand eq "USAGE")
2454                 {
2455                         $values = return_host_vmware_performance_values($vmname, 'disk', ('usage.average:*'));
2456                         if (defined($values))
2457                         {
2458                                 my $value = simplify_number(convert_number($$values[0][0]->value) / 1024);
2459                                 $np->add_perfdata(label => "io_usage", value => $value, uom => 'MB', threshold => $np->threshold);
2460                                 $output = "\"$vmname\" io usage=" . $value . " MB";
2461                                 $res = $np->check_threshold(check => $value);
2462                         }
2463                 }
2464                 elsif ($subcommand eq "READ")
2465                 {
2466                         $values = return_host_vmware_performance_values($vmname, 'disk', ('read.average:*'));
2467                         if (defined($values))
2468                         {
2469                                 my $value = simplify_number(convert_number($$values[0][0]->value) / 1024);
2470                                 $np->add_perfdata(label => "io_read", value => $value, uom => 'MB/s', threshold => $np->threshold);
2471                                 $output = "\"$vmname\" io read=" . $value . " MB/s";
2472                                 $res = $np->check_threshold(check => $value);
2473                         }
2474                 }
2475                 elsif ($subcommand eq "WRITE")
2476                 {
2477                         $values = return_host_vmware_performance_values($vmname, 'disk', ('write.average:*'));
2478                         if (defined($values))
2479                         {
2480                                 my $value = simplify_number(convert_number($$values[0][0]->value) / 1024);
2481                                 $np->add_perfdata(label => "io_write", value => $value, uom => 'MB/s', threshold => $np->threshold);
2482                                 $output = "\"$vmname\" io write=" . $value . " MB/s";
2483                                 $res = $np->check_threshold(check => $value);
2484                         }
2485                 }
2486                 else
2487                 {
2488                         $res = CRITICAL;
2489                         $output = "HOST IO - unknown subcommand\n" . $np->opts->_help;
2490                 }
2491         }
2492         else
2493         {
2494                 $values = return_host_vmware_performance_values($vmname, 'disk', ('usage.average:*', 'read.average:*', 'write.average:*'));
2495                 if (defined($values))
2496                 {
2497                         my $value1 = simplify_number(convert_number($$values[0][0]->value) / 1024);
2498                         my $value2 = simplify_number(convert_number($$values[0][1]->value) / 1024);
2499                         my $value3 = simplify_number(convert_number($$values[0][2]->value) / 1024);
2500                         $np->add_perfdata(label => "io_usage", value => $value1, uom => 'MB', threshold => $np->threshold);
2501                         $np->add_perfdata(label => "io_read", value => $value2, uom => 'MB/s', threshold => $np->threshold);
2502                         $np->add_perfdata(label => "io_write", value => $value3, uom => 'MB/s', threshold => $np->threshold);
2503                         $res = OK;
2504                         $output = "\"$vmname\" io usage=" . $value1 . " MB, read=" . $value2 . " MB/s, write=" . $value3 . " MB/s";
2505                 }
2506         }
2507
2508         return ($res, $output);
2509 }
2510
2511 sub vm_runtime_info
2512 {
2513         my ($vmname, $np, $subcommand) = @_;
2514
2515         my $res = CRITICAL;
2516         my $output = 'HOST-VM RUNTIME Unknown error';
2517         my $runtime;
2518         my $vm_view = Vim::find_entity_view(view_type => 'VirtualMachine', filter => {name => $vmname}, properties => ['name', 'runtime', 'overallStatus', 'guest', 'configIssue']);
2519         die "VMware machine \"" . $vmname . "\" does not exist\n" if (!defined($vm_view));
2520         $runtime = $vm_view->runtime;
2521
2522         if (defined($subcommand))
2523         {
2524                 if ($subcommand eq "CON")
2525                 {
2526                         $output = "\"$vmname\" connection state=" . $runtime->connectionState->val;
2527                         $res = OK if ($runtime->connectionState->val eq "connected");
2528                 }
2529                 elsif ($subcommand eq "CPU")
2530                 {
2531                         $output = "\"$vmname\" max cpu=" . $runtime->maxCpuUsage . " MHz";
2532                         $res = OK;
2533                 }
2534                 elsif ($subcommand eq "MEM")
2535                 {
2536                         $output = "\"$vmname\" max mem=" . $runtime->maxMemoryUsage . " MB";
2537                         $res = OK;
2538                 }
2539                 elsif ($subcommand eq "STATE")
2540                 {
2541                         my %vm_state_strings = ("poweredOn" => "UP", "poweredOff" => "DOWN", "suspended" => "SUSPENDED");
2542                         my $state = $vm_state_strings{$runtime->powerState->val};
2543                         $output = "\"$vmname\" run state=" . $state;
2544                         $res = OK if ($state eq "UP");
2545                 }
2546                 elsif ($subcommand eq "STATUS")
2547                 {
2548                         my $status = $vm_view->overallStatus->val;
2549                         $output = "\"$vmname\" overall status=" . $status;
2550                         $res = check_health_state($status);
2551                 }
2552                 elsif ($subcommand eq "CONSOLECONNECTIONS")
2553                 {
2554                         $output = "\"$vmname\" console connections=" . $runtime->numMksConnections;
2555                         $res = $np->check_threshold(check => $runtime->numMksConnections);
2556                 }
2557                 elsif ($subcommand eq "GUEST")
2558                 {
2559                         my %vm_guest_state = ("running" => "Running", "notRunning" => "Not running", "shuttingDown" => "Shutting down", "resetting" => "Resetting", "standby" => "Standby", "unknown" => "Unknown");
2560                         my $state = $vm_guest_state{$vm_view->guest->guestState};
2561                         $output = "\"$vmname\" guest state=" . $state;
2562                         $res = OK if ($state eq "Running");
2563                 }
2564                 elsif ($subcommand eq "TOOLS")
2565                 {
2566                         my $tools_status;
2567                         my $tools_runstate;
2568                         my $tools_version;
2569                         $tools_runstate = $vm_view->guest->toolsRunningStatus if (exists($vm_view->guest->{toolsRunningStatus}) && defined($vm_view->guest->toolsRunningStatus));
2570                         $tools_version = $vm_view->guest->toolsVersionStatus if (exists($vm_view->guest->{toolsVersionStatus}) && defined($vm_view->guest->toolsVersionStatus));
2571
2572                         if (defined($tools_runstate) || defined($tools_version))
2573                         {
2574                                 my %vm_tools_strings = ("guestToolsCurrent" => "Newest", "guestToolsNeedUpgrade" => "Old", "guestToolsNotInstalled" => "Not installed", "guestToolsUnmanaged" => "Unmanaged", "guestToolsExecutingScripts" => "Starting", "guestToolsNotRunning" => "Not running", "guestToolsRunning" => "Running");
2575                                 $tools_status = $vm_tools_strings{$tools_runstate} . "-" if (defined($tools_runstate));
2576                                 $tools_status .= $vm_tools_strings{$tools_version} . "-" if (defined($tools_version));
2577                                 chop($tools_status);
2578                                 $res = OK if (($tools_status eq "Running-Newest") || ($tools_status eq "Running-Unmanaged"));
2579                         }
2580                         else
2581                         {
2582                                 my %vm_tools_strings = ("toolsNotInstalled" => "Not installed", "toolsNotRunning" => "Not running", "toolsOk" => "OK", "toolsOld" => "Old", "notDefined" => "Not defined");
2583                                 $tools_status = $vm_view->guest->toolsStatus;
2584                                 if (defined($tools_status))
2585                                 {
2586                                         $tools_status = $vm_tools_strings{$tools_status->val};
2587                                 }
2588                                 else
2589                                 {
2590                                         $tools_status = $vm_tools_strings{"notDefined"};
2591                                 }
2592                                 $res = OK if ($tools_status eq "OK");
2593                         }
2594                         $output = "\"$vmname\" tools status=" . $tools_status;
2595                 }
2596                 elsif ($subcommand eq "ISSUES")
2597                 {
2598                         my $issues = $vm_view->configIssue;
2599
2600                         if (defined($issues))
2601                         {
2602                                 $output = "\"$vmname\": ";
2603                                 foreach (@$issues)
2604                                 {
2605                                         $output .= $_->fullFormattedMessage . "(caused by " . $_->userName . "); ";
2606                                 }
2607                         }
2608                         else
2609                         {
2610                                 $res = OK;
2611                                 $output = "\"$vmname\" has no config issues";
2612                         }
2613                 }
2614                 else
2615                 {
2616                         $res = CRITICAL;
2617                         $output = "HOST-VM RUNTIME - unknown subcommand\n" . $np->opts->_help;
2618                 }
2619         }
2620         else
2621         {
2622                 my %vm_state_strings = ("poweredOn" => "UP", "poweredOff" => "DOWN", "suspended" => "SUSPENDED");
2623                 my %vm_tools_status = ("toolsNotInstalled" => "Not installed", "toolsNotRunning" => "Not running", "toolsOk" => "OK", "toolsOld" => "Old");
2624                 my %vm_guest_state = ("running" => "Running", "notRunning" => "Not running", "shuttingDown" => "Shutting down", "resetting" => "Resetting", "standby" => "Standby", "unknown" => "Unknown");
2625                 $res = OK;
2626                 $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} . ", ";
2627                 my $issues = $vm_view->configIssue;
2628                 if (defined($issues))
2629                 {
2630                         $output .= @$issues . " config issue(s)";
2631                 }
2632                 else
2633                 {
2634                         $output .= "has no config issues";
2635                 }
2636         }
2637
2638         return ($res, $output);
2639 }
2640
2641 #==========================================================================| DC |============================================================================#
2642
2643 sub return_cluster_DRS_recommendations {
2644         my ($np, $cluster_name) = @_;
2645         my $res = OK;
2646         my $output;
2647         my @clusters;
2648
2649         if (defined($cluster_name))
2650         {
2651                 my $cluster = Vim::find_entity_view(view_type => 'ClusterComputeResource', filter => $cluster_name, properties => ['name', 'recommendation']);
2652                 die "cluster \"" . $$cluster_name{"name"} . "\" does not exist\n" if (!defined($cluster));
2653                 push(@clusters, $cluster);
2654         }
2655         else
2656         {
2657                 my $cluster = Vim::find_entity_views(view_type => 'ClusterComputeResource', properties => ['name', 'recommendation']);
2658                 die "Runtime error\n" if (!defined($cluster));
2659                 die "There are no clusters\n" if (!@$cluster);
2660                 @clusters = @$cluster;
2661         }
2662
2663         my $rec_count = 0;
2664         foreach my $cluster_view (@clusters)
2665         {
2666                 my ($recommends) = $cluster_view->recommendation;
2667                 if (defined($recommends))
2668                 {
2669                         my $value = 0;
2670                         foreach my $recommend (@$recommends)
2671                         {
2672                                 $value = $recommend->rating if ($recommend->rating > $value);
2673                                 $output .= "(" . $recommend->rating . ") " . $recommend->reason . " : " . $recommend->reasonText . "; ";
2674                         }
2675                         $rec_count += @$recommends;
2676                         $res = $np->check_threshold(check => $value);
2677                 }
2678         }
2679
2680         if (defined($output))
2681         {
2682                 $output = "Recommendations:" . $output;
2683         }
2684         else
2685         {
2686                 $output = "No recommendations";
2687         }
2688
2689         $np->add_perfdata(label => "recommendations", value => $rec_count);
2690
2691         return ($res, $output);
2692 }
2693
2694 sub dc_cpu_info
2695 {
2696         my ($np, $subcommand, $addopts) = @_;
2697
2698         my $res = CRITICAL;
2699         my $output = 'DC CPU Unknown error';
2700
2701         my $quickStats;
2702         $quickStats = $addopts =~ m/(^|\s|\t|,)\Qquickstats\E($|\s|\t|,)/ if (defined($addopts));
2703
2704         if (defined($subcommand))
2705         {
2706                 if ($subcommand eq "USAGE")
2707                 {
2708                         my $value;
2709                         if (defined($quickStats))
2710                         {
2711                                 my $host_views = Vim::find_entity_views(view_type => 'HostSystem', properties => ['name', 'summary.hardware', 'summary.quickStats']);
2712                                 die "Runtime error\n" if (!defined($host_views));
2713                                 die "Datacenter does not contain any hosts\n" if (!@$host_views);
2714                                 foreach my $host_view (@$host_views)
2715                                 {
2716                                         $values = $host_view->get_property('summary.quickStats');
2717                                         my $hardinfo = $host_view->get_property('summary.hardware');
2718                                         die "Can not retrieve required information from Host '" . $host_view->name . "'\n" if !(exists($values->{overallCpuUsage}) && defined($hardinfo));
2719                                         $value += $values->overallCpuUsage / ($hardinfo->numCpuCores * $hardinfo->cpuMhz) * 100;
2720                                 }
2721                                 $value = simplify_number($value / @$host_views);
2722                         }
2723                         else
2724                         {
2725                                 $values = return_dc_performance_values('cpu', ('usage.average'));
2726                                 grep($value += convert_number($$_[0]->value) * 0.01, @$values) if (defined($values));
2727                                 $value = simplify_number($value / @$values) if (defined($value));
2728                         }
2729                         if (defined($value))
2730                         {
2731                                 $np->add_perfdata(label => "cpu_usage", value => $value, uom => '%', threshold => $np->threshold);
2732                                 $output = "cpu usage=" . $value . " %"; 
2733                                 $res = $np->check_threshold(check => $value);
2734                         }
2735                 }
2736                 elsif ($subcommand eq "USAGEMHZ")
2737                 {
2738                         my $value;
2739                         if (defined($quickStats))
2740                         {
2741                                 my $host_views = Vim::find_entity_views(view_type => 'HostSystem', properties => ['name', 'summary.quickStats']);
2742                                 die "Runtime error\n" if (!defined($host_views));
2743                                 die "Datacenter does not contain any hosts\n" if (!@$host_views);
2744                                 foreach my $host_view (@$host_views)
2745                                 {
2746                                         $values = $host_view->get_property('summary.quickStats');
2747                                         die "Can not retrieve required information from Host '" . $host_view->name . "'\n" if !(exists($values->{overallCpuUsage}));
2748                                         $value += $values->overallCpuUsage;
2749                                 }
2750                                 $value = simplify_number($value);
2751                         }
2752                         else
2753                         {
2754                                 $values = return_dc_performance_values('cpu', ('usagemhz.average'));
2755                                 grep($value += convert_number($$_[0]->value), @$values);
2756                                 $value = simplify_number($value) if (defined($value));
2757                         }
2758                         if (defined($value))
2759                         {
2760                                 $np->add_perfdata(label => "cpu_usagemhz", value => $value, uom => 'Mhz', threshold => $np->threshold);
2761                                 $output = "cpu usagemhz=" . $value . " MHz";
2762                                 $res = $np->check_threshold(check => $value);
2763                         }
2764                 }
2765                 else
2766                 {
2767                         $res = CRITICAL;
2768                         $output = "DC CPU - unknown subcommand\n" . $np->opts->_help;
2769                 }
2770         }
2771         else
2772         {
2773                 my $value1 = 0;
2774                 my $value2 = 0;
2775                 if (defined($quickStats))
2776                 {
2777                         my $host_views = Vim::find_entity_views(view_type => 'HostSystem', properties => ['name', 'summary.hardware', 'summary.quickStats']);
2778                         die "Runtime error\n" if (!defined($host_views));
2779                         die "Datacenter does not contain any hosts\n" if (!@$host_views);
2780                         foreach my $host_view (@$host_views)
2781                         {
2782                                 $values = $host_view->get_property('summary.quickStats');
2783                                 my $hardinfo = $host_view->get_property('summary.hardware');
2784                                 die "Can not retrieve required information from Host '" . $host_view->name . "'\n" if !(exists($values->{overallCpuUsage}) && defined($hardinfo));
2785                                 $value1 += $values->overallCpuUsage;
2786                                 $value2 += $values->overallCpuUsage / ($hardinfo->numCpuCores * $hardinfo->cpuMhz) * 100;
2787                         }
2788                         $value1 = simplify_number($value1);
2789                         $value2 = simplify_number($value2 / @$host_views);
2790                 }
2791                 else
2792                 {
2793                         $values = return_dc_performance_values('cpu', ('usagemhz.average', 'usage.average'));
2794                         grep($value1 += convert_number($$_[0]->value), @$values);
2795                         grep($value2 += convert_number($$_[1]->value) * 0.01, @$values);
2796                         $value1 = simplify_number($value1);
2797                         $value2 = simplify_number($value2 / @$values);
2798                 }
2799                 if (defined($value1) && defined($value2))
2800                 {
2801                         $np->add_perfdata(label => "cpu_usagemhz", value => $value1, uom => 'Mhz', threshold => $np->threshold);
2802                         $np->add_perfdata(label => "cpu_usage", value => $value2, uom => '%', threshold => $np->threshold);
2803                         $res = OK;
2804                         $output = "cpu usage=" . $value1 . " MHz (" . $value2 . "%)";
2805                 }
2806         }
2807
2808         return ($res, $output);
2809 }
2810
2811 sub dc_mem_info
2812 {
2813         my ($np, $subcommand, $addopts) = @_;
2814
2815         my $res = CRITICAL;
2816         my $output = 'DC MEM Unknown error';
2817
2818         my $quickStats;
2819         $quickStats = $addopts =~ m/(^|\s|\t|,)\Qquickstats\E($|\s|\t|,)/ if (defined($addopts));
2820
2821         if (defined($subcommand))
2822         {
2823                 if ($subcommand eq "USAGE")
2824                 {
2825                         my $value;
2826                         if (defined($quickStats))
2827                         {
2828                                 my $host_views = Vim::find_entity_views(view_type => 'HostSystem', properties => ['name', 'summary.hardware', 'summary.quickStats']);
2829                                 die "Runtime error\n" if (!defined($host_views));
2830                                 die "Datacenter does not contain any hosts\n" if (!@$host_views);
2831                                 foreach my $host_view (@$host_views)
2832                                 {
2833                                         $values = $host_view->get_property('summary.quickStats');
2834                                         my $hardinfo = $host_view->get_property('summary.hardware');
2835                                         die "Can not retrieve required information from Host '" . $host_view->name . "'\n" if !(exists($values->{overallMemoryUsage}) && defined($hardinfo));
2836                                         $value += $values->overallMemoryUsage / ($hardinfo->memorySize / 1024 / 1024) * 100;
2837                                 }
2838                                 $value = simplify_number($value);
2839                         }
2840                         else
2841                         {
2842                                 $values = return_dc_performance_values('mem', ('usage.average'));
2843                                 grep($value += convert_number($$_[0]->value) * 0.01, @$values);
2844                                 $value = simplify_number($value / @$values) if (defined($value));
2845                         }
2846                         if (defined($value))
2847                         {
2848                                 $np->add_perfdata(label => "mem_usage", value => $value, uom => '%', threshold => $np->threshold);
2849                                 $output = "mem usage=" . $value . " %"; 
2850                                 $res = $np->check_threshold(check => $value);
2851                         }
2852                 }
2853                 elsif ($subcommand eq "USAGEMB")
2854                 {
2855                         my $value;
2856                         if (defined($quickStats))
2857                         {
2858                                 my $host_views = Vim::find_entity_views(view_type => 'HostSystem', properties => ['name', 'summary.quickStats']);
2859                                 die "Runtime error\n" if (!defined($host_views));
2860                                 die "Datacenter does not contain any hosts\n" if (!@$host_views);
2861                                 foreach my $host_view (@$host_views)
2862                                 {
2863                                         $values = $host_view->get_property('summary.quickStats');
2864                                         die "Can not retrieve required information from Host '" . $host_view->name . "'\n" if !(exists($values->{overallMemoryUsage}));
2865                                         $value += $values->overallMemoryUsage;
2866                                 }
2867                                 $value = simplify_number($value);
2868                         }
2869                         else
2870                         {
2871                                 $values = return_dc_performance_values('mem', ('consumed.average'));
2872                                 grep($value += convert_number($$_[0]->value) / 1024, @$values);
2873                                 $value = simplify_number($value) if (defined($value));
2874                         }
2875                         if (defined($value))
2876                         {
2877                                 $np->add_perfdata(label => "mem_usagemb", value => $value, uom => 'MB', threshold => $np->threshold);
2878                                 $output = "mem usage=" . $value . " MB";
2879                                 $res = $np->check_threshold(check => $value);
2880                         }
2881                 }
2882                 elsif ($subcommand eq "SWAP")
2883                 {
2884                         $values = return_dc_performance_values('mem', ('swapused.average'));
2885                         if (defined($values))
2886                         {
2887                                 my $value = 0;
2888                                 grep($value += convert_number($$_[0]->value) / 1024, @$values);
2889                                 $value = simplify_number($value);
2890                                 $np->add_perfdata(label => "mem_swap", value => $value, uom => 'MB', threshold => $np->threshold);
2891                                 $output = "swap usage=" . $value . " MB";
2892                                 $res = $np->check_threshold(check => $value);
2893                         }
2894                 }
2895                 elsif ($subcommand eq "OVERHEAD")
2896                 {
2897                         $values = return_dc_performance_values('mem', ('overhead.average'));
2898                         if (defined($values))
2899                         {
2900                                 my $value = 0;
2901                                 grep($value += convert_number($$_[0]->value) / 1024, @$values);
2902                                 $value = simplify_number($value);
2903                                 $np->add_perfdata(label => "mem_overhead", value => $value, uom => 'MB', threshold => $np->threshold);
2904                                 $output = "overhead=" . $value . " MB";
2905                                 $res = $np->check_threshold(check => $value);
2906                         }
2907                 }
2908                 elsif ($subcommand eq "OVERALL")
2909                 {
2910                         $values = return_dc_performance_values('mem', ('consumed.average', 'overhead.average'));
2911                         if (defined($values))
2912                         {
2913                                 my $value = 0;
2914                                 grep($value += (convert_number($$_[0]->value) + convert_number($$_[1]->value)) / 1024, @$values);
2915                                 $value = simplify_number($value);
2916                                 $np->add_perfdata(label => "mem_overall", value => $value, uom => 'MB', threshold => $np->threshold);
2917                                 $output = "overall=" . $value . " MB";
2918                                 $res = $np->check_threshold(check => $value);
2919                         }
2920                 }
2921                 elsif ($subcommand eq "MEMCTL")
2922                 {
2923                         $values = return_dc_performance_values('mem', ('vmmemctl.average'));
2924                         if (defined($values))
2925                         {
2926                                 my $value = 0;
2927                                 grep($value += convert_number($$_[0]->value) / 1024, @$values);
2928                                 $value = simplify_number($value);
2929                                 $np->add_perfdata(label => "mem_memctl", value => $value, uom => 'MB', threshold => $np->threshold);
2930                                 $output = "memctl=" . $value . " MB";
2931                                 $res = $np->check_threshold(check => $value);
2932                         }
2933                 }
2934                 else
2935                 {
2936                         $res = CRITICAL;
2937                         $output = "DC MEM - unknown subcommand\n" . $np->opts->_help;
2938                 }
2939         }
2940         else
2941         {
2942                 $values = return_dc_performance_values('mem', ('consumed.average', 'usage.average', 'overhead.average', 'swapused.average', 'vmmemctl.average'));
2943                 if (defined($values))
2944                 {
2945                         my $value1 = 0;
2946                         my $value2 = 0;
2947                         my $value3 = 0;
2948                         my $value4 = 0;
2949                         my $value5 = 0;
2950                         grep($value1 += convert_number($$_[0]->value) / 1024, @$values);
2951                         grep($value2 += convert_number($$_[1]->value) * 0.01, @$values);
2952                         grep($value3 += convert_number($$_[2]->value) / 1024, @$values);
2953                         grep($value4 += convert_number($$_[3]->value) / 1024, @$values);
2954                         grep($value5 += convert_number($$_[4]->value) / 1024, @$values);
2955                         $value1 = simplify_number($value1);
2956                         $value2 = simplify_number($value2 / @$values);
2957                         $value3 = simplify_number($value3);
2958                         $value4 = simplify_number($value4);
2959                         $value5 = simplify_number($value5);
2960                         $np->add_perfdata(label => "mem_usagemb", value => $value1, uom => 'MB', threshold => $np->threshold);
2961                         $np->add_perfdata(label => "mem_usage", value => $value2, uom => '%', threshold => $np->threshold);
2962                         $np->add_perfdata(label => "mem_overhead", value => $value3, uom => 'MB', threshold => $np->threshold);
2963                         $np->add_perfdata(label => "mem_swap", value => $value4, uom => 'MB', threshold => $np->threshold);
2964                         $np->add_perfdata(label => "mem_memctl", value => $value5, uom => 'MB', threshold => $np->threshold);
2965                         $res = OK;
2966                         $output = "mem usage=" . $value1 . " MB (" . $value2 . "%), overhead=" . $value3 . " MB, swapped=" . $value4 . " MB, memctl=" . $value5 . " MB";
2967                 }
2968         }
2969
2970         return ($res, $output);
2971 }
2972
2973 sub dc_net_info
2974 {
2975         my ($np, $subcommand) = @_;
2976
2977         my $res = CRITICAL;
2978         my $output = 'DC NET Unknown error';
2979
2980         if (defined($subcommand))
2981         {
2982                 if ($subcommand eq "USAGE")
2983                 {
2984                         $values = return_dc_performance_values('net', ('usage.average:*'));
2985                         if (defined($values))
2986                         {
2987                                 my $value = 0;
2988                                 grep($value += convert_number($$_[0]->value), @$values);
2989                                 $value = simplify_number($value);
2990                                 $np->add_perfdata(label => "net_usage", value => $value, uom => 'KBps', threshold => $np->threshold);
2991                                 $output = "net usage=" . $value . " KBps"; 
2992                                 $res = $np->check_threshold(check => $value);
2993                         }
2994                 }
2995                 elsif ($subcommand eq "RECEIVE")
2996                 {
2997                         $values = return_dc_performance_values('net', ('received.average:*'));
2998                         if (defined($values))
2999                         {
3000                                 my $value = 0;
3001                                 grep($value += convert_number($$_[0]->value), @$values);
3002                                 $value = simplify_number($value);
3003                                 $np->add_perfdata(label => "net_receive", value => $value, uom => 'KBps', threshold => $np->threshold);
3004                                 $output = "net receive=" . $value . " KBps"; 
3005                                 $res = $np->check_threshold(check => $value);
3006                         }
3007                 }
3008                 elsif ($subcommand eq "SEND")
3009                 {
3010                         $values = return_dc_performance_values('net', ('transmitted.average:*'));
3011                         if (defined($values))
3012                         {
3013                                 my $value = 0;
3014                                 grep($value += convert_number($$_[0]->value), @$values);
3015                                 $value = simplify_number($value);
3016                                 $np->add_perfdata(label => "net_send", value => $value, uom => 'KBps', threshold => $np->threshold);
3017                                 $output = "net send=" . $value . " KBps"; 
3018                                 $res = $np->check_threshold(check => $value);
3019                         }
3020                 }
3021                 else
3022                 {
3023                         $res = CRITICAL;
3024                         $output = "DC NET - unknown subcommand\n" . $np->opts->_help;
3025                 }
3026         }
3027         else
3028         {
3029                 $values = return_dc_performance_values('net', ('received.average:*', 'transmitted.average:*'));
3030                 if (defined($values))
3031                 {
3032                         my $value1 = 0;
3033                         my $value2 = 0;
3034                         grep($value1 += convert_number($$_[0]->value), @$values);
3035                         grep($value2 += convert_number($$_[1]->value), @$values);
3036                         $value1 = simplify_number($value1);
3037                         $value2 = simplify_number($value2);
3038                         $np->add_perfdata(label => "net_receive", value => $value1, uom => 'KBps', threshold => $np->threshold);
3039                         $np->add_perfdata(label => "net_send", value => $value2, uom => 'KBps', threshold => $np->threshold);
3040                         $res = OK;
3041                         $output = "net receive=" . $value1 . " KBps, send=" . $value2 . " KBps";
3042                 }
3043         }
3044
3045         return ($res, $output);
3046 }
3047
3048 sub dc_list_vm_volumes_info
3049 {
3050         my ($np, $subcommand, $blacklist, $perc, $addopts) = @_;
3051
3052         my $host_views = Vim::find_entity_views(view_type => 'HostSystem', properties => ['name', 'datastore']);
3053         die "Runtime error\n" if (!defined($host_views));
3054         die "Datacenter does not contain any hosts\n" if (!@$host_views);
3055
3056         my @datastores;
3057         foreach my $host (@$host_views)
3058         {
3059                 push(@datastores, @{$host->datastore});
3060         }
3061         return datastore_volumes_info(\@datastores, $np, $subcommand, $blacklist, $perc, $addopts);
3062 }
3063
3064 sub dc_disk_io_info
3065 {
3066         my ($np, $subcommand) = @_;
3067
3068         my $res = CRITICAL;
3069         my $output = 'DC IO Unknown error';
3070
3071         if (defined($subcommand))
3072         {
3073                 if ($subcommand eq "ABORTED")
3074                 {
3075                         $values = return_dc_performance_values('disk', ('commandsAborted.summation:*'));
3076                         if (defined($values))
3077                         {
3078                                 my $value = 0;
3079                                 grep($value += convert_number($$_[0]->value), @$values);
3080                                 $value = simplify_number($value, 0);
3081                                 $np->add_perfdata(label => "io_aborted", value => $value, threshold => $np->threshold);
3082                                 $output = "io commands aborted=" . $value;
3083                                 $res = $np->check_threshold(check => $value);
3084                         }
3085                 }
3086                 elsif ($subcommand eq "RESETS")
3087                 {
3088                         $values = return_dc_performance_values('disk', ('busResets.summation:*'));
3089                         if (defined($values))
3090                         {
3091                                 my $value = 0;
3092                                 grep($value += convert_number($$_[0]->value), @$values);
3093                                 $value = simplify_number($value, 0);
3094                                 $np->add_perfdata(label => "io_busresets", value => $value, threshold => $np->threshold);
3095                                 $output = "io bus resets=" . $value;
3096                                 $res = $np->check_threshold(check => $value);
3097                         }
3098                 }
3099                 elsif ($subcommand eq "READ")
3100                 {
3101                         $values = return_dc_performance_values('disk', ('totalReadLatency.average:*'));
3102                         if (defined($values))
3103                         {
3104                                 my $value = 0;
3105                                 grep($value += convert_number($$_[0]->value), @$values);
3106                                 $value = simplify_number($value, 0);
3107                                 $np->add_perfdata(label => "io_read", value => $value, uom => 'ms', threshold => $np->threshold);
3108                                 $output = "io read latency=" . $value . " ms";
3109                                 $res = $np->check_threshold(check => $value);
3110                         }
3111                 }
3112                 elsif ($subcommand eq "WRITE")
3113                 {
3114                         $values = return_dc_performance_values('disk', ('totalWriteLatency.average:*'));
3115                         if (defined($values))
3116                         {
3117                                 my $value = 0;
3118                                 grep($value += convert_number($$_[0]->value), @$values);
3119                                 $value = simplify_number($value, 0);
3120                                 $np->add_perfdata(label => "io_write", value => $value, uom => 'ms', threshold => $np->threshold);
3121                                 $output = "io write latency=" . $value . " ms";
3122                                 $res = $np->check_threshold(check => $value);
3123                         }
3124                 }
3125                 elsif ($subcommand eq "KERNEL")
3126                 {
3127                         $values = return_dc_performance_values('disk', ('kernelLatency.average:*'));
3128                         if (defined($values))
3129                         {
3130                                 my $value = 0;
3131                                 grep($value += convert_number($$_[0]->value), @$values);
3132                                 $value = simplify_number($value, 0);
3133                                 $np->add_perfdata(label => "io_kernel", value => $value, uom => 'ms', threshold => $np->threshold);
3134                                 $output = "io kernel latency=" . $value . " ms";
3135                                 $res = $np->check_threshold(check => $value);
3136                         }
3137                 }
3138                 elsif ($subcommand eq "DEVICE")
3139                 {
3140                         $values = return_dc_performance_values('disk', ('deviceLatency.average:*'));
3141                         if (defined($values))
3142                         {
3143                                 my $value = 0;
3144                                 grep($value += convert_number($$_[0]->value), @$values);
3145                                 $value = simplify_number($value, 0);
3146                                 $np->add_perfdata(label => "io_device", value => $value, uom => 'ms', threshold => $np->threshold);
3147                                 $output = "io device latency=" . $value . " ms";
3148                                 $res = $np->check_threshold(check => $value);
3149                         }
3150                 }
3151                 elsif ($subcommand eq "QUEUE")
3152                 {
3153                         $values = return_dc_performance_values('disk', ('queueLatency.average:*'));
3154                         if (defined($values))
3155                         {
3156                                 my $value = 0;
3157                                 grep($value += convert_number($$_[0]->value), @$values);
3158                                 $value = simplify_number($value, 0);
3159                                 $np->add_perfdata(label => "io_queue", value => $value, uom => 'ms', threshold => $np->threshold);
3160                                 $output = "io queue latency=" . $value . " ms";
3161                                 $res = $np->check_threshold(check => $value);
3162                         }
3163                 }
3164                 else
3165                 {
3166                         $res = CRITICAL;
3167                         $output = "DC IO - unknown subcommand\n" . $np->opts->_help;
3168                 }
3169         }
3170         else
3171         {
3172                 $values = return_dc_performance_values('disk', ('commandsAborted.summation:*', 'busResets.summation:*', 'totalReadLatency.average:*', 'totalWriteLatency.average:*', 'kernelLatency.average:*', 'deviceLatency.average:*', 'queueLatency.average:*'));
3173                 if (defined($values))
3174                 {
3175                         my $value1 = 0;
3176                         my $value2 = 0;
3177                         my $value3 = 0;
3178                         my $value4 = 0;
3179                         my $value5 = 0;
3180                         my $value6 = 0;
3181                         my $value7 = 0;
3182                         grep($value1 += convert_number($$_[0]->value), @$values);
3183                         grep($value2 += convert_number($$_[1]->value), @$values);
3184                         grep($value3 += convert_number($$_[2]->value), @$values);
3185                         grep($value4 += convert_number($$_[3]->value), @$values);
3186                         grep($value5 += convert_number($$_[4]->value), @$values);
3187                         grep($value6 += convert_number($$_[5]->value), @$values);
3188                         grep($value7 += convert_number($$_[6]->value), @$values);
3189                         $value1 = simplify_number($value1, 0);
3190                         $value2 = simplify_number($value2, 0);
3191                         $value3 = simplify_number($value3, 0);
3192                         $value4 = simplify_number($value4, 0);
3193                         $value5 = simplify_number($value5, 0);
3194                         $value6 = simplify_number($value6, 0);
3195                         $value7 = simplify_number($value7, 0);
3196                         $np->add_perfdata(label => "io_aborted", value => $value1, threshold => $np->threshold);
3197                         $np->add_perfdata(label => "io_busresets", value => $value2, threshold => $np->threshold);
3198                         $np->add_perfdata(label => "io_read", value => $value3, uom => 'ms', threshold => $np->threshold);
3199                         $np->add_perfdata(label => "io_write", value => $value4, uom => 'ms', threshold => $np->threshold);
3200                         $np->add_perfdata(label => "io_kernel", value => $value5, uom => 'ms', threshold => $np->threshold);
3201                         $np->add_perfdata(label => "io_device", value => $value6, uom => 'ms', threshold => $np->threshold);
3202                         $np->add_perfdata(label => "io_queue", value => $value7, uom => 'ms', threshold => $np->threshold);
3203                         $res = OK;
3204                         $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";
3205                 }
3206         }
3207
3208         return ($res, $output);
3209 }
3210
3211 sub dc_runtime_info
3212 {
3213         my ($np, $subcommand, $blacklist) = @_;
3214
3215         my $res = CRITICAL;
3216         my $output = 'DC RUNTIME Unknown error';
3217         my $runtime;
3218         my $dc_view = Vim::find_entity_view(view_type => 'Datacenter', properties => ['name', 'overallStatus', 'configIssue']);
3219
3220         die "There are no Datacenter\n" if (!defined($dc_view));
3221
3222         if (defined($subcommand))
3223         {
3224                 if (($subcommand eq "LIST") || ($subcommand eq "LISTVM"))
3225                 {
3226                         my %vm_state_strings = ("poweredOn" => "UP", "poweredOff" => "DOWN", "suspended" => "SUSPENDED");
3227                         my $vm_views = Vim::find_entity_views(view_type => 'VirtualMachine', properties => ['name', 'runtime']);
3228                         die "Runtime error\n" if (!defined($vm_views));
3229                         die "There are no VMs.\n" if (!@$vm_views);
3230                         my $up = 0;
3231                         $output = '';
3232
3233                         foreach my $vm (@$vm_views) {
3234                                 my $vm_state = $vm_state_strings{$vm->runtime->powerState->val};
3235                                 if ($vm_state eq "UP")
3236                                 {
3237                                         $up++;
3238                                         $output .= $vm->name . "(UP), ";
3239                                 }
3240                                 else
3241                                 {
3242                                         $output = $vm->name . "(" . $vm_state . "), " . $output;
3243                                 }
3244                         }
3245
3246                         chop($output);
3247                         chop($output);
3248                         $res = OK;
3249                         $output = $up . "/" . @$vm_views . " VMs up: " . $output;
3250                         $np->add_perfdata(label => "vmcount", value => $up, uom => 'units', threshold => $np->threshold);
3251                         $res = $np->check_threshold(check => $up) if (defined($np->threshold));
3252                 }
3253                 elsif ($subcommand eq "LISTHOST")
3254                 {
3255                         my %host_state_strings = ("unknown" => "UNKNOWN", "poweredOn" => "UP", "poweredOff" => "DOWN", "suspended" => "SUSPENDED", "standBy" => "STANDBY", "MaintenanceMode" => "Maintenance Mode");
3256                         my $host_views = Vim::find_entity_views(view_type => 'HostSystem', properties => ['name', 'runtime.powerState']);
3257                         die "Runtime error\n" if (!defined($host_views));
3258                         die "There are no VMs.\n" if (!@$host_views);
3259                         my $up = 0;
3260                         my $unknown = 0;
3261                         $output = '';
3262
3263                         foreach my $host (@$host_views) {
3264                                 $host->update_view_data(['name', 'runtime.powerState']);
3265                                 my $host_state = $host_state_strings{$host->get_property('runtime.powerState')->val};
3266                                 $unknown += $host_state eq "UNKNOWN";
3267                                 if ($host_state eq "UP") {
3268                                         $up++;
3269                                         $output .= $host->name . "(UP), ";
3270                                 } else
3271                                 {
3272                                         $output = $host->name . "(" . $host_state . "), " . $output;
3273                                 }
3274                         }
3275
3276                         chop($output);
3277                         chop($output);
3278                         $res = OK;
3279                         $output = $up . "/" . @$host_views . " Hosts up: " . $output;
3280                         $np->add_perfdata(label => "hostcount", value => $up, uom => 'units', threshold => $np->threshold);
3281                         $res = $np->check_threshold(check => $up) if (defined($np->threshold));
3282                         $res = UNKNOWN if ($res == OK && $unknown);
3283                 }
3284                 elsif ($subcommand eq "TOOLS")
3285                 {
3286                         my $vm_views = Vim::find_entity_views(view_type => 'VirtualMachine', properties => ['name', 'runtime.powerState', 'summary.guest']);
3287                         die "Runtime error\n" if (!defined($vm_views));
3288                         die "There are no VMs.\n" if (!@$vm_views);
3289                         $output = '';
3290                         my $tools_ok = 0;
3291                         my $vms_up = 0;
3292                         foreach my $vm (@$vm_views) {
3293                                 my $name = $vm->name;
3294                                 if (defined($blacklist))
3295                                 {
3296                                         next if ($blacklist =~ m/(^|\s|\t|,)\Q$name\E($|\s|\t|,)/);
3297                                 }
3298                                 if ($vm->get_property('runtime.powerState')->val eq "poweredOn")
3299                                 {
3300                                         my $vm_guest = $vm->get_property('summary.guest');
3301                                         my $tools_status;
3302                                         my $tools_runstate;
3303                                         my $tools_version;
3304                                         $tools_runstate = $vm_guest->toolsRunningStatus if (exists($vm_guest->{toolsRunningStatus}) && defined($vm_guest->toolsRunningStatus));
3305                                         $tools_version = $vm_guest->toolsVersionStatus if (exists($vm_guest->{toolsVersionStatus}) && defined($vm_guest->toolsVersionStatus));
3306
3307                                         $vms_up++;
3308                                         if (defined($tools_runstate) || defined($tools_version))
3309                                         {
3310                                                 my %vm_tools_strings = ("guestToolsCurrent" => "Newest", "guestToolsNeedUpgrade" => "Old", "guestToolsNotInstalled" => "Not installed", "guestToolsUnmanaged" => "Unmanaged", "guestToolsExecutingScripts" => "Starting", "guestToolsNotRunning" => "Not running", "guestToolsRunning" => "Running");
3311                                                 $tools_status = $vm_tools_strings{$tools_runstate} . "-" if (defined($tools_runstate));
3312                                                 $tools_status .= $vm_tools_strings{$tools_version} . "-" if (defined($tools_version));
3313                                                 chop($tools_status);
3314                                                 if ($tools_status eq "Running-Newest")
3315                                                 {
3316                                                         $output .= $name . "(Running-Newest), ";
3317                                                         $tools_ok++;
3318                                                 }
3319                                                 else
3320                                                 {
3321                                                         $output = $name . "(" . $tools_status . "), " . $output;
3322                                                 }
3323                                         }
3324                                         else
3325                                         {
3326                                                 my %vm_tools_strings = ("toolsNotInstalled" => "Not installed", "toolsNotRunning" => "Not running", "toolsOk" => "OK", "toolsOld" => "Old", "notDefined" => "Not defined");
3327                                                 $tools_status = $vm_guest->toolsStatus;
3328                                                 if (defined($tools_status))
3329                                                 {
3330                                                         $tools_status = $vm_tools_strings{$tools_status->val};
3331                                                         if ($tools_status eq "OK")
3332                                                         {
3333                                                                 $output .= $name . "(OK), ";
3334                                                                 $tools_ok++;
3335                                                         }
3336                                                         else
3337                                                         {
3338                                                                 $output = $name . "(" . $tools_status . "), " . $output;
3339                                                         }
3340                                                 }
3341                                                 else
3342                                                 {
3343                                                         $output = $name . "(" . $vm_tools_strings{"notDefined"} . "), " . $output;
3344                                                 }
3345                                         }
3346                                 }
3347                         }
3348                         chop($output);
3349                         chop($output);
3350                         if ($vms_up)
3351                         {
3352                                 $tools_ok /= $vms_up / 100;
3353                         }
3354                         else
3355                         {
3356                                 $tools_ok = 100;
3357                         }
3358                         $res = $np->check_threshold(check => $tools_ok) if (defined($np->threshold));
3359                         $np->add_perfdata(label => "toolsok", value => $tools_ok, uom => '%', threshold => $np->threshold);
3360                 }
3361                 elsif ($subcommand eq "STATUS")
3362                 {
3363                         if (defined($dc_view->overallStatus))
3364                         {
3365                                 my $status = $dc_view->overallStatus->val;
3366                                 $output = "overall status=" . $status;
3367                                 $res = check_health_state($status);
3368                         }
3369                         else
3370                         {
3371                                 $output = "Insufficient rights to access status info on the DC\n";
3372                                 $res = WARNING;
3373                         }
3374                 }
3375                 elsif ($subcommand eq "ISSUES")
3376                 {
3377                         my $issues = $dc_view->configIssue;
3378                         my $issues_count = 0;
3379
3380                         $output = '';
3381                         if (defined($issues))
3382                         {
3383                                 foreach (@$issues)
3384                                 {
3385                                         if (defined($blacklist))
3386                                         {
3387                                                 my $name = ref($_);
3388                                                 next if ($blacklist =~ m/(^|\s|\t|,)\Q$name\E($|\s|\t|,)/);
3389                                         }
3390                                         $output .= format_issue($_) . "; ";
3391                                         $issues_count++;
3392                                 }
3393                         }
3394
3395                         if ($output eq '')
3396                         {
3397                                 $res = OK;
3398                                 $output = 'No config issues';
3399                         }
3400                         $np->add_perfdata(label => "issues", value => $issues_count);
3401                 }
3402                 else
3403                 {
3404                         $res = CRITICAL;
3405                         $output = "HOST RUNTIME - unknown subcommand\n" . $np->opts->_help;
3406                 }
3407         }
3408         else
3409         {
3410                 my %host_maintenance_state = (0 => "no", 1 => "yes");
3411                 my $vm_views = Vim::find_entity_views(view_type => 'VirtualMachine', begin_entity => $dc_view, properties => ['name', 'runtime.powerState']);
3412                 die "Runtime error\n" if (!defined($vm_views));
3413                 my $up = 0;
3414
3415                 if (@$vm_views)
3416                 {
3417                         foreach my $vm (@$vm_views) {
3418                                 $up += $vm->get_property('runtime.powerState')->val eq "poweredOn";
3419                         }
3420                         $output = $up . "/" . @$vm_views . " VMs up, ";
3421                 }
3422                 else
3423                 {
3424                         $output = "No VMs installed, ";
3425                 }
3426                 $np->add_perfdata(label => "vmcount", value => $up, uom => 'units', threshold => $np->threshold);
3427
3428                 my $host_views = Vim::find_entity_views(view_type => 'HostSystem', properties => ['name', 'runtime.powerState']);
3429                 die "Runtime error\n" if (!defined($host_views));
3430                 $up = 0;
3431
3432                 if (@$host_views)
3433                 {
3434                         foreach my $host (@$host_views) {
3435                                 $up += $host->get_property('runtime.powerState')->val eq "poweredOn"
3436                         }
3437                         $output .= $up . "/" . @$host_views . " Hosts up, ";
3438                 }
3439                 else
3440                 {
3441                         $output .= "there are no hosts, ";
3442                 }
3443                 $np->add_perfdata(label => "hostcount", value => $up, uom => 'units');
3444
3445                 $res = OK;
3446                 $output .= "overall status=" . $dc_view->overallStatus->val . ", " if (defined($dc_view->overallStatus));
3447                 my $issues = $dc_view->configIssue;
3448                 if (defined($issues))
3449                 {
3450                         $output .= @$issues . " config issue(s)";
3451                         $np->add_perfdata(label => "config_issues", value => "" . @$issues);
3452                 }
3453                 else
3454                 {
3455                         $output .= "no config issues";
3456                         $np->add_perfdata(label => "config_issues", value => 0);
3457                 }
3458         }
3459
3460         return ($res, $output);
3461 }
3462
3463 #=====================================================================| Cluster |============================================================================#
3464
3465 sub cluster_cpu_info
3466 {
3467         my ($cluster, $np, $subcommand) = @_;
3468
3469         my $res = CRITICAL;
3470         my $output = 'CLUSTER CPU Unknown error';
3471
3472         if (defined($subcommand))
3473         {
3474                 if ($subcommand eq "USAGE")
3475                 {
3476                         $values = return_cluster_performance_values($cluster, 'cpu', ('usage.average'));
3477                         if (defined($values))
3478                         {
3479                                 my $value = simplify_number(convert_number($$values[0][0]->value) * 0.01);
3480                                 $np->add_perfdata(label => "cpu_usage", value => $value, uom => '%', threshold => $np->threshold);
3481                                 $output = "cpu usage=" . $value . " %"; 
3482                                 $res = $np->check_threshold(check => $value);
3483                         }
3484                 }
3485                 elsif ($subcommand eq "USAGEMHZ")
3486                 {
3487                         $values = return_cluster_performance_values($cluster, 'cpu', ('usagemhz.average'));
3488                         if (defined($values))
3489                         {
3490                                 my $value = simplify_number(convert_number($$values[0][0]->value));
3491                                 $np->add_perfdata(label => "cpu_usagemhz", value => $value, uom => 'Mhz', threshold => $np->threshold);
3492                                 $output = "cpu usagemhz=" . $value . " MHz";
3493                                 $res = $np->check_threshold(check => $value);
3494                         }
3495                 }
3496                 else
3497                 {
3498                         $res = CRITICAL;
3499                         $output = "CLUSTER CPU - unknown subcommand\n" . $np->opts->_help;
3500                 }
3501         }
3502         else
3503         {
3504                 $values = return_cluster_performance_values($cluster, 'cpu', ('usagemhz.average', 'usage.average'));
3505                 if (defined($values))
3506                 {
3507                         my $value1 = simplify_number(convert_number($$values[0][0]->value));
3508                         my $value2 = simplify_number(convert_number($$values[0][1]->value) * 0.01);
3509                         $np->add_perfdata(label => "cpu_usagemhz", value => $value1, uom => 'Mhz', threshold => $np->threshold);
3510                         $np->add_perfdata(label => "cpu_usage", value => $value2, uom => '%', threshold => $np->threshold);
3511                         $res = OK;
3512                         $output = "cpu usage=" . $value1 . " MHz (" . $value2 . "%)";
3513                 }
3514         }
3515
3516         return ($res, $output);
3517 }
3518
3519 sub cluster_mem_info
3520 {
3521         my ($cluster, $np, $subcommand, $addopts) = @_;
3522
3523         my $res = CRITICAL;
3524         my $output = 'CLUSTER MEM Unknown error';
3525
3526         my $outputlist;
3527         $outputlist = $addopts =~ m/(^|\s|\t|,)\Qlistvm\E($|\s|\t|,)/ if (defined($addopts));
3528
3529         if (defined($subcommand))
3530         {
3531                 if ($subcommand eq "USAGE")
3532                 {
3533                         $values = return_cluster_performance_values($cluster, 'mem', ('usage.average'));
3534                         if (defined($values))
3535                         {
3536                                 my $value = simplify_number(convert_number($$values[0][0]->value) * 0.01);
3537                                 $np->add_perfdata(label => "mem_usage", value => $value, uom => '%', threshold => $np->threshold);
3538                                 $output = "mem usage=" . $value . " %"; 
3539                                 $res = $np->check_threshold(check => $value);
3540                         }
3541                 }
3542                 elsif ($subcommand eq "USAGEMB")
3543                 {
3544                         $values = return_cluster_performance_values($cluster, 'mem', ('consumed.average'));
3545                         if (defined($values))
3546                         {
3547                                 my $value = simplify_number(convert_number($$values[0][0]->value) / 1024);
3548                                 $np->add_perfdata(label => "mem_usagemb", value => $value, uom => 'MB', threshold => $np->threshold);
3549                                 $output = "mem usage=" . $value . " MB";
3550                                 $res = $np->check_threshold(check => $value);
3551                         }
3552                 }
3553                 elsif ($subcommand eq "SWAP")
3554                 {
3555                         my $cluster_view;
3556                         ($cluster_view, $values) = return_cluster_performance_values($cluster, 'mem', ('swapused.average'));
3557                         if (defined($values))
3558                         {
3559                                 my $value = simplify_number(convert_number($$values[0][0]->value) / 1024);
3560                                 $np->add_perfdata(label => "mem_swap", value => $value, uom => 'MB', threshold => $np->threshold);
3561                                 $output = "swap usage=" . $value . " MB: ";
3562                                 $res = $np->check_threshold(check => $value);
3563                                 if ($res != OK && $outputlist)
3564                                 {
3565                                         my $vm_views = Vim::find_entity_views(view_type => 'VirtualMachine', begin_entity => $$cluster_view[0], properties => ['name', 'runtime.powerState']);
3566                                         die "Runtime error\n" if (!defined($vm_views));
3567                                         die "There are no VMs.\n" if (!@$vm_views);
3568                                         my @vms = ();
3569                                         foreach my $vm (@$vm_views)
3570                                         {
3571                                                 push(@vms, $vm) if ($vm->get_property('runtime.powerState')->val eq "poweredOn");
3572                                         }
3573                                         $values = generic_performance_values(\@vms, 'mem', ('swapped.average'));
3574                                         if (defined($values))
3575                                         {
3576                                                 foreach my $index (0..@vms-1) {
3577                                                         my $value = simplify_number(convert_number($$values[$index][0]->value) / 1024);
3578                                                         $output .= $vms[$index]->name . " (" . $value . "MB), " if ($value > 0);
3579                                                 }
3580                                         }
3581                                 }
3582                                 chop($output);
3583                                 chop($output);
3584                         }
3585                 }
3586                 elsif ($subcommand eq "MEMCTL")
3587                 {
3588                         my $cluster_view;
3589                         ($cluster_view, $values) = return_cluster_performance_values($cluster, 'mem', ('vmmemctl.average'));
3590                         if (defined($values))
3591                         {
3592                                 my $value = simplify_number(convert_number($$values[0][0]->value) / 1024);
3593                                 $np->add_perfdata(label => "mem_memctl", value => $value, uom => 'MB', threshold => $np->threshold);
3594                                 $output = "memctl=" . $value . " MB: ";
3595                                 $res = $np->check_threshold(check => $value);
3596                                 if ($res != OK && $outputlist)
3597                                 {
3598                                         my $vm_views = Vim::find_entity_views(view_type => 'VirtualMachine', begin_entity => $$cluster_view[0], properties => ['name', 'runtime.powerState']);
3599                                         die "Runtime error\n" if (!defined($vm_views));
3600                                         die "There are no VMs.\n" if (!@$vm_views);
3601                                         my @vms = ();
3602                                         foreach my $vm (@$vm_views)
3603                                         {
3604                                                 push(@vms, $vm) if ($vm->get_property('runtime.powerState')->val eq "poweredOn");
3605                                         }
3606                                         $values = generic_performance_values(\@vms, 'mem', ('vmmemctl.average'));
3607                                         if (defined($values))
3608                                         {
3609                                                 foreach my $index (0..@vms-1) {
3610                                                         my $value = simplify_number(convert_number($$values[$index][0]->value) / 1024);
3611                                                         $output .= $vms[$index]->name . " (" . $value . "MB), " if ($value > 0);
3612                                                 }
3613                                         }
3614                                 }
3615                                 chop($output);
3616                                 chop($output);
3617                         }
3618                 }
3619                 else
3620                 {
3621                         $res = CRITICAL;
3622                         $output = "CLUSTER MEM - unknown subcommand\n" . $np->opts->_help;
3623                 }
3624         }
3625         else
3626         {
3627                 $values = return_cluster_performance_values($cluster, 'mem', ('consumed.average', 'usage.average', 'overhead.average', 'swapused.average', 'vmmemctl.average'));
3628                 if (defined($values))
3629                 {
3630                         my $value1 = simplify_number(convert_number($$values[0][0]->value) / 1024);
3631                         my $value2 = simplify_number(convert_number($$values[0][1]->value) * 0.01);
3632                         my $value3 = simplify_number(convert_number($$values[0][2]->value) / 1024);
3633                         my $value4 = simplify_number(convert_number($$values[0][3]->value) / 1024);
3634                         my $value5 = simplify_number(convert_number($$values[0][4]->value) / 1024);
3635                         $np->add_perfdata(label => "mem_usagemb", value => $value1, uom => 'MB', threshold => $np->threshold);
3636                         $np->add_perfdata(label => "mem_usage", value => $value2, uom => '%', threshold => $np->threshold);
3637                         $np->add_perfdata(label => "mem_overhead", value => $value3, uom => 'MB', threshold => $np->threshold);
3638                         $np->add_perfdata(label => "mem_swap", value => $value4, uom => 'MB', threshold => $np->threshold);
3639                         $np->add_perfdata(label => "mem_memctl", value => $value5, uom => 'MB', threshold => $np->threshold);
3640                         $res = OK;
3641                         $output = "mem usage=" . $value1 . " MB (" . $value2 . "%), overhead=" . $value3 . " MB, swapped=" . $value4 . " MB, memctl=" . $value5 . " MB";
3642                 }
3643         }
3644
3645         return ($res, $output);
3646 }
3647
3648 sub cluster_cluster_info
3649 {
3650         my ($cluster, $np, $subcommand) = @_;
3651          
3652         my $res = CRITICAL;
3653         my $output = 'CLUSTER clusterServices Unknown error';
3654         
3655         if (defined($subcommand))
3656         {
3657                 if ($subcommand eq "EFFECTIVECPU")
3658                 {
3659                         $values = return_cluster_performance_values($cluster, 'clusterServices', ('effectivecpu.average'));
3660                         if (defined($values))
3661                         {
3662                                 my $value = simplify_number(convert_number(get_val_from_list($$values[0][0]->value)) * 0.01);
3663                                 $np->add_perfdata(label => "effective cpu", value => $value, uom => 'Mhz', threshold => $np->threshold);
3664                                 $output = "effective cpu=" . $value . " %"; 
3665                                 $res = $np->check_threshold(check => $value);
3666                         }
3667                 }
3668                 elsif ($subcommand eq "EFFECTIVEMEM")
3669                 {
3670                         $values = return_cluster_performance_values($cluster, 'clusterServices', ('effectivemem.average'));
3671                         if (defined($values))
3672                         {
3673                                 my $value = simplify_number(convert_number($$values[0][0]->value) / 1024);
3674                                 $np->add_perfdata(label => "effectivemem", value => $value, uom => 'MB', threshold => $np->threshold);
3675                                 $output = "effective mem=" . $value . " MB";
3676                                 $res = $np->check_threshold(check => $value);
3677                         }
3678                 }
3679                 elsif ($subcommand eq "FAILOVER")
3680                 {
3681                         $values = return_cluster_performance_values($cluster, 'clusterServices', ('failover.latest:*'));
3682                         if (defined($values))
3683                         {
3684                                 my $value = simplify_number(convert_number($$values[0][0]->value) / 1024);
3685                                 $np->add_perfdata(label => "failover", value => $value, uom => 'MB', threshold => $np->threshold);
3686                                 $output = "failover=" . $value . " ";
3687                                 $res = $np->check_threshold(check => $value);
3688                         }
3689                 }
3690                 elsif ($subcommand eq "CPUFAIRNESS")
3691                 {
3692                         $values = return_cluster_performance_values($cluster, 'clusterServices', ('cpufairness.latest'));
3693                         if (defined($values))
3694                         {
3695                                 my $value = simplify_number(convert_number($$values[0][0]->value));
3696                                 $np->add_perfdata(label => "cpufairness", value => $value, uom => '%', threshold => $np->threshold);
3697                                 $output = "cpufairness=" . $value . " %";
3698                                 $res = $np->check_threshold(check => $value);
3699                         }
3700                 }
3701                 elsif ($subcommand eq "MEMFAIRNESS")
3702                 {
3703                         $values = return_cluster_performance_values($cluster, 'clusterServices', ('memfairness.latest'));
3704                         if (defined($values))
3705                         {
3706                                 my $value = simplify_number((convert_number($$values[0][0]->value)));
3707                                 $np->add_perfdata(label => "memfairness", value =>  $value, uom => '%', threshold => $np->threshold);
3708                                 $output = "memfairness=" . $value . " %";
3709                                 $res = $np->check_threshold(check => $value);
3710                         }
3711                 }
3712                 else
3713                 {
3714                         $res = CRITICAL;
3715                         $output = "CLUSTER clusterServices - unknown subcommand\n" . $np->opts->_help;
3716                 }
3717         }
3718         else
3719         {
3720                 $values = return_cluster_performance_values($cluster, 'clusterServices', ('effectivecpu.average', 'effectivemem.average'));
3721                 if (defined($values))
3722                 {
3723                         my $value1 = simplify_number(convert_number($$values[0][0]->value));
3724                         my $value2 = simplify_number(convert_number($$values[0][1]->value) / 1024);
3725                         $np->add_perfdata(label => "effective cpu", value => $value1, uom => 'Mhz', threshold => $np->threshold);
3726                         $np->add_perfdata(label => "effective mem", value => $value2, uom => 'MB', threshold => $np->threshold);
3727                         $res = OK;
3728                         $output = "effective cpu=" . $value1 . " Mhz, effective Mem=" . $value2 . " MB";
3729                 }
3730         }
3731
3732         return ($res, $output);
3733 }
3734
3735 sub cluster_runtime_info
3736 {
3737         my ($cluster, $np, $subcommand, $blacklist) = @_;
3738
3739         my $res = CRITICAL;
3740         my $output = 'CLUSTER RUNTIME Unknown error';
3741         my $runtime;
3742         my $cluster_view = Vim::find_entity_view(view_type => 'ClusterComputeResource', filter => { name => "$cluster" }, properties => ['name', 'overallStatus', 'configIssue']);
3743         die "Cluster \"" . $$cluster{"name"} . "\" does not exist\n" if (!defined($cluster_view));
3744         $cluster_view->update_view_data();
3745
3746         if (defined($subcommand))
3747         {
3748                 if (($subcommand eq "LIST") || ($subcommand eq "LISTVM"))
3749                 {
3750                         my %vm_state_strings = ("poweredOn" => "UP", "poweredOff" => "DOWN", "suspended" => "SUSPENDED");
3751                         my $vm_views = Vim::find_entity_views(view_type => 'VirtualMachine', begin_entity => $cluster_view, properties => ['name', 'runtime']);
3752                         die "Runtime error\n" if (!defined($vm_views));
3753                         die "There are no VMs.\n" if (!defined($vm_views));
3754                         my $up = 0;
3755                         $output = '';
3756
3757                         foreach my $vm (@$vm_views)
3758                         {
3759                                 my $vm_state = $vm_state_strings{$vm->runtime->powerState->val};
3760                                 if ($vm_state eq "UP")
3761                                 {
3762                                         $up++;
3763                                         $output .= $vm->name . "(OK), ";
3764                                 }
3765                                 else
3766                                 {
3767                                         $output = $vm->name . "(" . $vm_state . "), " . $output;
3768                                 }
3769                         }
3770
3771                         chop($output);
3772                         chop($output);
3773                         $res = OK;
3774                         $output = $up .  "/" . @$vm_views . " VMs up: " . $output;
3775                         $np->add_perfdata(label => "vmcount", value => $up, uom => 'units', threshold => $np->threshold);
3776                         $res = $np->check_threshold(check => $up) if (defined($np->threshold));
3777                 }
3778                 elsif ($subcommand eq "LISTHOST")
3779                 {
3780                         my %host_state_strings = ("poweredOn" => "UP", "poweredOff" => "DOWN", "suspended" => "SUSPENDED", "standBy" => "STANDBY", "MaintenanceMode" => "Maintenance Mode");
3781                         my $host_views = Vim::find_entity_views(view_type => 'HostSystem', begin_entity => $cluster_view, properties => ['name', 'runtime.powerState']);
3782                         die "Runtime error\n" if (!defined($host_views));
3783                         die "There are no hosts.\n" if (!defined($host_views));
3784                         my $up = 0;
3785                         my $unknown = 0;
3786                         $output = '';
3787
3788                         foreach my $host (@$host_views) {
3789                                 $host->update_view_data(['name', 'runtime.powerState']);
3790                                 my $host_state = $host_state_strings{$host->get_property('runtime.powerState')->val};
3791                                 $unknown += $host_state eq "UNKNOWN";
3792                                 if ($host_state eq "UP" && $host_state eq "Maintenance Mode") {
3793                                         $up++;
3794                                         $output .= $host->name . "(UP), ";
3795                                 } else
3796                                 {
3797                                         $output = $host->name . "(" . $host_state . "), " . $output;
3798                                 }
3799                         }
3800
3801                         chop($output);
3802                         chop($output);
3803                         $res = OK;
3804                         $output = $up .  "/" . @$host_views . " Hosts up: " . $output;
3805                         $np->add_perfdata(label => "vmcount", value => $up, uom => 'units', threshold => $np->threshold);
3806                         $res = $np->check_threshold(check => $up) if (defined($np->threshold));
3807                         $res = UNKNOWN if ($res == OK && $unknown);
3808                 }
3809                 elsif ($subcommand eq "STATUS")
3810                 {
3811                         if (defined($cluster_view->overallStatus))
3812                         {
3813                                 my $status = $cluster_view->overallStatus->val;
3814                                 $output = "overall status=" . $status;
3815                                 $res = check_health_state($status);
3816                         }
3817                         else
3818                         {
3819                                 $output = "Insufficient rights to access status info on the DC\n";
3820                                 $res = WARNING;
3821                         }
3822                 }
3823                 elsif ($subcommand eq "ISSUES")
3824                 {
3825                         my $issues = $cluster_view->configIssue;
3826                         my $issues_count = 0;
3827
3828                         $output = '';
3829                         if (defined($issues))
3830                         {
3831                                 foreach (@$issues)
3832                                 {
3833                                         if (defined($blacklist))
3834                                         {
3835                                                 my $name = ref($_);
3836                                                 next if ($blacklist =~ m/(^|\s|\t|,)\Q$name\E($|\s|\t|,)/);
3837                                         }
3838                                         $output .= format_issue($_) . "; ";
3839                                         $issues_count++;
3840                                 }
3841                         }
3842
3843                         if ($output eq '')
3844                         {
3845                                 $res = OK;
3846                                 $output = 'No config issues';
3847                         }
3848                         $np->add_perfdata(label => "issues", value => $issues_count);
3849                 }
3850                 else
3851                 {
3852                         $res = CRITICAL;
3853                         $output = "CLUSTER RUNTIME - unknown subcommand\n" . $np->opts->_help;
3854                 }
3855         }
3856         else
3857         {
3858                 my %cluster_maintenance_state = (0 => "no", 1 => "yes");
3859                 my $vm_views = Vim::find_entity_views(view_type => 'VirtualMachine', begin_entity => $cluster_view, properties => ['name', 'runtime.powerState']);
3860                 my $up = 0;
3861
3862                 if (defined($vm_views))
3863                 {
3864                         foreach my $vm (@$vm_views) {
3865                                 $up += $vm->get_property('runtime.powerState')->val eq "poweredOn";
3866                         }
3867                         $np->add_perfdata(label => "vmcount", value => $up, uom => 'units', threshold => $np->threshold);
3868                         $output = $up . "/" . @$vm_views . " VMs up";
3869                 }
3870                 else
3871                 {
3872                         $output = "No VMs installed";
3873                 }
3874
3875                 my $AlertCount = 0;
3876                 my $SensorCount = 0;
3877                 my ($cpuStatusInfo, $storageStatusInfo, $memoryStatusInfo, $numericSensorInfo);
3878
3879                 $res = OK;
3880                 $output .= ", overall status=" . $cluster_view->overallStatus->val . ", " if (defined($cluster_view->overallStatus));
3881
3882                 my $issues = $cluster_view->configIssue;
3883                 if (defined($issues))
3884                 {
3885                         $output .= @$issues . " config issue(s)";
3886                 }
3887                 else
3888                 {
3889                         $output .= "no config issues";
3890                 }
3891         }
3892
3893         return ($res, $output);
3894 }
3895
3896 sub cluster_list_vm_volumes_info
3897 {
3898         my ($cluster, $np, $subcommand, $blacklist, $perc, $addopts) = @_;
3899
3900         my $cluster_view = Vim::find_entity_view(view_type => 'ClusterComputeResource', filter => {name => "$cluster"}, properties => ['name', 'datastore']);
3901         die "Insufficient rights to access Datastores on the Host\n" if (!defined($cluster_view->datastore));
3902
3903         return datastore_volumes_info($cluster_view->datastore, $np, $subcommand, $blacklist, $perc, $addopts);
3904 }
3905