diff --git a/centreon-plugins/apps/vmware/connector/mode/countvmhost.pm b/centreon-plugins/apps/vmware/connector/mode/countvmhost.pm index 814f791c1..0d1c36b36 100644 --- a/centreon-plugins/apps/vmware/connector/mode/countvmhost.pm +++ b/centreon-plugins/apps/vmware/connector/mode/countvmhost.pm @@ -24,7 +24,6 @@ use base qw(centreon::plugins::templates::counter); use strict; use warnings; -use centreon::plugins::misc; use centreon::plugins::templates::catalog_functions qw(catalog_status_threshold); sub custom_status_output { diff --git a/centreon-plugins/apps/vmware/connector/mode/cpuvm.pm b/centreon-plugins/apps/vmware/connector/mode/cpuvm.pm index 551be8bd2..bd2e620f8 100644 --- a/centreon-plugins/apps/vmware/connector/mode/cpuvm.pm +++ b/centreon-plugins/apps/vmware/connector/mode/cpuvm.pm @@ -179,8 +179,6 @@ sub manage_selection { $self->{vm} = {}; my $response = $options{custom}->execute(params => $self->{option_results}, command => 'cpuvm'); - use Data::Dumper; - print Data::Dumper::Dumper($response); foreach my $vm_id (keys %{$response->{data}}) { my $vm_name = $response->{data}->{$vm_id}->{name}; @@ -189,7 +187,7 @@ sub manage_selection { cpu => {}, global => { connection_state => $response->{data}->{$vm_id}->{connection_state}, - power_state => $response->{data}->{$vm_id}->{power_state}, + power_state => $response->{data}->{$vm_id}->{power_state}, }, global_cpu => { cpu_average => $response->{data}->{$vm_id}->{'cpu.usage.average'}, diff --git a/centreon-plugins/apps/vmware/connector/mode/datastorevm.pm b/centreon-plugins/apps/vmware/connector/mode/datastorevm.pm index 634bfcf06..f179eb8ab 100644 --- a/centreon-plugins/apps/vmware/connector/mode/datastorevm.pm +++ b/centreon-plugins/apps/vmware/connector/mode/datastorevm.pm @@ -20,10 +20,114 @@ package apps::vmware::connector::mode::datastorevm; -use base qw(centreon::plugins::mode); +use base qw(centreon::plugins::templates::counter); use strict; use warnings; +use centreon::plugins::misc; +use centreon::plugins::templates::catalog_functions qw(catalog_status_threshold); + +sub custom_status_output { + my ($self, %options) = @_; + + my $msg = '[connection state ' . $self->{result_values}->{connection_state} . '][power state ' . $self->{result_values}->{power_state} . ']'; + return $msg; +} + +sub custom_status_calc { + my ($self, %options) = @_; + + $self->{result_values}->{connection_state} = $options{new_datas}->{$self->{instance} . '_connection_state'}; + $self->{result_values}->{power_state} = $options{new_datas}->{$self->{instance} . '_power_state'}; + return 0; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'vm', type => 3, cb_prefix_output => 'prefix_vm_output', cb_long_output => 'vm_long_output', indent_long_output => ' ', message_multiple => 'All virtual machines are ok', + group => [ + { name => 'global', type => 0, skipped_code => { -10 => 1 } }, + { name => 'global_vm', type => 0, skipped_code => { -10 => 1 } }, + { name => 'datastore', cb_prefix_output => 'prefix_datastore_output', message_multiple => 'All datastores are ok', type => 1, skipped_code => { -10 => 1 } }, + ] + } + ]; + + $self->{maps_counters}->{global} = [ + { label => 'status', threshold => 0, set => { + key_values => [ { name => 'connection_state' }, { name => 'power_state' } ], + closure_custom_calc => $self->can('custom_status_calc'), + closure_custom_output => $self->can('custom_status_output'), + closure_custom_perfdata => sub { return 0; }, + closure_custom_threshold_check => \&catalog_status_threshold, + } + }, + ]; + + $self->{maps_counters}->{global_vm} = [ + { label => 'max-total-latency', set => { + key_values => [ { name => 'total_latency' } ], + output_template => 'max total latency is %s ms', + perfdatas => [ + { label => 'max_total_latency', value => 'total_latency_absolute', template => '%s', unit => 'ms', + min => 0, label_extra_instance => 1 }, + ], + } + }, + ]; + + $self->{maps_counters}->{datastore} = [ + { label => 'read', set => { + key_values => [ { name => 'read' } ], + output_template => '%s read iops', + perfdatas => [ + { label => 'riops', value => 'read_absolute', template => '%s', unit => 'iops', + min => 0, label_extra_instance => 1 }, + ], + } + }, + { label => 'write', set => { + key_values => [ { name => 'write' } ], + output_template => '%s write iops', + perfdatas => [ + { label => 'wiops', value => 'write_absolute', template => '%s', unit => 'iops', + min => 0, max => 'write_absolute', label_extra_instance => 1 }, + ], + } + }, + ]; +} + +sub prefix_vm_output { + my ($self, %options) = @_; + + my $msg = "Virtual machine '" . $options{instance_value}->{display} . "'"; + if (defined($options{instance_value}->{config_annotation})) { + $msg .= ' [annotation: ' . $options{instance_value}->{config_annotation} . ']'; + } + $msg .= ' : '; + + return $msg; +} + +sub vm_long_output { + my ($self, %options) = @_; + + my $msg = "checking virtual machine '" . $options{instance_value}->{display} . "'"; + if (defined($options{instance_value}->{config_annotation})) { + $msg .= ' [annotation: ' . $options{instance_value}->{config_annotation} . ']'; + } + + return $msg; +} + +sub prefix_datastore_output { + my ($self, %options) = @_; + + return "datastore '" . $options{instance_value}->{display} . "' "; +} sub new { my ($class, %options) = @_; @@ -31,57 +135,63 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "vm-hostname:s" => { name => 'vm_hostname' }, - "filter" => { name => 'filter' }, - "scope-datacenter:s" => { name => 'scope_datacenter' }, - "scope-cluster:s" => { name => 'scope_cluster' }, - "scope-host:s" => { name => 'scope_host' }, - "filter-description:s" => { name => 'filter_description' }, - "disconnect-status:s" => { name => 'disconnect_status', default => 'unknown' }, - "nopoweredon-status:s" => { name => 'nopoweredon_status', default => 'unknown' }, - "display-description" => { name => 'display_description' }, - "warning:s" => { name => 'warning' }, - "critical:s" => { name => 'critical' }, - "warning-max-total-latency:s" => { name => 'warning_max_total_latency' }, - "critical-max-total-latency:s" => { name => 'critical_max_total_latency' }, - "datastore-name:s" => { name => 'datastore_name' }, - "filter-datastore:s" => { name => 'filter_datastore' }, - }); + $options{options}->add_options(arguments => { + "vm-hostname:s" => { name => 'vm_hostname' }, + "filter" => { name => 'filter' }, + "scope-datacenter:s" => { name => 'scope_datacenter' }, + "scope-cluster:s" => { name => 'scope_cluster' }, + "scope-host:s" => { name => 'scope_host' }, + "filter-description:s" => { name => 'filter_description' }, + "display-description" => { name => 'display_description' }, + "datastore-name:s" => { name => 'datastore_name' }, + "filter-datastore:s" => { name => 'filter_datastore' }, + "unknown-status:s" => { name => 'unknown_status', default => '%{connection_state} !~ /^connected$/i or %{power_state} !~ /^poweredOn$/i' }, + "warning-status:s" => { name => 'warning_status', default => '' }, + "critical-status:s" => { name => 'critical_status', default => '' }, + }); + return $self; } sub check_options { my ($self, %options) = @_; - $self->SUPER::init(%options); + $self->SUPER::check_options(%options); - foreach my $label (('warning', 'critical', 'warning_max_total_latency', 'critical_max_total_latency')) { - if (($self->{perfdata}->threshold_validate(label => $label, value => $self->{option_results}->{$label})) == 0) { - my ($label_opt) = $label; - $label_opt =~ tr/_/-/; - $self->{output}->add_option_msg(short_msg => "Wrong " . $label_opt . " threshold '" . $self->{option_results}->{$label} . "'."); - $self->{output}->option_exit(); - } - } - - if ($self->{output}->is_litteral_status(status => $self->{option_results}->{disconnect_status}) == 0) { - $self->{output}->add_option_msg(short_msg => "Wrong disconnect-status option '" . $self->{option_results}->{disconnect_status} . "'."); - $self->{output}->option_exit(); - } - if ($self->{output}->is_litteral_status(status => $self->{option_results}->{nopoweredon_status}) == 0) { - $self->{output}->add_option_msg(short_msg => "Wrong nopoweredon-status option '" . $self->{option_results}->{nopoweredon_status} . "'."); - $self->{output}->option_exit(); - } + $self->change_macros(macros => ['unknown_status', 'warning_status', 'critical_status']); } -sub run { +sub manage_selection { my ($self, %options) = @_; - $self->{connector} = $options{custom}; - $self->{connector}->add_params(params => $self->{option_results}, - command => 'datastorevm'); - $self->{connector}->run(); + $self->{vm} = {}; + my $response = $options{custom}->execute(params => $self->{option_results}, + command => 'datastorevm'); + + foreach my $vm_id (keys %{$response->{data}}) { + my $vm_name = $response->{data}->{$vm_id}->{name}; + + $self->{vm}->{$vm_name} = { display => $vm_name, + datastore => {}, + global => { + connection_state => $response->{data}->{$vm_id}->{connection_state}, + power_state => $response->{data}->{$vm_id}->{power_state}, + }, + global_vm => { + total_latency => $response->{data}->{$vm_id}->{'disk.maxTotalLatency.latest'}, + }, + }; + + if (defined($self->{option_results}->{display_description})) { + $self->{vm}->{$vm_name}->{config_annotation} = $options{custom}->strip_cr(value => $response->{data}->{$vm_id}->{'config.annotation'}); + } + + foreach my $ds_name (sort keys %{$response->{data}->{$vm_id}->{datastore}}) { + $self->{vm}->{$vm_name}->{datastore}->{$ds_name} = { display => $ds_name, + read => $response->{data}->{$vm_id}->{datastore}->{$ds_name}->{'disk.numberRead.summation'}, + write => $response->{data}->{$vm_id}->{datastore}->{$ds_name}->{'disk.numberWrite.summation'}, + }; + } + } } 1; @@ -128,33 +238,34 @@ If not set, we check all datastores. Datastore name is a regexp. -=item B<--disconnect-status> - -Status if VM disconnected (default: 'unknown'). - -=item B<--nopoweredon-status> - -Status if VM is not poweredOn (default: 'unknown'). - =item B<--display-description> Display virtual machine description. -=item B<--warning> +=item B<--unknown-status> -Threshold warning in IOPs. +Set warning threshold for status (Default: '%{connection_state} !~ /^connected$/i or %{power_state} !~ /^poweredOn$/i'). +Can used special variables like: %{status} -=item B<--critical> +=item B<--warning-status> -Threshold critical in IOPs. +Set warning threshold for status (Default: ''). +Can used special variables like: %{status} -=item B<--warning-max-total-latency> +=item B<--critical-status> -Threshold warning in ms. +Set critical threshold for status (Default: ''). +Can used special variables like: %{status} -=item B<--critical-max-total-latency> +=item B<--warning-*> -Threshold critical in ms. +Threshold warning. +Can be: 'max-total-latency', 'read', 'write'. + +=item B<--critical-*> + +Threshold critical. +Can be: 'max-total-latency', 'read', 'write'. =back diff --git a/centreon-plugins/apps/vmware/connector/mode/devicevm.pm b/centreon-plugins/apps/vmware/connector/mode/devicevm.pm index 3dd820d31..d46a12971 100644 --- a/centreon-plugins/apps/vmware/connector/mode/devicevm.pm +++ b/centreon-plugins/apps/vmware/connector/mode/devicevm.pm @@ -20,10 +20,86 @@ package apps::vmware::connector::mode::devicevm; -use base qw(centreon::plugins::mode); +use base qw(centreon::plugins::templates::counter); use strict; use warnings; +use centreon::plugins::templates::catalog_functions qw(catalog_status_threshold); + +sub custom_status_output { + my ($self, %options) = @_; + + my $msg = '[connection state ' . $self->{result_values}->{connection_state} . '][power state ' . $self->{result_values}->{power_state} . ']'; + return $msg; +} + +sub custom_status_calc { + my ($self, %options) = @_; + + $self->{result_values}->{connection_state} = $options{new_datas}->{$self->{instance} . '_connection_state'}; + $self->{result_values}->{power_state} = $options{new_datas}->{$self->{instance} . '_power_state'}; + return 0; +} + +sub custom_device_output { + my ($self, %options) = @_; + + my $msg = sprintf("%s %s device connected", $self->{result_values}->{device_connected_absolute}, $self->{instance_mode}->{option_results}->{device}); + return $msg; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'global', type => 0, skipped_code => { -10 => 1 } }, + { name => 'vm', type => 1, cb_prefix_output => 'prefix_vm_output', message_multiple => 'All virtual machines are ok' }, + ]; + + $self->{maps_counters}->{global} = [ + { label => 'total-device-connected', set => { + key_values => [ { name => 'device_connected' } ], + closure_custom_output => $self->can('custom_device_output'), + perfdatas => [ + { label => 'total_device_connected', value => 'device_connected_absolute', template => '%s', + min => 0 }, + ], + } + }, + ]; + + $self->{maps_counters}->{vm} = [ + { label => 'status', threshold => 0, set => { + key_values => [ { name => 'connection_state' }, { name => 'power_state' } ], + closure_custom_calc => $self->can('custom_status_calc'), + closure_custom_output => $self->can('custom_status_output'), + closure_custom_perfdata => sub { return 0; }, + closure_custom_threshold_check => \&catalog_status_threshold, + } + }, + { label => 'device-connected', set => { + key_values => [ { name => 'device_connected' }, { name => 'display' } ], + oclosure_custom_output => $self->can('custom_device_output'), + perfdatas => [ + { label => 'device_connected', value => 'device_connected_absolute', template => '%s', + min => 0, label_extra_instance => 1 }, + ], + } + }, + ]; +} + +sub prefix_vm_output { + my ($self, %options) = @_; + + my $msg = "Virtual machine '" . $options{instance_value}->{display} . "'"; + if (defined($options{instance_value}->{config_annotation})) { + $msg .= ' [annotation: ' . $options{instance_value}->{config_annotation} . ']'; + } + $msg .= ' : '; + + return $msg; +} sub new { my ($class, %options) = @_; @@ -31,58 +107,57 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "vm-hostname:s" => { name => 'vm_hostname' }, - "filter" => { name => 'filter' }, - "scope-datacenter:s" => { name => 'scope_datacenter' }, - "scope-cluster:s" => { name => 'scope_cluster' }, - "scope-host:s" => { name => 'scope_host' }, - "filter-description:s" => { name => 'filter_description' }, - "disconnect-status:s" => { name => 'disconnect_status', default => 'unknown' }, - "nopoweredon-status:s" => { name => 'nopoweredon_status', default => 'unknown' }, - "display-description" => { name => 'display_description' }, - "warning:s" => { name => 'warning' }, - "critical:s" => { name => 'critical' }, - "device:s" => { name => 'device' }, - }); + $options{options}->add_options(arguments => { + "vm-hostname:s" => { name => 'vm_hostname' }, + "filter" => { name => 'filter' }, + "scope-datacenter:s" => { name => 'scope_datacenter' }, + "scope-cluster:s" => { name => 'scope_cluster' }, + "scope-host:s" => { name => 'scope_host' }, + "filter-description:s" => { name => 'filter_description' }, + "display-description" => { name => 'display_description' }, + "device:s" => { name => 'device' }, + "unknown-status:s" => { name => 'unknown_status', default => '%{connection_state} !~ /^connected$/i' }, + "warning-status:s" => { name => 'warning_status', default => '' }, + "critical-status:s" => { name => 'critical_status', default => '' }, + }); + return $self; } sub check_options { my ($self, %options) = @_; - $self->SUPER::init(%options); + $self->SUPER::check_options(%options); - foreach my $label (('warning', 'critical')) { - if (($self->{perfdata}->threshold_validate(label => $label, value => $self->{option_results}->{$label})) == 0) { - my ($label_opt) = $label; - $label_opt =~ tr/_/-/; - $self->{output}->add_option_msg(short_msg => "Wrong " . $label_opt . " threshold '" . $self->{option_results}->{$label} . "'."); - $self->{output}->option_exit(); - } - } - + $self->change_macros(macros => ['unknown_status', 'warning_status', 'critical_status']); if (!defined($self->{option_results}->{device}) || $self->{option_results}->{device} eq '') { $self->{output}->add_option_msg(short_msg => "Please set device option."); $self->{output}->option_exit(); } - if ($self->{output}->is_litteral_status(status => $self->{option_results}->{disconnect_status}) == 0) { - $self->{output}->add_option_msg(short_msg => "Wrong disconnect-status option '" . $self->{option_results}->{disconnect_status} . "'."); - $self->{output}->option_exit(); - } - if ($self->{output}->is_litteral_status(status => $self->{option_results}->{nopoweredon_status}) == 0) { - $self->{output}->add_option_msg(short_msg => "Wrong nopoweredon-status option '" . $self->{option_results}->{nopoweredon_status} . "'."); - $self->{output}->option_exit(); - } } -sub run { +sub manage_selection { my ($self, %options) = @_; - $self->{connector} = $options{custom}; - $self->{connector}->add_params(params => $self->{option_results}, - command => 'devicevm'); - $self->{connector}->run(); + $self->{global} = { device_connected => 0 }; + $self->{vm} = {}; + my $response = $options{custom}->execute(params => $self->{option_results}, + command => 'devicevm'); + + foreach my $vm_id (keys %{$response->{data}}) { + my $vm_name = $response->{data}->{$vm_id}->{name}; + $self->{vm}->{$vm_name} = { + display => $vm_name, + connection_state => $response->{data}->{$vm_id}->{connection_state}, + power_state => $response->{data}->{$vm_id}->{power_state}, + device_connected => $response->{data}->{$vm_id}->{total_device_connected}, + }; + + if (defined($self->{option_results}->{display_description})) { + $self->{vm}->{$vm_name}->{config_annotation} = $options{custom}->strip_cr(value => $response->{data}->{$vm_id}->{'config.annotation'}); + } + + $self->{global}->{device_connected} += $self->{vm}->{$vm_name}->{device_connected}; + } } 1; @@ -120,30 +195,39 @@ Search in following cluster(s) (can be a regexp). Search in following host(s) (can be a regexp). -=item B<--disconnect-status> - -Status if VM disconnected (default: 'unknown'). - -=item B<--nopoweredon-status> - -Status if VM is not poweredOn (default: 'unknown'). - =item B<--display-description> Display virtual machine description. -=item B<--warning> - -Threshold warning in bytes per seconds. - -=item B<--critical> - -Threshold critical in bytes per seconds. - =item B<--device> Device to check (Required) (Example: --device='VirtualCdrom'). +=item B<--unknown-status> + +Set warning threshold for status (Default: '%{connection_state} !~ /^connected$/i'). +Can used special variables like: %{status} + +=item B<--warning-status> + +Set warning threshold for status (Default: ''). +Can used special variables like: %{status} + +=item B<--critical-status> + +Set critical threshold for status (Default: ''). +Can used special variables like: %{status} + +=item B<--warning-*> + +Threshold warning. +Can be: 'total-device-connected', 'device-connected'. + +=item B<--critical-*> + +Threshold critical. +Can be: 'total-device-connected', 'device-connected'. + =back =cut diff --git a/centreon-plugins/apps/vmware/connector/mode/getmap.pm b/centreon-plugins/apps/vmware/connector/mode/getmap.pm index 6d8b68e82..0542bd203 100644 --- a/centreon-plugins/apps/vmware/connector/mode/getmap.pm +++ b/centreon-plugins/apps/vmware/connector/mode/getmap.pm @@ -49,12 +49,25 @@ sub check_options { sub run { my ($self, %options) = @_; - $self->{connector} = $options{custom}; - $self->{connector}->set_discovery(); - $self->{connector}->add_params(params => $self->{option_results}, - command => 'getmap'); - $self->{connector}->run(); + my $response = $options{custom}->execute(params => $self->{option_results}, + command => 'getmap'); + + foreach my $host_id (sort { $response->{data}->{$a}->{name} cmp $response->{data}->{$b}->{name} } keys %{$response->{data}}) { + $self->{output}->output_add(long_msg => sprintf(" %s [v%s] %s", $response->{data}->{$host_id}->{name}, + $response->{data}->{$host_id}->{version}, + defined($self->{option_results}->{vm_no}) ? '' : ':')); + + foreach my $vm_id (sort { $response->{data}->{$host_id}->{vm}->{$a}->{name} cmp $response->{data}->{$host_id}->{vm}->{$b}->{name} } keys %{$response->{data}->{$host_id}->{vm}}) { + $self->{output}->output_add(long_msg => sprintf(" %s [%s]", + $response->{data}->{$host_id}->{vm}->{$vm_id}->{name}, $response->{data}->{$host_id}->{vm}->{$vm_id}->{power_state})); + } + } + + $self->{output}->output_add(severity => 'OK', + short_msg => 'List ESX host(s):'); + $self->{output}->display(nolabel => 1, force_ignore_perfdata => 1, force_long_output => 1); + $self->{output}->exit(); } 1; diff --git a/centreon-plugins/apps/vmware/connector/mode/healthhost.pm b/centreon-plugins/apps/vmware/connector/mode/healthhost.pm index 812289285..7b6fcde43 100644 --- a/centreon-plugins/apps/vmware/connector/mode/healthhost.pm +++ b/centreon-plugins/apps/vmware/connector/mode/healthhost.pm @@ -20,10 +20,146 @@ package apps::vmware::connector::mode::healthhost; -use base qw(centreon::plugins::mode); +use base qw(centreon::plugins::templates::counter); use strict; use warnings; +use centreon::plugins::templates::catalog_functions qw(catalog_status_threshold); + +sub custom_status_output { + my ($self, %options) = @_; + + my $msg = 'status ' . $self->{result_values}->{status}; + return $msg; +} + +sub custom_status_calc { + my ($self, %options) = @_; + + $self->{result_values}->{status} = $options{new_datas}->{$self->{instance} . '_state'}; + return 0; +} + +sub custom_summary_output { + my ($self, %options) = @_; + + use Data::Dumper; + print Data::Dumper::Dumper($self->{result_values}); + my $msg; + if ($self->{result_values}->{type_absolute} ne '') { + $msg = $self->{result_values}->{type_absolute} . " sensor " . $self->{result_values}->{name_absolute} . ": ". $self->{result_values}->{summary_absolute}; + } else { + $msg = $self->{result_values}->{name_absolute} . ": ". $self->{result_values}->{summary_absolute}; + } + return $msg; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'global', type => 0, skipped_code => { -10 => 1 } }, + { name => 'host', type => 3, cb_prefix_output => 'prefix_host_output', cb_long_output => 'host_long_output', indent_long_output => ' ', message_multiple => 'All ESX hosts are ok', + group => [ + { name => 'global_host', type => 0, skipped_code => { -10 => 1 } }, + { name => 'global_problems', type => 0, skipped_code => { -10 => 1 } }, + { name => 'global_summary', type => 1 }, + ] + } + ]; + + $self->{maps_counters}->{global} = [ + { label => 'total-problems', set => { + key_values => [ { name => 'total_problems' }, { name => 'total' } ], + output_template => '%s total health issue(s) found', + perfdatas => [ + { label => 'total_problems', value => 'total_problems_absolute', template => '%s', + min => 0, max => 'total_absolute' }, + ], + } + }, + ]; + + $self->{maps_counters}->{global_host} = [ + { label => 'status', threshold => 0, set => { + key_values => [ { name => 'state' } ], + closure_custom_calc => $self->can('custom_status_calc'), + closure_custom_output => $self->can('custom_status_output'), + closure_custom_perfdata => sub { return 0; }, + closure_custom_threshold_check => \&catalog_status_threshold, + } + }, + ]; + + $self->{maps_counters}->{global_problems} = [ + { label => 'ok', threshold => 0, set => { + key_values => [ { name => 'ok' } ], + output_template => '%s health checks are green', + closure_custom_perfdata => sub { return 0; }, + } + }, + { label => 'problems', set => { + key_values => [ { name => 'total_problems' }, { name => 'total' } ], + output_template => '%s total health issue(s) found', + perfdatas => [ + { label => 'problems', value => 'total_problems_absolute', template => '%s', + min => 0, max => 'total_absolute', label_extra_instance => 1 }, + ], + } + }, + { label => 'problems-yellow', set => { + key_values => [ { name => 'yellow' }, { name => 'total' } ], + output_template => '%s yellow health issue(s) found', + perfdatas => [ + { label => 'problems_yellow', value => 'yellow_absolute', template => '%s', + min => 0, max => 'total_absolute', label_extra_instance => 1 }, + ], + } + }, + { label => 'problems-red', set => { + key_values => [ { name => 'red' }, { name => 'total' } ], + output_template => '%s red health issue(s) found', + perfdatas => [ + { label => 'problems_red', value => 'red_absolute', template => '%s', + min => 0, max => 'total_absolute', label_extra_instance => 1 }, + ], + } + }, + ]; + + $self->{maps_counters}->{global_summary} = [ + { label => 'global-summary', threshold => 0, set => { + key_values => [ { name => 'type' }, { name => 'name' }, { name => 'summary' } ], + closure_custom_output => $self->can('custom_summary_output'), + closure_custom_perfdata => sub { return 0; }, + } + }, + ]; +} + +sub prefix_host_output { + my ($self, %options) = @_; + + return "Host '" . $options{instance_value}->{display} . "' : "; +} + +sub host_long_output { + my ($self, %options) = @_; + + return "checking host '" . $options{instance_value}->{display} . "'"; +} + +sub prefix_global_cpu_output { + my ($self, %options) = @_; + + return "cpu total average : "; +} + +sub prefix_cpu_output { + my ($self, %options) = @_; + + return "cpu '" . $options{instance_value}->{display} . "' "; +} sub new { my ($class, %options) = @_; @@ -31,35 +167,71 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "esx-hostname:s" => { name => 'esx_hostname' }, - "filter" => { name => 'filter' }, - "scope-datacenter:s" => { name => 'scope_datacenter' }, - "scope-cluster:s" => { name => 'scope_cluster' }, - "storage-status" => { name => 'storage_status' }, - "disconnect-status:s" => { name => 'disconnect_status', default => 'unknown' }, - }); + $options{options}->add_options(arguments => { + "esx-hostname:s" => { name => 'esx_hostname' }, + "filter" => { name => 'filter' }, + "scope-datacenter:s" => { name => 'scope_datacenter' }, + "scope-cluster:s" => { name => 'scope_cluster' }, + "storage-status" => { name => 'storage_status' }, + "unknown-status:s" => { name => 'unknown_status', default => '%{status} !~ /^connected$/i' }, + "warning-status:s" => { name => 'warning_status', default => '' }, + "critical-status:s" => { name => 'critical_status', default => '' }, + }); + return $self; } sub check_options { my ($self, %options) = @_; - $self->SUPER::init(%options); + $self->SUPER::check_options(%options); - if ($self->{output}->is_litteral_status(status => $self->{option_results}->{disconnect_status}) == 0) { - $self->{output}->add_option_msg(short_msg => "Wrong disconnect-status status option '" . $self->{option_results}->{disconnect_status} . "'."); - $self->{output}->option_exit(); - } + $self->change_macros(macros => ['unknown_status', 'warning_status', 'critical_status']); } -sub run { +sub manage_selection { my ($self, %options) = @_; - $self->{connector} = $options{custom}; - $self->{connector}->add_params(params => $self->{option_results}, - command => 'healthhost'); - $self->{connector}->run(); + $self->{global} = { total_problems => 0, total => 0 }; + $self->{host} = {}; + my $response = $options{custom}->execute(params => $self->{option_results}, + command => 'healthhost'); + + foreach my $host_id (keys %{$response->{data}}) { + my $host_name = $response->{data}->{$host_id}->{name}; + $self->{host}->{$host_name} = { display => $host_name, + global_host => { + state => $response->{data}->{$host_id}->{state}, + }, + global_summary => {}, + global_problems => { + ok => 0, total_problems => 0, red => 0, yellow => 0, total => 0, + }, + }; + + my $i = 0; + foreach (('memory_info', 'cpu_info', 'sensor_info', 'storage_info')) { + if (defined($response->{data}->{$host_id}->{$_})) { + $self->{host}->{$host_name}->{global_problems}->{ok} += $response->{data}->{$host_id}->{$_}->{ok}; + $self->{host}->{$host_name}->{global_problems}->{red} += $response->{data}->{$host_id}->{$_}->{red}; + $self->{host}->{$host_name}->{global_problems}->{yellow} += $response->{data}->{$host_id}->{$_}->{yellow}; + $self->{host}->{$host_name}->{global_problems}->{total_problems} += + $self->{host}->{$host_name}->{global_problems}->{red} + $self->{host}->{$host_name}->{global_problems}->{yellow}; + $self->{host}->{$host_name}->{global_problems}->{total} += + $response->{data}->{$host_id}->{$_}->{ok} + $response->{data}->{$host_id}->{$_}->{red} + $response->{data}->{$host_id}->{$_}->{yellow}; + foreach (@{$response->{data}->{$host_id}->{$_}->{summary_yellow}}, @{$response->{data}->{$host_id}->{$_}->{summary_red}}) { + $self->{host}->{$host_name}->{global_summary}->{$i} = { + type => defined($_->{type}) ? $_->{type} : '', + name => $_->{name}, + summary => $_->{summary}, + }; + } + $i++; + } + } + + $self->{global}->{total_problems} += $self->{host}->{$host_name}->{global_problems}->{red} + $self->{host}->{$host_name}->{global_problems}->{yellow}; + $self->{global}->{total} += $self->{host}->{$host_name}->{global_problems}->{total}; + } } 1; @@ -93,9 +265,30 @@ Search in following cluster(s) (can be a regexp). Check storage(s) status. -=item B<--disconnect-status> +=item B<--unknown-status> -Status if ESX host disconnected (default: 'unknown'). +Set warning threshold for status (Default: '%{status} !~ /^connected$/i'). +Can used special variables like: %{status} + +=item B<--warning-status> + +Set warning threshold for status (Default: ''). +Can used special variables like: %{status} + +=item B<--critical-status> + +Set critical threshold for status (Default: ''). +Can used special variables like: %{status} + +=item B<--warning-*> + +Threshold warning. +Can be: 'total-problems', 'problems', 'problems-yellow', 'problems-red'. + +=item B<--critical-*> + +Threshold critical. +Can be: 'total-problems', 'problems', 'problems-yellow', 'problems-red'. =back diff --git a/centreon-plugins/apps/vmware/connector/mode/limitvm.pm b/centreon-plugins/apps/vmware/connector/mode/limitvm.pm index 2138e9eaa..cf80864bc 100644 --- a/centreon-plugins/apps/vmware/connector/mode/limitvm.pm +++ b/centreon-plugins/apps/vmware/connector/mode/limitvm.pm @@ -20,10 +20,113 @@ package apps::vmware::connector::mode::limitvm; -use base qw(centreon::plugins::mode); +use base qw(centreon::plugins::templates::counter); use strict; use warnings; +use centreon::plugins::templates::catalog_functions qw(catalog_status_threshold); + +sub custom_limit_output { + my ($self, %options) = @_; + + my $msg; + if ($self->{result_values}->{limit} != -1) { + $msg = sprintf("%s limit set", $self->{result_values}->{label}); + } else { + $msg = sprintf("no %s limit set", $self->{result_values}->{label}); + } + + return $msg; +} + +sub custom_limit_calc { + my ($self, %options) = @_; + + $self->{result_values}->{limit} = $options{new_datas}->{$self->{instance} . '_'. $options{extra_options}->{label_ref} . '_limit'}; + $self->{result_values}->{label} = $options{extra_options}->{label_ref}; + $self->{result_values}->{connection_state} = $options{new_datas}->{$self->{instance} . '_connection_state'}; + $self->{result_values}->{power_state} = $options{new_datas}->{$self->{instance} . '_power_state'}; + $self->{result_values}->{name} = $options{new_datas}->{$self->{instance} . '_name'}; + + return 0; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'cpu_alarms', type => 2, cb_long_output => 'cpu_long_output', message_multiple => '0 cpu limit problem(s) detected', format_output => '%s cpu limit problem(s) detected', display_counter_problem => { label => 'cpu_alerts', min => 0 }, + group => [ { name => 'cpu_alarm', cb_prefix_output => 'prefix_vm_output', skipped_code => { -11 => 1 } } ] + }, + { name => 'memory_alarms', type => 2,cb_long_output => 'memory_long_output', message_multiple => '0 memory limit problem(s) detected', format_output => '%s memory limit problem(s) detected', display_counter_problem => { label => 'memory_alerts', min => 0 }, + group => [ { name => 'memory_alarm', cb_prefix_output => 'prefix_vm_output', skipped_code => { -11 => 1 } } ] + }, + { name => 'disk_alarms', type => 2, cb_long_output => 'disk_long_output', message_multiple => '0 disk limit problem(s) detected', format_output => '%s disk limit problem(s) detected', display_counter_problem => { label => 'disk_alerts', min => 0 }, + group => [ { name => 'disk_alarm', cb_prefix_output => 'prefix_vm_output', skipped_code => { -11 => 1 } } ] + }, + ]; + + $self->{maps_counters}->{cpu_alarm} = [ + { label => 'cpu-status', threshold => 0, set => { + key_values => [ { name => 'name' }, { name => 'connection_state' }, { name => 'power_state' }, { name => 'cpu_limit' } ], + closure_custom_calc => $self->can('custom_limit_calc'), closure_custom_calc_extra_options => { label_ref => 'cpu' }, + closure_custom_output => $self->can('custom_limit_output'), + closure_custom_perfdata => sub { return 0; }, + closure_custom_threshold_check => \&catalog_status_threshold, + } + }, + ]; + $self->{maps_counters}->{memory_alarm} = [ + { label => 'memory-status', threshold => 0, set => { + key_values => [ { name => 'name' }, { name => 'connection_state' }, { name => 'power_state' }, { name => 'memory_limit' } ], + closure_custom_calc => $self->can('custom_limit_calc'), closure_custom_calc_extra_options => { label_ref => 'memory' }, + closure_custom_output => $self->can('custom_limit_output'), + closure_custom_perfdata => sub { return 0; }, + closure_custom_threshold_check => \&catalog_status_threshold, + } + }, + ]; + $self->{maps_counters}->{disk_alarm} = [ + { label => 'disk-status', threshold => 0, set => { + key_values => [ { name => 'name' }, { name => 'connection_state' }, { name => 'power_state' }, { name => 'disk_limit' } ], + closure_custom_calc => $self->can('custom_limit_calc'), closure_custom_calc_extra_options => { label_ref => 'disk' }, + closure_custom_output => $self->can('custom_limit_output'), + closure_custom_perfdata => sub { return 0; }, + closure_custom_threshold_check => \&catalog_status_threshold, + } + }, + ]; +} + +sub cpu_long_output { + my ($self, %options) = @_; + + return "checking cpu limit"; +} + +sub memory_long_output { + my ($self, %options) = @_; + + return "checking memory limit"; +} + +sub disk_long_output { + my ($self, %options) = @_; + + return "checking disk limit"; +} + +sub prefix_vm_output { + my ($self, %options) = @_; + + my $msg = "Virtual machine '" . $options{instance_value}->{name} . "'"; + if (defined($options{instance_value}->{config_annotation})) { + $msg .= ' [annotation: ' . $options{instance_value}->{config_annotation} . ']'; + } + $msg .= ' : '; + + return $msg; +} sub new { my ($class, %options) = @_; @@ -31,51 +134,77 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "vm-hostname:s" => { name => 'vm_hostname' }, - "filter" => { name => 'filter' }, - "filter-description:s" => { name => 'filter_description' }, - "disconnect-status:s" => { name => 'disconnect_status', default => 'unknown' }, - "cpu-limitset-status:s" => { name => 'cpu_limitset_status', default => 'critical' }, - "memory-limitset-status:s" => { name => 'memory_limitset_status', default => 'critical' }, - "disk-limitset-status:s" => { name => 'disk_limitset_status', default => 'critical' }, - "nopoweredon-skip" => { name => 'nopoweredon_skip' }, - "display-description" => { name => 'display_description' }, - "check-disk-limit" => { name => 'check_disk_limit' }, - }); + $options{options}->add_options(arguments => { + "vm-hostname:s" => { name => 'vm_hostname' }, + "filter" => { name => 'filter' }, + "filter-description:s" => { name => 'filter_description' }, + "display-description" => { name => 'display_description' }, + "check-disk-limit" => { name => 'check_disk_limit' }, + "warning-disk-status:s" => { name => 'warning_disk_status', default => '' }, + "critical-disk-status:s" => { name => 'critical_disk_status', default => '%{connection_state} !~ /^connected$/i || %{limit} != -1' }, + "warning-cpu-status:s" => { name => 'warning_cpu_status', default => '' }, + "critical-cpu-status:s" => { name => 'critical_cpu_status', default => '%{connection_state} !~ /^connected$/i || %{limit} != -1' }, + "warning-memory-status:s" => { name => 'warning_memory_status', default => '' }, + "critical-memory-status:s" => { name => 'critical_memory_status', default => '%{connection_state} !~ /^connected$/i || %{limit} != -1' }, + }); + return $self; } sub check_options { my ($self, %options) = @_; - $self->SUPER::init(%options); - - if ($self->{output}->is_litteral_status(status => $self->{option_results}->{disconnect_status}) == 0) { - $self->{output}->add_option_msg(short_msg => "Wrong disconnect-status option '" . $self->{option_results}->{disconnect_status} . "'."); - $self->{output}->option_exit(); - } - if ($self->{output}->is_litteral_status(status => $self->{option_results}->{cpu_limitset_status}) == 0) { - $self->{output}->add_option_msg(short_msg => "Wrong cpu-limitset-status option '" . $self->{option_results}->{cpu_limitset_status} . "'."); - $self->{output}->option_exit(); - } - if ($self->{output}->is_litteral_status(status => $self->{option_results}->{memory_limitset_status}) == 0) { - $self->{output}->add_option_msg(short_msg => "Wrong memory-limitset-status option '" . $self->{option_results}->{memory_limitset_status} . "'."); - $self->{output}->option_exit(); - } - if ($self->{output}->is_litteral_status(status => $self->{option_results}->{disk_limitset_status}) == 0) { - $self->{output}->add_option_msg(short_msg => "Wrong disk-limitset-status option '" . $self->{option_results}->{disk_limitset_status} . "'."); - $self->{output}->option_exit(); - } + $self->SUPER::check_options(%options); + + $self->change_macros(macros => ['warning_disk_status', 'critical_disk_status','warning_memory_status', 'critical_memory_status', + 'warning_cpu_status', 'critical_cpu_status']); } -sub run { +sub manage_selection { my ($self, %options) = @_; - $self->{connector} = $options{custom}; - $self->{connector}->add_params(params => $self->{option_results}, - command => 'limitvm'); - $self->{connector}->run(); + my $response = $options{custom}->execute(params => $self->{option_results}, + command => 'limitvm'); + + my $i = 0; + $self->{cpu_alarms}->{global} = { cpu_alarm => {} }; + $self->{memory_alarms}->{global} = { memory_alarm => {} }; + $self->{disk_alarms}->{global} = { disk_alarm => {} } if (defined($self->{option_results}->{check_disk_limit})); + foreach my $vm_id (keys %{$response->{data}}) { + my $vm_name = $response->{data}->{$vm_id}->{name}; + + $self->{cpu_alarms}->{global}->{cpu_alarm}->{$i} = { + name => $vm_name, + config_annotation => defined($self->{option_results}->{display_description}) ? $options{custom}->strip_cr(value => $response->{data}->{$vm_id}->{'config.annotation'}) : undef, + connection_state => $response->{data}->{$vm_id}->{connection_state}, + power_state => $response->{data}->{$vm_id}->{power_state}, + cpu_limit => $response->{data}->{$vm_id}->{'config.cpuAllocation.limit'}, + }; + $self->{memory_alarms}->{global}->{memory_alarm}->{$i} = { + name => $vm_name, + config_annotation => defined($self->{option_results}->{display_description}) ? $options{custom}->strip_cr(value => $response->{data}->{$vm_id}->{'config.annotation'}) : undef, + connection_state => $response->{data}->{$vm_id}->{connection_state}, + power_state => $response->{data}->{$vm_id}->{power_state}, + memory_limit => $response->{data}->{$vm_id}->{'config.memoryAllocation.limit'} + }; + + if (defined($self->{option_results}->{check_disk_limit})) { + $self->{disk_alarms}->{global}->{disk_alarm}->{$i} = { + name => $vm_name, + config_annotation => defined($self->{option_results}->{display_description}) ? $options{custom}->strip_cr(value => $response->{data}->{$vm_id}->{'config.annotation'}) : undef, + connection_state => $response->{data}->{$vm_id}->{connection_state}, + power_state => $response->{data}->{$vm_id}->{power_state}, + disk_limit => -1 + }; + + foreach (@{$response->{data}->{$vm_id}->{'config.storageIOAllocation.limit'}}) { + if ($_->{limit} != -1) { + $self->{disk_alarms}->{global}->{disk_alarm}->{$i}->{disk_limit} = 1; + } + } + } + + $i++; + } } 1; @@ -101,34 +230,29 @@ VM hostname is a regexp. Filter also virtual machines description (can be a regexp). -=item B<--disconnect-status> - -Status if VM disconnected (default: 'unknown'). - -=item B<--nopoweredon-skip> - -Skip check if VM is not poweredOn. - =item B<--display-description> Display virtual machine description. -=item B<--cpu-limitset-status> - -Status if cpu limit is set (default: critical). - -=item B<--memory-limitset-status> - -Status if memory limit is set (default: critical). - -=item B<--disk-limitset-status> - -Status if disk limit is set (default: critical). - =item B<--check-disk-limit> Check disk limits (since vsphere 5.0). +=item B<--unknown-status> + +Set warning threshold for status (Default: '%{connection_state} !~ /^connected$/i'). +Can used special variables like: %{status} + +=item B<--warning-status> + +Set warning threshold for status (Default: ''). +Can used special variables like: %{status} + +=item B<--critical-status> + +Set critical threshold for status (Default: ''). +Can used special variables like: %{status} + =back =cut diff --git a/centreon-plugins/centreon/plugins/templates/counter.pm b/centreon-plugins/centreon/plugins/templates/counter.pm index 536e0acd0..57d58e556 100644 --- a/centreon-plugins/centreon/plugins/templates/counter.pm +++ b/centreon-plugins/centreon/plugins/templates/counter.pm @@ -310,6 +310,7 @@ sub run_group { my ($self, %options) = @_; my $multiple = 1; + return if (scalar(keys %{$self->{$options{config}->{name}}}) <= 0); if (scalar(keys %{$self->{$options{config}->{name}}}) == 1) { $multiple = 0; } @@ -319,6 +320,8 @@ sub run_group { short_msg => $options{config}->{message_multiple}); } + my $format_output = defined($options{config}->{format_output}) ? $options{config}->{format_output} : '%s problem(s) detected'; + my ($global_exit, $total_problems) = ([], 0); foreach my $id (sort keys %{$self->{$options{config}->{name}}}) { $self->{most_critical_instance} = 'ok'; @@ -343,7 +346,7 @@ sub run_group { if ($multiple == 0 && (!defined($group->{display}) || $group->{display} != 0)) { $self->{output}->output_add(severity => $self->{most_critical_instance}, - short_msg => "${prefix_output}$self->{lproblems} problem(s) detected"); + short_msg => sprintf("${prefix_output}" . $format_output, $self->{lproblems})); } } } @@ -352,7 +355,7 @@ sub run_group { my $exit = $self->{output}->get_most_critical(status => [ @{$global_exit} ]); if (!$self->{output}->is_status(litteral => 1, value => $exit, compare => 'ok')) { $self->{output}->output_add(severity => $exit, - short_msg => "$total_problems problem(s) detected"); + short_msg => sprintf($format_output, $total_problems)); } }