enh(vmware/connector): see details (#3330)
- add modes: cpu-cluster, licences, storage-host - mode datastore-iops: add total iops counters - mode datastore-usage: add --refresh option - add option --empty-continue for modes: snapshot-vm, tools-vm - fix --time-shift option: now it's working
This commit is contained in:
parent
a5139dd79b
commit
b3e9d540fc
|
@ -86,7 +86,7 @@ sub check_options {
|
|||
$self->{vsphere_username} = (defined($self->{option_results}->{vsphere_username})) ? shift(@{$self->{option_results}->{vsphere_username}}) : undef;
|
||||
$self->{vsphere_password} = (defined($self->{option_results}->{vsphere_password})) ? shift(@{$self->{option_results}->{vsphere_password}}) : undef;
|
||||
$self->{sampling_period} = (defined($self->{option_results}->{sampling_period})) ? shift(@{$self->{option_results}->{sampling_period}}) : undef;
|
||||
$self->{time_shift} = (defined($self->{option_results}->{sampling_period})) ? shift(@{$self->{option_results}->{time_shift}}) : 0;
|
||||
$self->{time_shift} = (defined($self->{option_results}->{time_shift})) ? shift(@{$self->{option_results}->{time_shift}}) : 0;
|
||||
$self->{unknown_connector_status} = (defined($self->{option_results}->{unknown_connector_status})) ? $self->{option_results}->{unknown_connector_status} : '%{code} < 0 || (%{code} > 0 && %{code} < 200)';
|
||||
$self->{warning_connector_status} = (defined($self->{option_results}->{warning_connector_status})) ? $self->{option_results}->{warning_connector_status} : '';
|
||||
$self->{critical_connector_status} = (defined($self->{option_results}->{critical_connector_status})) ? $self->{option_results}->{critical_connector_status} : '';
|
||||
|
@ -221,7 +221,7 @@ sub strip_cr {
|
|||
|
||||
sub execute {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
|
||||
$self->add_params(%options);
|
||||
|
||||
# Build request
|
||||
|
|
|
@ -0,0 +1,142 @@
|
|||
#
|
||||
# Copyright 2021 Centreon (http://www.centreon.com/)
|
||||
#
|
||||
# Centreon is a full-fledged industry-strength solution that meets
|
||||
# the needs in IT infrastructure and application monitoring for
|
||||
# service performance.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
package apps::vmware::connector::mode::cpucluster;
|
||||
|
||||
use base qw(centreon::plugins::templates::counter);
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
sub prefix_cluster_output {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
return "Cluster '" . $options{instance} . "' : ";
|
||||
}
|
||||
|
||||
sub cluster_long_output {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
return "checking cluster '" . $options{instance} . "'";
|
||||
}
|
||||
|
||||
sub prefix_cpu_output {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
return "cpu total average: ";
|
||||
}
|
||||
|
||||
sub set_counters {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
$self->{maps_counters_type} = [
|
||||
{ name => 'clusters', type => 3, cb_prefix_output => 'prefix_cluster_output', cb_long_output => 'cluster_long_output', indent_long_output => ' ', message_multiple => 'All clusters are ok',
|
||||
group => [
|
||||
{ name => 'cpu', cb_prefix_output => 'prefix_cpu_output', type => 0, skipped_code => { -10 => 1 } }
|
||||
]
|
||||
}
|
||||
];
|
||||
|
||||
$self->{maps_counters}->{cpu} = [
|
||||
{ label => 'total-cpu', nlabel => 'cluster.cpu.utilization.percentage', set => {
|
||||
key_values => [ { name => 'cpu_average' } ],
|
||||
output_template => '%s %%',
|
||||
perfdatas => [
|
||||
{ template => '%s', unit => '%', min => 0, max => 100, label_extra_instance => 1 }
|
||||
]
|
||||
}
|
||||
},
|
||||
{ label => 'total-cpu-mhz', nlabel => 'cluster.cpu.utilization.mhz', set => {
|
||||
key_values => [ { name => 'cpu_average_mhz' } ],
|
||||
output_template => '%s MHz',
|
||||
perfdatas => [
|
||||
{ template => '%s', unit => 'MHz', min => 0, label_extra_instance => 1 }
|
||||
]
|
||||
}
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
sub new {
|
||||
my ($class, %options) = @_;
|
||||
my $self = $class->SUPER::new(package => __PACKAGE__, %options, force_new_perfdata => 1);
|
||||
bless $self, $class;
|
||||
|
||||
$options{options}->add_options(arguments => {
|
||||
'cluster-name:s' => { name => 'cluster_name' },
|
||||
'filter' => { name => 'filter' },
|
||||
'scope-datacenter:s' => { name => 'scope_datacenter' }
|
||||
});
|
||||
|
||||
return $self;
|
||||
}
|
||||
|
||||
sub manage_selection {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
$self->{host} = {};
|
||||
my $response = $options{custom}->execute(
|
||||
params => $self->{option_results},
|
||||
command => 'cpucluster'
|
||||
);
|
||||
|
||||
$self->{clusters} = {};
|
||||
foreach my $cluster_id (keys %{$response->{data}}) {
|
||||
my $cluster_name = $response->{data}->{$cluster_id}->{name};
|
||||
$self->{clusters}->{$cluster_name} = {
|
||||
cpu => {
|
||||
cpu_average => $response->{data}->{$cluster_id}->{'cpu.usage.average'},
|
||||
cpu_average_mhz => $response->{data}->{$cluster_id}->{'cpu.usagemhz.average'}
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
__END__
|
||||
|
||||
=head1 MODE
|
||||
|
||||
Check cluster cpu usage.
|
||||
|
||||
=over 8
|
||||
|
||||
=item B<--cluster-name>
|
||||
|
||||
cluster to check.
|
||||
If not set, we check all clusters.
|
||||
|
||||
=item B<--filter>
|
||||
|
||||
Cluster name is a regexp.
|
||||
|
||||
=item B<--scope-datacenter>
|
||||
|
||||
Search in following datacenter(s) (can be a regexp).
|
||||
|
||||
=item B<--warning-*> B<--critical-*>
|
||||
|
||||
Thresholds.
|
||||
Can be: 'total-cpu', 'total-cpu-mhz'.
|
||||
|
||||
=back
|
||||
|
||||
=cut
|
|
@ -52,7 +52,7 @@ sub set_counters {
|
|||
]
|
||||
}
|
||||
];
|
||||
|
||||
|
||||
$self->{maps_counters}->{global} = [
|
||||
{
|
||||
label => 'status', type => 2, unknown_default => '%{status} !~ /^connected$/i',
|
||||
|
@ -86,7 +86,7 @@ sub set_counters {
|
|||
}
|
||||
}
|
||||
];
|
||||
|
||||
|
||||
$self->{maps_counters}->{cpu} = [
|
||||
{ label => 'cpu', nlabel => 'host.core.cpu.utilization.percentage', set => {
|
||||
key_values => [ { name => 'cpu_usage' }, { name => 'display' } ],
|
||||
|
|
|
@ -33,20 +33,64 @@ sub custom_status_output {
|
|||
return 'accessible ' . $self->{result_values}->{accessible};
|
||||
}
|
||||
|
||||
sub prefix_datastore_output {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
return "Datastore '" . $options{instance_value}->{display} . "' : ";
|
||||
}
|
||||
|
||||
sub datastore_long_output {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
return "checking datastore '" . $options{instance_value}->{display} . "'";
|
||||
}
|
||||
|
||||
sub prefix_vm_output {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
return "virtual machine '" . $options{instance_value}->{display} . "' ";
|
||||
}
|
||||
|
||||
sub prefix_global_iops_output {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
return 'Total ';
|
||||
}
|
||||
|
||||
sub set_counters {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
$self->{maps_counters_type} = [
|
||||
{ name => 'global_iops', type => 0, cb_prefix_output => 'prefix_global_iops_output', skipped_code => { -10 => 1 } },
|
||||
{ name => 'datastore', type => 3, cb_prefix_output => 'prefix_datastore_output', cb_long_output => 'datastore_long_output', indent_long_output => ' ', message_multiple => 'All datastores are ok',
|
||||
group => [
|
||||
{ name => 'global', type => 0, skipped_code => { -10 => 1 } },
|
||||
{ name => 'global_iops', type => 0, skipped_code => { -10 => 1 } },
|
||||
{ name => 'ds_global', type => 0, skipped_code => { -10 => 1 } },
|
||||
{ name => 'ds_global_iops', type => 0, skipped_code => { -10 => 1 } },
|
||||
{ name => 'vm', cb_prefix_output => 'prefix_vm_output', message_multiple => 'All virtual machines IOPs are ok', type => 1, skipped_code => { -10 => 1 } }
|
||||
]
|
||||
}
|
||||
];
|
||||
|
||||
$self->{maps_counters}->{global} = [
|
||||
|
||||
$self->{maps_counters}->{global_iops} = [
|
||||
{ label => 'read-total', nlabel => 'datastores.read.usage.iops', set => {
|
||||
key_values => [ { name => 'read' } ],
|
||||
output_template => 'read: %s iops',
|
||||
perfdatas => [
|
||||
{ label => 'total_riops', template => '%s', unit => 'iops', min => 0 }
|
||||
]
|
||||
}
|
||||
},
|
||||
{ label => 'write-total', nlabel => 'datastores.write.usage.iops', set => {
|
||||
key_values => [ { name => 'write' } ],
|
||||
output_template => 'write: %s iops',
|
||||
perfdatas => [
|
||||
{ label => 'total_wiops', template => '%s', unit => 'iops', min => 0 }
|
||||
]
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
$self->{maps_counters}->{ds_global} = [
|
||||
{
|
||||
label => 'status', type => 2, unknown_default => '%{accessible} !~ /^true|1$/i',
|
||||
set => {
|
||||
|
@ -58,7 +102,7 @@ sub set_counters {
|
|||
}
|
||||
];
|
||||
|
||||
$self->{maps_counters}->{global_iops} = [
|
||||
$self->{maps_counters}->{ds_global_iops} = [
|
||||
{ label => 'read', nlabel => 'datastore.read.usage.iops', set => {
|
||||
key_values => [ { name => 'read' } ],
|
||||
output_template => '%s read iops',
|
||||
|
@ -101,24 +145,6 @@ sub set_counters {
|
|||
];
|
||||
}
|
||||
|
||||
sub prefix_datastore_output {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
return "Datastore '" . $options{instance_value}->{display} . "' : ";
|
||||
}
|
||||
|
||||
sub datastore_long_output {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
return "checking datastore '" . $options{instance_value}->{display} . "'";
|
||||
}
|
||||
|
||||
sub prefix_vm_output {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
return "virtual machine '" . $options{instance_value}->{display} . "' ";
|
||||
}
|
||||
|
||||
sub new {
|
||||
my ($class, %options) = @_;
|
||||
my $self = $class->SUPER::new(package => __PACKAGE__, %options);
|
||||
|
@ -152,24 +178,28 @@ sub manage_selection {
|
|||
$self->{output}->exit();
|
||||
}
|
||||
|
||||
$self->{global_iops} = { write => 0, read => 0 };
|
||||
foreach my $ds_id (keys %{$response->{data}}) {
|
||||
my $ds_name = $response->{data}->{$ds_id}->{name};
|
||||
$self->{datastore}->{$ds_name} = { display => $ds_name,
|
||||
vm => {},
|
||||
global => {
|
||||
accessible => $response->{data}->{$ds_id}->{accessible},
|
||||
ds_global => {
|
||||
accessible => $response->{data}->{$ds_id}->{accessible}
|
||||
},
|
||||
global_iops => {
|
||||
ds_global_iops => {
|
||||
write => $response->{data}->{$ds_id}->{'disk.numberWrite.summation'},
|
||||
read => $response->{data}->{$ds_id}->{'disk.numberRead.summation'},
|
||||
},
|
||||
read => $response->{data}->{$ds_id}->{'disk.numberRead.summation'}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
$self->{global_iops}->{write} += $response->{data}->{$ds_id}->{'disk.numberWrite.summation'};
|
||||
$self->{global_iops}->{read} += $response->{data}->{$ds_id}->{'disk.numberRead.summation'};
|
||||
|
||||
foreach my $vm_name (sort keys %{$response->{data}->{$ds_id}->{vm}}) {
|
||||
$self->{datastore}->{$ds_name}->{vm}->{$vm_name} = {
|
||||
display => $vm_name,
|
||||
display => $vm_name,
|
||||
write => $response->{data}->{$ds_id}->{vm}->{$vm_name}->{'disk.numberWrite.summation'},
|
||||
read => $response->{data}->{$ds_id}->{vm}->{$vm_name}->{'disk.numberRead.summation'},
|
||||
read => $response->{data}->{$ds_id}->{vm}->{$vm_name}->{'disk.numberRead.summation'}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -216,15 +246,11 @@ Can used special variables like: %{accessible}
|
|||
Set critical threshold for status (Default: '').
|
||||
Can used special variables like: %{accessible}
|
||||
|
||||
=item B<--warning-*>
|
||||
=item B<--warning-*> B<--critical-*>
|
||||
|
||||
Threshold warning.
|
||||
Can be: 'read', 'write', 'read-vm', 'write-vm'.
|
||||
|
||||
=item B<--critical-*>
|
||||
|
||||
Threshold critical.
|
||||
Can be: 'read', 'write', 'read-vm', 'write-vm'.
|
||||
Thresholds.
|
||||
Can be: 'read-total', 'write-total',
|
||||
'read', 'write', 'read-vm', 'write-vm'.
|
||||
|
||||
=back
|
||||
|
||||
|
|
|
@ -151,7 +151,8 @@ sub new {
|
|||
'scope-datacenter:s' => { name => 'scope_datacenter' },
|
||||
'filter-host:s' => { name => 'filter_host' },
|
||||
'units:s' => { name => 'units', default => '' },
|
||||
'free' => { name => 'free' }
|
||||
'free' => { name => 'free' },
|
||||
'refresh' => { name => 'refresh' }
|
||||
});
|
||||
|
||||
return $self;
|
||||
|
@ -259,6 +260,10 @@ Search in following datacenter(s) (can be a regexp).
|
|||
|
||||
Filter datastores attached to hosts (can be a regexp).
|
||||
|
||||
=item B<--refresh>
|
||||
|
||||
Explicitly ask vmware to refreshes free-space and capacity values (slower).
|
||||
|
||||
=item B<--unknown-status>
|
||||
|
||||
Set warning threshold for status (Default: '%{accessible} !~ /^true|1$/i').
|
||||
|
|
|
@ -51,91 +51,6 @@ sub custom_summary_output {
|
|||
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', nlabel => 'host.health.problems.current.count', set => {
|
||||
key_values => [ { name => 'total_problems' }, { name => 'total' } ],
|
||||
output_template => '%s total health issue(s) found',
|
||||
perfdatas => [
|
||||
{ label => 'total_problems', template => '%s',
|
||||
min => 0, max => 'total' }
|
||||
]
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
$self->{maps_counters}->{global_host} = [
|
||||
{
|
||||
label => 'status', type => 2, unknown_default => '%{status} !~ /^connected$/i',
|
||||
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_ng
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
$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', nlabel => 'host.health.problems.current.count', set => {
|
||||
key_values => [ { name => 'total_problems' }, { name => 'total' } ],
|
||||
output_template => '%s total health issue(s) found',
|
||||
perfdatas => [
|
||||
{ label => 'problems', template => '%s',
|
||||
min => 0, max => 'total', label_extra_instance => 1 }
|
||||
]
|
||||
}
|
||||
},
|
||||
{ label => 'problems-yellow', nlabel => 'host.health.yellow.current.count', set => {
|
||||
key_values => [ { name => 'yellow' }, { name => 'total' } ],
|
||||
output_template => '%s yellow health issue(s) found',
|
||||
perfdatas => [
|
||||
{ label => 'problems_yellow', template => '%s',
|
||||
min => 0, max => 'total', label_extra_instance => 1 }
|
||||
]
|
||||
}
|
||||
},
|
||||
{ label => 'problems-red', nlabel => 'host.health.red.current.count', set => {
|
||||
key_values => [ { name => 'red' }, { name => 'total' } ],
|
||||
output_template => '%s red health issue(s) found',
|
||||
perfdatas => [
|
||||
{ label => 'problems_red', template => '%s',
|
||||
min => 0, max => 'total', 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) = @_;
|
||||
|
||||
|
@ -160,9 +75,144 @@ sub prefix_cpu_output {
|
|||
return "cpu '" . $options{instance_value}->{display} . "' ";
|
||||
}
|
||||
|
||||
sub prefix_sensor_output {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
return "sensor '" . $options{instance} . "' ";
|
||||
}
|
||||
|
||||
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 },
|
||||
{ name => 'sensors_temp', display_long => 1, cb_prefix_output => 'prefix_sensor_output', message_multiple => 'temperature sensors are ok', type => 1, skipped_code => { -10 => 1 } },
|
||||
{ name => 'sensors_fan', display_long => 1, cb_prefix_output => 'prefix_sensor_output', message_multiple => 'fan sensors are ok', type => 1, skipped_code => { -10 => 1 } },
|
||||
{ name => 'sensors_voltage', display_long => 1, cb_prefix_output => 'prefix_sensor_output', message_multiple => 'voltage sensors are ok', type => 1, skipped_code => { -10 => 1 } },
|
||||
{ name => 'sensors_power', display_long => 1, cb_prefix_output => 'prefix_sensor_output', message_multiple => 'power sensors are ok', type => 1, skipped_code => { -10 => 1 } }
|
||||
]
|
||||
}
|
||||
];
|
||||
|
||||
$self->{maps_counters}->{global} = [
|
||||
{ label => 'total-problems', nlabel => 'host.health.problems.current.count', set => {
|
||||
key_values => [ { name => 'total_problems' }, { name => 'total' } ],
|
||||
output_template => '%s total health issue(s) found',
|
||||
perfdatas => [
|
||||
{ template => '%s', min => 0, max => 'total' }
|
||||
]
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
$self->{maps_counters}->{global_host} = [
|
||||
{
|
||||
label => 'status', type => 2, unknown_default => '%{status} !~ /^connected$/i',
|
||||
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_ng
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
$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', nlabel => 'host.health.problems.current.count', set => {
|
||||
key_values => [ { name => 'total_problems' }, { name => 'total' } ],
|
||||
output_template => '%s total health issue(s) found',
|
||||
perfdatas => [
|
||||
{ template => '%s', min => 0, max => 'total', label_extra_instance => 1 }
|
||||
]
|
||||
}
|
||||
},
|
||||
{ label => 'problems-yellow', nlabel => 'host.health.yellow.current.count', set => {
|
||||
key_values => [ { name => 'yellow' }, { name => 'total' } ],
|
||||
output_template => '%s yellow health issue(s) found',
|
||||
perfdatas => [
|
||||
{ template => '%s', min => 0, max => 'total', label_extra_instance => 1 }
|
||||
]
|
||||
}
|
||||
},
|
||||
{ label => 'problems-red', nlabel => 'host.health.red.current.count', set => {
|
||||
key_values => [ { name => 'red' }, { name => 'total' } ],
|
||||
output_template => '%s red health issue(s) found',
|
||||
perfdatas => [
|
||||
{ template => '%s', min => 0, max => 'total', 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; }
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
$self->{maps_counters}->{sensors_temp} = [
|
||||
{ label => 'sensor-temperature', nlabel => 'host.sensor.temperature.celsius', set => {
|
||||
key_values => [ { name => 'value' } ],
|
||||
output_template => 'temperature: %s C',
|
||||
perfdatas => [
|
||||
{ template => '%s', unit => 'C', min => 0, label_extra_instance => 1 }
|
||||
]
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
$self->{maps_counters}->{sensors_fan} = [
|
||||
{ label => 'sensor-fan', nlabel => 'host.sensor.fan.speed.rpm', set => {
|
||||
key_values => [ { name => 'value' } ],
|
||||
output_template => 'fan speed: %s rpm',
|
||||
perfdatas => [
|
||||
{ template => '%s', unit => 'rpm', min => 0, label_extra_instance => 1 }
|
||||
]
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
$self->{maps_counters}->{sensors_voltage} = [
|
||||
{ label => 'sensor-voltage', nlabel => 'host.sensor.voltage.volt', set => {
|
||||
key_values => [ { name => 'value' } ],
|
||||
output_template => 'voltage: %s V',
|
||||
perfdatas => [
|
||||
{ template => '%s', unit => 'V', min => 0, label_extra_instance => 1 }
|
||||
]
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
$self->{maps_counters}->{sensors_power} = [
|
||||
{ label => 'sensor-power', nlabel => 'host.sensor.power.watt', set => {
|
||||
key_values => [ { name => 'value' } ],
|
||||
output_template => 'power: %s W',
|
||||
perfdatas => [
|
||||
{ template => '%s', unit => 'W', min => 0, label_extra_instance => 1 }
|
||||
]
|
||||
}
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
sub new {
|
||||
my ($class, %options) = @_;
|
||||
my $self = $class->SUPER::new(package => __PACKAGE__, %options);
|
||||
my $self = $class->SUPER::new(package => __PACKAGE__, %options, force_new_perfdata => 1);
|
||||
bless $self, $class;
|
||||
|
||||
$options{options}->add_options(arguments => {
|
||||
|
@ -195,9 +245,10 @@ sub manage_selection {
|
|||
global_summary => {},
|
||||
global_problems => {
|
||||
ok => 0, total_problems => 0, red => 0, yellow => 0, total => 0
|
||||
}
|
||||
},
|
||||
sensors_temp => {}
|
||||
};
|
||||
|
||||
|
||||
my $i = 0;
|
||||
foreach (('memory_info', 'cpu_info', 'sensor_info', 'storage_info')) {
|
||||
if (defined($response->{data}->{$host_id}->{$_})) {
|
||||
|
@ -221,6 +272,24 @@ sub manage_selection {
|
|||
}
|
||||
}
|
||||
|
||||
if (defined($response->{data}->{$host_id}->{sensor_info})) {
|
||||
foreach my $entry (@{$response->{data}->{$host_id}->{sensor_info}}) {
|
||||
next if ($entry->{current_reading} == 0);
|
||||
|
||||
$entry->{current_reading} *= 10 ** $entry->{power10};
|
||||
$entry->{name} =~ s/\s---\s.+//;
|
||||
if (lc($entry->{type}) eq 'temperature' && $entry->{unit} =~ /Degrees\s+C/i) {
|
||||
$self->{host}->{$host_name}->{sensors_temp}->{ $entry->{name} } = { value => $entry->{current_reading} };
|
||||
} elsif (lc($entry->{type}) eq 'fan' && $entry->{unit} =~ /rpm/i) {
|
||||
$self->{host}->{$host_name}->{sensors_fan}->{ $entry->{name} } = { value => $entry->{current_reading} };
|
||||
} elsif (lc($entry->{type}) eq 'voltage' && $entry->{unit} =~ /volts/i) {
|
||||
$self->{host}->{$host_name}->{sensors_voltage}->{ $entry->{name} } = { value => $entry->{current_reading} };
|
||||
} elsif (lc($entry->{type}) eq 'power' && $entry->{unit} =~ /watts/i) {
|
||||
$self->{host}->{$host_name}->{sensors_power}->{ $entry->{name} } = { value => $entry->{current_reading} };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$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};
|
||||
}
|
||||
|
@ -272,15 +341,11 @@ Can used special variables like: %{status}
|
|||
Set critical threshold for status (Default: '').
|
||||
Can used special variables like: %{status}
|
||||
|
||||
=item B<--warning-*>
|
||||
=item B<--warning-*> B<--critical-*>
|
||||
|
||||
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'.
|
||||
Thresholds.
|
||||
Can be: 'total-problems', 'problems', 'problems-yellow', 'problems-red',
|
||||
'sensor-temperature', 'sensor-fan', 'sensor-voltage', 'sensor-power'.
|
||||
|
||||
=back
|
||||
|
||||
|
|
|
@ -0,0 +1,345 @@
|
|||
#
|
||||
# Copyright 2021 Centreon (http://www.centreon.com/)
|
||||
#
|
||||
# Centreon is a full-fledged industry-strength solution that meets
|
||||
# the needs in IT infrastructure and application monitoring for
|
||||
# service performance.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
package apps::vmware::connector::mode::licenses;
|
||||
|
||||
use base qw(centreon::plugins::templates::counter);
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use centreon::plugins::misc;
|
||||
use POSIX;
|
||||
|
||||
my $unitdiv = { s => 1, w => 604800, d => 86400, h => 3600, m => 60 };
|
||||
my $unitdiv_long = { s => 'seconds', w => 'weeks', d => 'days', h => 'hours', m => 'minutes' };
|
||||
|
||||
sub custom_expires_perfdata {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
$self->{output}->perfdata_add(
|
||||
nlabel => $self->{nlabel} . '.' . $unitdiv_long->{ $self->{instance_mode}->{option_results}->{unit} },
|
||||
unit => $self->{instance_mode}->{option_results}->{unit},
|
||||
instances => $self->{result_values}->{name},
|
||||
value => floor($self->{result_values}->{expires_seconds} / $unitdiv->{ $self->{instance_mode}->{option_results}->{unit} }),
|
||||
warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{thlabel}),
|
||||
critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{thlabel}),
|
||||
min => 0
|
||||
);
|
||||
}
|
||||
|
||||
sub custom_expires_threshold {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
return $self->{perfdata}->threshold_check(
|
||||
value => floor($self->{result_values}->{expires_seconds} / $unitdiv->{ $self->{instance_mode}->{option_results}->{unit} }),
|
||||
threshold => [
|
||||
{ label => 'critical-' . $self->{thlabel}, exit_litteral => 'critical' },
|
||||
{ label => 'warning-'. $self->{thlabel}, exit_litteral => 'warning' },
|
||||
{ label => 'unknown-'. $self->{thlabel}, exit_litteral => 'unknown' }
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
sub custom_expires_output {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
my $msg;
|
||||
if ($self->{result_values}->{expires_seconds} == 0) {
|
||||
$msg = 'expired';
|
||||
} else {
|
||||
$msg = 'expires in ' . $self->{result_values}->{expires_human};
|
||||
}
|
||||
return $msg;
|
||||
}
|
||||
|
||||
sub custom_usage_output {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
my $msg;
|
||||
if ($self->{result_values}->{total} <= 0) {
|
||||
$msg = sprintf('used: %s (unlimited)', $self->{result_values}->{used});
|
||||
} else {
|
||||
$msg = sprintf(
|
||||
"total: %s used: %s (%.2f%%) free: %s (%.2f%%)",
|
||||
$self->{result_values}->{total},
|
||||
$self->{result_values}->{used}, $self->{result_values}->{prct_used},
|
||||
$self->{result_values}->{free}, $self->{result_values}->{prct_free}
|
||||
);
|
||||
}
|
||||
return $msg;
|
||||
}
|
||||
|
||||
sub custom_usage_calc {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
$self->{result_values}->{name} = $options{new_datas}->{$self->{instance} . '_name'};
|
||||
$self->{result_values}->{edition} = $options{new_datas}->{$self->{instance} . '_edition'};
|
||||
$self->{result_values}->{total} = $options{new_datas}->{$self->{instance} . '_total'};
|
||||
$self->{result_values}->{used} = $options{new_datas}->{$self->{instance} . '_used'};
|
||||
|
||||
if ($self->{result_values}->{total} == 0) {
|
||||
return -10 if ($options{extra_options}->{label} ne 'usage');
|
||||
return 0;
|
||||
}
|
||||
|
||||
$self->{result_values}->{prct_used} = $self->{result_values}->{used} * 100 / $self->{result_values}->{total};
|
||||
$self->{result_values}->{prct_free} = 100 - $self->{result_values}->{prct_used};
|
||||
$self->{result_values}->{free} = $self->{result_values}->{total} - $self->{result_values}->{used};
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
sub prefix_license_output {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
return sprintf(
|
||||
"License '%s' [edition: %s] ",
|
||||
$options{instance},
|
||||
$options{instance_value}->{edition}
|
||||
);
|
||||
}
|
||||
|
||||
sub set_counters {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
$self->{maps_counters_type} = [
|
||||
{ name => 'global', type => 0, skipped_code => { -10 => 1 } },
|
||||
{ name => 'licenses', type => 1, cb_prefix_output => 'prefix_license_output', message_multiple => 'All licenses are ok', skipped_code => { -10 => 1 } }
|
||||
];
|
||||
|
||||
$self->{maps_counters}->{global} = [
|
||||
{ label => 'total-licenses', nlabel => 'licenses.total.count', set => {
|
||||
key_values => [ { name => 'total' } ],
|
||||
output_template => 'Number of licenses: %s',
|
||||
perfdatas => [
|
||||
{ template => '%s', min => 0 }
|
||||
]
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
$self->{maps_counters}->{licenses} = [
|
||||
{ label => 'usage', nlabel => 'license.usage.count', set => {
|
||||
key_values => [
|
||||
{ name => 'edition' }, { name => 'name' }, { name => 'used' }, { name => 'total' }
|
||||
],
|
||||
closure_custom_calc_extra_options => { label => 'usage' },
|
||||
closure_custom_calc => $self->can('custom_usage_calc'),
|
||||
closure_custom_output => $self->can('custom_usage_output'),
|
||||
closure_custom_threshold_check => sub {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
return $self->{perfdata}->threshold_check(
|
||||
value => $self->{result_values}->{used}, threshold => [
|
||||
{ label => 'critical-' . $self->{thlabel}, exit_litteral => 'critical' },
|
||||
{ label => 'warning-' . $self->{thlabel}, exit_litteral => 'warning' }
|
||||
]
|
||||
);
|
||||
},
|
||||
closure_custom_perfdata => sub {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
$self->{output}->perfdata_add(
|
||||
nlabel => $self->{nlabel},
|
||||
instances => $self->{result_values}->{name},
|
||||
value => $self->{result_values}->{used},
|
||||
warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{thlabel}),
|
||||
critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{thlabel}),
|
||||
min => 0,
|
||||
max => $self->{result_values}->{total} > 0 ? $self->{result_values}->{total} : undef
|
||||
);
|
||||
}
|
||||
}
|
||||
},
|
||||
{ label => 'usage-free', nlabel => 'license.free.count', display_ok => 0, set => {
|
||||
key_values => [
|
||||
{ name => 'edition' }, { name => 'name' }, { name => 'used' }, { name => 'total' }
|
||||
],
|
||||
closure_custom_calc_extra_options => { label => 'free' },
|
||||
closure_custom_calc => $self->can('custom_usage_calc'),
|
||||
closure_custom_output => $self->can('custom_usage_output'),
|
||||
closure_custom_threshold_check => sub {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
return $self->{perfdata}->threshold_check(
|
||||
value => $self->{result_values}->{free}, threshold => [
|
||||
{ label => 'critical-' . $self->{thlabel}, exit_litteral => 'critical' },
|
||||
{ label => 'warning-'. $self->{thlabel}, exit_litteral => 'warning' }
|
||||
]
|
||||
);
|
||||
},
|
||||
closure_custom_perfdata => sub {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
$self->{output}->perfdata_add(
|
||||
nlabel => $self->{nlabel},
|
||||
instances => $self->{result_values}->{name},
|
||||
value => $self->{result_values}->{free},
|
||||
warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{thlabel}),
|
||||
critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{thlabel}),
|
||||
min => 0,
|
||||
max => $self->{result_values}->{total}
|
||||
);
|
||||
}
|
||||
}
|
||||
},
|
||||
{ label => 'usage-prct', nlabel => 'license.usage.percentage', display_ok => 0, set => {
|
||||
key_values => [
|
||||
{ name => 'edition' }, { name => 'name' }, { name => 'used' }, { name => 'total' }
|
||||
],
|
||||
closure_custom_calc_extra_options => { label => 'prct' },
|
||||
closure_custom_calc => $self->can('custom_usage_calc'),
|
||||
closure_custom_output => $self->can('custom_usage_output'),
|
||||
closure_custom_threshold_check => sub {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
return $self->{perfdata}->threshold_check(
|
||||
value => $self->{result_values}->{prct_used}, threshold => [
|
||||
{ label => 'critical-' . $self->{thlabel}, exit_litteral => 'critical' },
|
||||
{ label => 'warning-'. $self->{thlabel}, exit_litteral => 'warning' }
|
||||
]
|
||||
);
|
||||
},
|
||||
closure_custom_perfdata => sub {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
$self->{output}->perfdata_add(
|
||||
nlabel => $self->{nlabel},
|
||||
unit => '%',
|
||||
instances => $self->{result_values}->{name},
|
||||
value => $self->{result_values}->{prct_used},
|
||||
warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{thlabel}),
|
||||
critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{thlabel}),
|
||||
min => 0, max => 100
|
||||
);
|
||||
}
|
||||
}
|
||||
},
|
||||
{ label => 'expires', nlabel => 'license.expires', set => {
|
||||
key_values => [ { name => 'expires_seconds' }, { name => 'expires_human' }, { name => 'name' } ],
|
||||
closure_custom_output => $self->can('custom_expires_output'),
|
||||
closure_custom_perfdata => $self->can('custom_expires_perfdata'),
|
||||
closure_custom_threshold_check => $self->can('custom_expires_threshold')
|
||||
}
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
sub new {
|
||||
my ($class, %options) = @_;
|
||||
my $self = $class->SUPER::new(package => __PACKAGE__, %options, force_new_perfdata => 1);
|
||||
bless $self, $class;
|
||||
|
||||
$options{options}->add_options(arguments => {
|
||||
'filter-name:s' => { name => 'filter_name' },
|
||||
'exclude-name:s' => { name => 'exclude_name' },
|
||||
'filter-edition:s' => { name => 'filter_edition' },
|
||||
'exclude-edition:s' => { name => 'exclude_edition' },
|
||||
'unit:s' => { name => 'unit', default => 'd' }
|
||||
});
|
||||
|
||||
return $self;
|
||||
}
|
||||
|
||||
sub check_options {
|
||||
my ($self, %options) = @_;
|
||||
$self->SUPER::check_options(%options);
|
||||
|
||||
if ($self->{option_results}->{unit} eq '' || !defined($unitdiv->{$self->{option_results}->{unit}})) {
|
||||
$self->{option_results}->{unit} = 'd';
|
||||
}
|
||||
}
|
||||
|
||||
sub manage_selection {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
my $response = $options{custom}->execute(
|
||||
params => $self->{option_results},
|
||||
command => 'licenses'
|
||||
);
|
||||
|
||||
$self->{global} = { total => 0 };
|
||||
$self->{licenses} = {};
|
||||
foreach my $name (keys %{$response->{data}}) {
|
||||
next if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' &&
|
||||
$name !~ /$self->{option_results}->{filter_name}/);
|
||||
next if (defined($self->{option_results}->{exclude_name}) && $self->{option_results}->{exclude_name} ne '' &&
|
||||
$name =~ /$self->{option_results}->{exclude_name}/);
|
||||
next if (defined($self->{option_results}->{filter_edition}) && $self->{option_results}->{filter_edition} ne '' &&
|
||||
$response->{data}->{$name}->{edition} !~ /$self->{option_results}->{filter_edition}/);
|
||||
next if (defined($self->{option_results}->{exclude_edition}) && $self->{option_results}->{exclude_edition} ne '' &&
|
||||
$response->{data}->{$name}->{edition} =~ /$self->{option_results}->{exclude_edition}/);
|
||||
next if (!defined($response->{data}->{$name}->{used}) && !defined($response->{data}->{$name}->{expiration_minutes}));
|
||||
|
||||
$self->{licenses}->{$name} = {
|
||||
name => $name,
|
||||
edition => $response->{data}->{$name}->{edition},
|
||||
total => $response->{data}->{$name}->{total},
|
||||
used => $response->{data}->{$name}->{used}
|
||||
};
|
||||
if (defined($response->{data}->{$name}->{expiration_minutes})) {
|
||||
$self->{licenses}->{$name}->{expires_seconds} = $response->{data}->{$name}->{expiration_minutes} * 60;
|
||||
$self->{licenses}->{$name}->{expires_human} = centreon::plugins::misc::change_seconds(
|
||||
value => $self->{licenses}->{$name}->{expires_seconds}
|
||||
);
|
||||
}
|
||||
$self->{global}->{total}++;
|
||||
}
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
__END__
|
||||
|
||||
=head1 MODE
|
||||
|
||||
Check licenses.
|
||||
|
||||
=over 8
|
||||
|
||||
=item B<--filter-name>
|
||||
|
||||
Filter licenses by name (can be a regexp).
|
||||
|
||||
=item B<--exclude-name>
|
||||
|
||||
Exclude licenses by name (can be a regexp).
|
||||
|
||||
=item B<--filter-edition>
|
||||
|
||||
Filter licenses by edition name (can be a regexp).
|
||||
|
||||
=item B<--exclude-edition>
|
||||
|
||||
Exclude licenses by edition name (can be a regexp).
|
||||
|
||||
=item B<--unit>
|
||||
|
||||
Select the unit for expires threshold. May be 's' for seconds, 'm' for minutes,
|
||||
'h' for hours, 'd' for days, 'w' for weeks. Default is days.
|
||||
|
||||
=item B<--warning-*> B<--critical-*>
|
||||
|
||||
Thresholds.
|
||||
Can be: 'total-licenses', 'usage', 'usage-free', 'usage-prct', 'expires'.
|
||||
|
||||
=back
|
||||
|
||||
=cut
|
|
@ -58,7 +58,7 @@ sub custom_traffic_output {
|
|||
|
||||
my ($value, $unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{traffic}, network => 1);
|
||||
return sprintf(
|
||||
"traffic %s : %s/s (%.2f %%)",
|
||||
"traffic %s: %s/s (%.2f %%)",
|
||||
$self->{result_values}->{label_ref}, $value . $unit, $self->{result_values}->{traffic_prct}
|
||||
);
|
||||
}
|
||||
|
@ -79,7 +79,7 @@ sub custom_dropped_output {
|
|||
my ($self, %options) = @_;
|
||||
|
||||
return sprintf(
|
||||
'packets %s dropped : %.2f %% (%d/%d packets)',
|
||||
'packets %s dropped: %.2f %% (%d/%d packets)',
|
||||
$self->{result_values}->{label_ref},
|
||||
$self->{result_values}->{dropped_prct},
|
||||
$self->{result_values}->{dropped}, $self->{result_values}->{packets}
|
||||
|
@ -131,7 +131,7 @@ sub set_counters {
|
|||
$self->{maps_counters}->{global_host} = [
|
||||
{ label => 'host-traffic-in', nlabel => 'host.traffic.in.bitsperseconds', set => {
|
||||
key_values => [ { name => 'traffic_in' } ],
|
||||
output_template => 'host traffic in : %s %s/s',
|
||||
output_template => 'host traffic in: %s %s/s',
|
||||
output_change_bytes => 2,
|
||||
perfdatas => [
|
||||
{ label => 'host_traffic_in', template => '%s',
|
||||
|
@ -141,7 +141,7 @@ sub set_counters {
|
|||
},
|
||||
{ label => 'host-traffic-out', nlabel => 'host.traffic.out.bitsperseconds', set => {
|
||||
key_values => [ { name => 'traffic_out' } ],
|
||||
output_template => 'host traffic out : %s %s/s',
|
||||
output_template => 'host traffic out: %s %s/s',
|
||||
output_change_bytes => 2,
|
||||
perfdatas => [
|
||||
{ label => 'host_traffic_out', template => '%s',
|
||||
|
@ -154,17 +154,17 @@ sub set_counters {
|
|||
$self->{maps_counters}->{vswitch} = [
|
||||
{ label => 'vswitch-traffic-in', nlabel => 'host.vswitch.traffic.in.bitsperseconds', set => {
|
||||
key_values => [ { name => 'traffic_in' } ],
|
||||
output_template => 'traffic in : %s %s/s',
|
||||
output_template => 'traffic in: %s %s/s',
|
||||
output_change_bytes => 2,
|
||||
perfdatas => [
|
||||
{ label => 'vswitch_traffic_in', template => '%s',
|
||||
unit => 'b/s', min => 0, label_extra_instance => 1 },
|
||||
],
|
||||
unit => 'b/s', min => 0, label_extra_instance => 1 }
|
||||
]
|
||||
}
|
||||
},
|
||||
{ label => 'vswitch-traffic-out', nlabel => 'host.vswitch.traffic.out.bitsperseconds', set => {
|
||||
key_values => [ { name => 'traffic_out' } ],
|
||||
output_template => 'traffic out : %s %s/s',
|
||||
output_template => 'traffic out: %s %s/s',
|
||||
output_change_bytes => 2,
|
||||
perfdatas => [
|
||||
{ label => 'vswitch_traffic_out', template => '%s',
|
||||
|
@ -262,12 +262,13 @@ sub new {
|
|||
bless $self, $class;
|
||||
|
||||
$options{options}->add_options(arguments => {
|
||||
'esx-hostname:s' => { name => 'esx_hostname' },
|
||||
'nic-name:s' => { name => 'nic_name' },
|
||||
'filter' => { name => 'filter' },
|
||||
'scope-datacenter:s' => { name => 'scope_datacenter' },
|
||||
'scope-cluster:s' => { name => 'scope_cluster' },
|
||||
'no-proxyswitch' => { name => 'no_proxyswitch' }
|
||||
'esx-hostname:s' => { name => 'esx_hostname' },
|
||||
'nic-name:s' => { name => 'nic_name' },
|
||||
'filter' => { name => 'filter' },
|
||||
'scope-datacenter:s' => { name => 'scope_datacenter' },
|
||||
'scope-cluster:s' => { name => 'scope_cluster' },
|
||||
'no-proxyswitch' => { name => 'no_proxyswitch' },
|
||||
'filter-vswitch-name:s' => { name => 'filter_vswitch_name' }
|
||||
});
|
||||
|
||||
return $self;
|
||||
|
@ -284,21 +285,36 @@ sub manage_selection {
|
|||
|
||||
foreach my $host_id (keys %{$response->{data}}) {
|
||||
my $host_name = $response->{data}->{$host_id}->{name};
|
||||
$self->{host}->{$host_name} = { display => $host_name,
|
||||
$self->{host}->{$host_name} = {
|
||||
display => $host_name,
|
||||
global => {
|
||||
state => $response->{data}->{$host_id}->{state},
|
||||
state => $response->{data}->{$host_id}->{state}
|
||||
},
|
||||
global_host => {
|
||||
traffic_in => 0,
|
||||
traffic_out => 0
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
foreach my $pnic_name (sort keys %{$response->{data}->{$host_id}->{pnic}}) {
|
||||
$self->{host}->{$host_name}->{pnic} = {} if (!defined($self->{host}->{$host_name}->{pnic}));
|
||||
|
||||
next if (defined($self->{option_results}->{nic_name}) && $self->{option_results}->{nic_name} ne '' &&
|
||||
$pnic_name !~ /$self->{option_results}->{nic_name}/);
|
||||
|
||||
|
||||
my $filtered = 1;
|
||||
if (defined($self->{option_results}->{filter_vswitch_name}) && $self->{option_results}->{filter_vswitch_name} ne '') {
|
||||
$filtered = 0;
|
||||
foreach my $vswitch_name (keys %{$response->{data}->{$host_id}->{vswitch}}) {
|
||||
next if (!defined($response->{data}->{$host_id}->{vswitch}->{$vswitch_name}->{pnic}));
|
||||
next if ($vswitch_name !~ /$self->{option_results}->{filter_vswitch_name}/);
|
||||
foreach (@{$response->{data}->{$host_id}->{vswitch}->{$vswitch_name}->{pnic}}) {
|
||||
$filtered = 1 if ($_ eq $response->{data}->{$host_id}->{pnic}->{$pnic_name}->{key});
|
||||
}
|
||||
}
|
||||
}
|
||||
next if ($filtered == 0);
|
||||
|
||||
$self->{host}->{$host_name}->{pnic}->{$pnic_name} = {
|
||||
display => $pnic_name,
|
||||
status => $response->{data}->{$host_id}->{pnic}->{$pnic_name}->{status} ,
|
||||
|
@ -310,9 +326,9 @@ sub manage_selection {
|
|||
dropped_in => $response->{data}->{$host_id}->{pnic}->{$pnic_name}->{'net.droppedRx.summation'},
|
||||
dropped_out => $response->{data}->{$host_id}->{pnic}->{$pnic_name}->{'net.droppedTx.summation'}
|
||||
};
|
||||
|
||||
|
||||
next if (!defined($response->{data}->{$host_id}->{pnic}->{$pnic_name}->{speed}));
|
||||
|
||||
|
||||
foreach my $vswitch_name (keys %{$response->{data}->{$host_id}->{vswitch}}) {
|
||||
next if (!defined($response->{data}->{$host_id}->{vswitch}->{$vswitch_name}->{pnic}));
|
||||
foreach (@{$response->{data}->{$host_id}->{vswitch}->{$vswitch_name}->{pnic}}) {
|
||||
|
@ -326,7 +342,7 @@ sub manage_selection {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$self->{host}->{$host_name}->{global_host}->{traffic_in} += $response->{data}->{$host_id}->{pnic}->{$pnic_name}->{'net.received.average'}
|
||||
if (defined($response->{data}->{$host_id}->{pnic}->{$pnic_name}->{'net.received.average'}));
|
||||
$self->{host}->{$host_name}->{global_host}->{traffic_out} += $response->{data}->{$host_id}->{pnic}->{$pnic_name}->{'net.transmitted.average'}
|
||||
|
@ -367,6 +383,11 @@ Search in following cluster(s) (can be a regexp).
|
|||
ESX nic to check.
|
||||
If not set, we check all nics.
|
||||
|
||||
=item B<--filter-vswitch-name>
|
||||
|
||||
Filter vswitch by name.
|
||||
It monitors only ESX nic that belongs to the filtered vswitches.
|
||||
|
||||
=item B<--unknown-status>
|
||||
|
||||
Set warning threshold for status (Default: '%{status} !~ /^connected$/i').
|
||||
|
|
|
@ -43,10 +43,11 @@ sub new {
|
|||
'display-description' => { name => 'display_description' },
|
||||
'check-consolidation' => { name => 'check_consolidation' },
|
||||
'nopoweredon-skip' => { name => 'nopoweredon_skip' },
|
||||
'empty-continue' => { name => 'empty_continue' },
|
||||
'warning:s' => { name => 'warning' },
|
||||
'critical:s' => { name => 'critical' },
|
||||
'disconnect-status:s' => { name => 'disconnect_status', default => 'unknown' },
|
||||
'unit:s' => { name => 'unit', default => 's' },
|
||||
'unit:s' => { name => 'unit', default => 's' }
|
||||
});
|
||||
|
||||
return $self;
|
||||
|
@ -80,9 +81,11 @@ sub check_options {
|
|||
sub run {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
my $response = $options{custom}->execute(params => $self->{option_results},
|
||||
command => 'snapshotvm');
|
||||
|
||||
my $response = $options{custom}->execute(
|
||||
params => $self->{option_results},
|
||||
command => 'snapshotvm'
|
||||
);
|
||||
|
||||
my $multiple = 0;
|
||||
my %vm_consolidate = ();
|
||||
my %vm_errors = (warning => {}, critical => {});
|
||||
|
@ -90,28 +93,34 @@ sub run {
|
|||
$multiple = 1;
|
||||
}
|
||||
if ($multiple == 1) {
|
||||
$self->{output}->output_add(severity => 'OK',
|
||||
short_msg => sprintf("All snapshots are ok"));
|
||||
$self->{output}->output_add(
|
||||
severity => 'OK',
|
||||
short_msg => sprintf("All snapshots are ok")
|
||||
);
|
||||
} else {
|
||||
$self->{output}->output_add(severity => 'OK',
|
||||
short_msg => sprintf("Snapshot(s) OK"));
|
||||
$self->{output}->output_add(
|
||||
severity => 'OK',
|
||||
short_msg => sprintf("Snapshot(s) OK")
|
||||
);
|
||||
}
|
||||
foreach my $vm_id (sort keys %{$response->{data}}) {
|
||||
my $vm_name = $response->{data}->{$vm_id}->{name};
|
||||
|
||||
|
||||
if ($options{custom}->entity_is_connected(state => $response->{data}->{$vm_id}->{connection_state}) == 0) {
|
||||
my $output = "VM '" . $vm_name . "' not connected. Current Connection State: '$response->{data}->{$vm_id}->{connection_state}'.";
|
||||
if ($multiple == 0 ||
|
||||
!$self->{output}->is_status(value => $self->{option_results}->{disconnect_status}, compare => 'ok', litteral => 1)) {
|
||||
$self->{output}->output_add(severity => $self->{option_results}->{disconnect_status},
|
||||
short_msg => $output);
|
||||
$self->{output}->output_add(
|
||||
severity => $self->{option_results}->{disconnect_status},
|
||||
short_msg => $output
|
||||
);
|
||||
}
|
||||
next;
|
||||
}
|
||||
|
||||
next if (defined($self->{option_results}->{nopoweredon_skip}) &&
|
||||
$options{custom}->vm_is_running(power => $response->{data}->{$vm_id}->{power_state}) == 0);
|
||||
|
||||
|
||||
if (defined($self->{check_consolidation}) && defined($response->{data}->{$vm_id}->{consolidation_needed}) && $response->{data}->{$vm_id}->{consolidation_needed} == 1) {
|
||||
$vm_consolidate{$response->{data}->{$vm_id}->{name}} = 1;
|
||||
}
|
||||
|
@ -119,15 +128,17 @@ sub run {
|
|||
foreach (@{$response->{data}->{$vm_id}->{snapshosts}}) {
|
||||
my $create_time = Date::Parse::str2time($_->{create_time});
|
||||
if (!defined($create_time)) {
|
||||
$self->{output}->output_add(severity => 'UNKNOWN',
|
||||
short_msg => "Can't Parse date '" . $_->{create_time} . "' for vm '" . $vm_name . "'");
|
||||
$self->{output}->output_add(
|
||||
severity => 'UNKNOWN',
|
||||
short_msg => "Can't Parse date '" . $_->{create_time} . "' for vm '" . $vm_name . "'"
|
||||
);
|
||||
next;
|
||||
}
|
||||
|
||||
|
||||
my $diff_time = time() - $create_time;
|
||||
my $days = int($diff_time / 60 / 60 / 24);
|
||||
my $exit = $self->{perfdata}->threshold_check(value => ($diff_time / $unitdiv->{$self->{option_results}->{unit}}->[1]), threshold => [ { label => 'critical', exit_litteral => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]);
|
||||
|
||||
|
||||
my $prefix_msg = "'$vm_name'";
|
||||
if (defined($self->{display_description}) && defined($response->{data}->{$vm_id}->{'config.annotation'}) &&
|
||||
$response->{data}->{$vm_id}->{'config.annotation'} ne '') {
|
||||
|
@ -187,7 +198,7 @@ sub run {
|
|||
)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
$self->{output}->display();
|
||||
$self->{output}->exit();
|
||||
}
|
||||
|
@ -247,6 +258,10 @@ Status if VM disconnected (default: 'unknown').
|
|||
|
||||
Skip check if VM is not poweredOn.
|
||||
|
||||
=item B<--empty-continue>
|
||||
|
||||
Ask to the connector that an empty response is ok.
|
||||
|
||||
=item B<--unit>
|
||||
|
||||
Select the unit for performance data and thresholds. May be 's' for seconds, 'm' for minutes,
|
||||
|
|
|
@ -97,7 +97,7 @@ sub manage_selection {
|
|||
foreach my $cluster_id (keys %{$response->{data}}) {
|
||||
my $cluster_name = $response->{data}->{$cluster_id}->{name};
|
||||
$self->{cluster}->{$cluster_name} = {
|
||||
display => $cluster_name,
|
||||
display => $cluster_name,
|
||||
overall_status => $response->{data}->{$cluster_id}->{overall_status},
|
||||
vsan_status => defined($response->{data}->{$cluster_id}->{vsan_cluster_status}) ? $response->{data}->{$cluster_id}->{vsan_cluster_status} : '',
|
||||
ha_enabled => defined($response->{data}->{$cluster_id}->{ha_enabled}) ? $response->{data}->{$cluster_id}->{ha_enabled} : '',
|
||||
|
|
|
@ -0,0 +1,414 @@
|
|||
#
|
||||
# Copyright 2021 Centreon (http://www.centreon.com/)
|
||||
#
|
||||
# Centreon is a full-fledged industry-strength solution that meets
|
||||
# the needs in IT infrastructure and application monitoring for
|
||||
# service performance.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
package apps::vmware::connector::mode::storagehost;
|
||||
|
||||
use base qw(centreon::plugins::templates::counter);
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use centreon::plugins::templates::catalog_functions qw(catalog_status_threshold_ng);
|
||||
|
||||
sub custom_status_output {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
return 'status ' . $self->{result_values}->{status} . ', maintenance mode is ' . $self->{result_values}->{maintenance};
|
||||
}
|
||||
|
||||
sub custom_status_calc {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
$self->{result_values}->{status} = $options{new_datas}->{$self->{instance} . '_state'};
|
||||
$self->{result_values}->{maintenance} = $options{new_datas}->{$self->{instance} . '_maintenance'};
|
||||
return 0;
|
||||
}
|
||||
|
||||
sub custom_adapter_output {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
return sprintf(
|
||||
'status: %s',
|
||||
$self->{result_values}->{status}
|
||||
);
|
||||
}
|
||||
|
||||
sub prefix_host_output {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
return "Host '" . $options{instance} . "' : ";
|
||||
}
|
||||
|
||||
sub host_long_output {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
return "checking host '" . $options{instance} . "'";
|
||||
}
|
||||
|
||||
sub prefix_adapters_output {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
return 'adapters ';
|
||||
}
|
||||
|
||||
sub prefix_adapter_output {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
return "adapter '" . $options{instance_value}->{name} . "' ";
|
||||
}
|
||||
|
||||
sub prefix_luns_output {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
return 'luns ';
|
||||
}
|
||||
|
||||
sub prefix_lun_output {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
return "lun '" . $options{instance_value}->{name} . "' ";
|
||||
}
|
||||
|
||||
sub prefix_paths_output {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
return 'paths ';
|
||||
}
|
||||
|
||||
sub prefix_path_output {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
return "path '" . $options{instance_value}->{name} . "' ";
|
||||
}
|
||||
|
||||
sub set_counters {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
$self->{maps_counters_type} = [
|
||||
{ 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', type => 0, skipped_code => { -10 => 1 } },
|
||||
{ name => 'adapters_global', type => 0, cb_prefix_output => 'prefix_adapters_output', skipped_code => { -10 => 1 } },
|
||||
{ name => 'luns_global', type => 0, cb_prefix_output => 'prefix_luns_output', skipped_code => { -10 => 1 } },
|
||||
{ name => 'paths_global', type => 0, cb_prefix_output => 'prefix_paths_output', skipped_code => { -10 => 1 } },
|
||||
{ name => 'adapters', type => 1, display_long => 1, cb_prefix_output => 'prefix_adapter_output', message_multiple => 'All adapters are ok', skipped_code => { -10 => 1 } },
|
||||
{ name => 'luns', type => 1, display_long => 1, cb_prefix_output => 'prefix_lun_output', message_multiple => 'All luns are ok', skipped_code => { -10 => 1 } },
|
||||
{ name => 'paths', type => 1, display_long => 1, cb_prefix_output => 'prefix_path_output', message_multiple => 'All paths are ok', skipped_code => { -10 => 1 } }
|
||||
]
|
||||
}
|
||||
];
|
||||
|
||||
$self->{maps_counters}->{global} = [
|
||||
{
|
||||
label => 'status', type => 2, unknown_default => '%{status} !~ /^connected$/i && %{maintenance} =~ /false/i',
|
||||
set => {
|
||||
key_values => [ { name => 'state' }, { name => 'maintenance' } ],
|
||||
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_ng
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
$self->{maps_counters}->{adapters_global} = [];
|
||||
foreach ('total', 'online', 'offline', 'fault', 'unknown') {
|
||||
push @{$self->{maps_counters}->{adapters_global}}, {
|
||||
label => 'adapters-' . $_, nlabel => 'host.adapters.' . $_ . '.count', set => {
|
||||
key_values => [ { name => $_ } ],
|
||||
output_template => $_ . ': %s',
|
||||
perfdatas => [
|
||||
{ template => '%s', min => 0, label_extra_instance => 1 }
|
||||
]
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
$self->{maps_counters}->{luns_global} = [];
|
||||
foreach ('total', 'ok', 'error', 'off', 'unknown', 'quiesced', 'degraded') {
|
||||
push @{$self->{maps_counters}->{luns_global}}, {
|
||||
label => 'luns-' . $_, nlabel => 'host.luns.' . $_ . '.count', set => {
|
||||
key_values => [ { name => $_ } ],
|
||||
output_template => $_ . ': %s',
|
||||
perfdatas => [
|
||||
{ template => '%s', min => 0, label_extra_instance => 1 }
|
||||
]
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
$self->{maps_counters}->{paths_global} = [];
|
||||
foreach ('total', 'active', 'disabled', 'standby', 'dead', 'unknown') {
|
||||
push @{$self->{maps_counters}->{paths_global}}, {
|
||||
label => 'paths-' . $_, nlabel => 'host.paths.' . $_ . '.count', set => {
|
||||
key_values => [ { name => $_ } ],
|
||||
output_template => $_ . ': %s',
|
||||
perfdatas => [
|
||||
{ template => '%s', min => 0, label_extra_instance => 1 }
|
||||
]
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
$self->{maps_counters}->{adapters} = [
|
||||
{
|
||||
label => 'adapter-status', type => 2, critical_default => '%{status} =~ /fault/',
|
||||
set => {
|
||||
key_values => [ { name => 'name' }, { name => 'status' }, { name => 'host' } ],
|
||||
closure_custom_output => $self->can('custom_adapter_output'),
|
||||
closure_custom_perfdata => sub { return 0; },
|
||||
closure_custom_threshold_check => \&catalog_status_threshold_ng
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
$self->{maps_counters}->{luns} = [
|
||||
{
|
||||
label => 'lun-status',
|
||||
type => 2,
|
||||
warning_default => '%{status} =~ /degraded|quiesced/',
|
||||
critical_default => '%{status} =~ /lostcommunication|error/',
|
||||
set => {
|
||||
key_values => [ { name => 'name' }, { name => 'status' }, { name => 'host' } ],
|
||||
closure_custom_output => $self->can('custom_adapter_output'),
|
||||
closure_custom_perfdata => sub { return 0; },
|
||||
closure_custom_threshold_check => \&catalog_status_threshold_ng
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
$self->{maps_counters}->{paths} = [
|
||||
{
|
||||
label => 'path-status',
|
||||
type => 2,
|
||||
critical_default => '%{status} =~ /dead/',
|
||||
set => {
|
||||
key_values => [ { name => 'name' }, { name => 'status' }, { name => 'host' } ],
|
||||
closure_custom_output => $self->can('custom_adapter_output'),
|
||||
closure_custom_perfdata => sub { return 0; },
|
||||
closure_custom_threshold_check => \&catalog_status_threshold_ng
|
||||
}
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
sub new {
|
||||
my ($class, %options) = @_;
|
||||
my $self = $class->SUPER::new(package => __PACKAGE__, %options, force_new_perfdata => 1);
|
||||
bless $self, $class;
|
||||
|
||||
$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' },
|
||||
'filter-adapter-name:s' => { name => 'filter_adapter_name' },
|
||||
'filter-lun-name:s' => { name => 'filter_lun_name' },
|
||||
'filter-path-name:s' => { name => 'filter_path_name' }
|
||||
});
|
||||
|
||||
return $self;
|
||||
}
|
||||
|
||||
sub manage_selection {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
$self->{host} = {};
|
||||
my $response = $options{custom}->execute(
|
||||
params => $self->{option_results},
|
||||
command => 'storagehost'
|
||||
);
|
||||
|
||||
foreach my $host_id (keys %{$response->{data}}) {
|
||||
my $host_name = $response->{data}->{$host_id}->{name};
|
||||
$self->{host}->{$host_name} = {
|
||||
global => {
|
||||
state => $response->{data}->{$host_id}->{state},
|
||||
maintenance => $response->{data}->{$host_id}->{inMaintenanceMode}
|
||||
}
|
||||
};
|
||||
|
||||
if (defined($response->{data}->{$host_id}->{adapters})) {
|
||||
$self->{host}->{$host_name}->{adapters} = {};
|
||||
$self->{host}->{$host_name}->{adapters_global} = {
|
||||
online => 0, offline => 0, fault => 0, unknown => 0, total => 0
|
||||
};
|
||||
foreach (@{$response->{data}->{$host_id}->{adapters}}) {
|
||||
next if (defined($self->{option_results}->{filter_adapter_name}) && $self->{option_results}->{filter_adapter_name} ne '' &&
|
||||
$_->{name} !~ /$self->{option_results}->{filter_adapter_name}/);
|
||||
|
||||
$self->{host}->{$host_name}->{adapters_global}->{total}++;
|
||||
if (defined($self->{host}->{$host_name}->{adapters_global}->{ $_->{status} })) {
|
||||
$self->{host}->{$host_name}->{adapters_global}->{ $_->{status} }++;
|
||||
} else {
|
||||
$self->{host}->{$host_name}->{adapters_global}->{unknown}++;
|
||||
}
|
||||
$self->{host}->{$host_name}->{adapters}->{ $_->{name} } = {
|
||||
name => $_->{name},
|
||||
host => $host_name,
|
||||
status => $_->{status}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
if (defined($response->{data}->{$host_id}->{luns})) {
|
||||
$self->{host}->{$host_name}->{luns} = {};
|
||||
$self->{host}->{$host_name}->{luns_global} = {
|
||||
ok => 0, error => 0, off => 0, unknown => 0, quiesced => 0, degraded => 0, total => 0
|
||||
};
|
||||
foreach (@{$response->{data}->{$host_id}->{luns}}) {
|
||||
next if (defined($self->{option_results}->{filter_lun_name}) && $self->{option_results}->{filter_lun_name} ne '' &&
|
||||
$_->{name} !~ /$self->{option_results}->{filter_lun_name}/);
|
||||
|
||||
$self->{host}->{$host_name}->{luns_global}->{total}++;
|
||||
foreach my $state (@{$_->{operational_states}}) {
|
||||
if (defined($self->{host}->{$host_name}->{luns_global}->{$state})) {
|
||||
$self->{host}->{$host_name}->{luns_global}->{$state}++;
|
||||
} else {
|
||||
$self->{host}->{$host_name}->{luns_global}->{unknown}++;
|
||||
}
|
||||
}
|
||||
|
||||
$self->{host}->{$host_name}->{luns}->{ $_->{name} } = {
|
||||
name => $_->{name},
|
||||
host => $host_name,
|
||||
status => join(',', @{$_->{operational_states}})
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
if (defined($response->{data}->{$host_id}->{paths})) {
|
||||
$self->{host}->{$host_name}->{paths} = {};
|
||||
$self->{host}->{$host_name}->{paths_global} = {
|
||||
active => 0, disabled => 0, standby => 0, dead => 0, unknown => 0
|
||||
};
|
||||
foreach (@{$response->{data}->{$host_id}->{paths}}) {
|
||||
next if (defined($self->{option_results}->{filter_path_name}) && $self->{option_results}->{filter_path_name} ne '' &&
|
||||
$_->{name} !~ /$self->{option_results}->{filter_path_name}/);
|
||||
|
||||
$self->{host}->{$host_name}->{paths_global}->{total}++;
|
||||
if (defined($self->{host}->{$host_name}->{paths_global}->{ $_->{state} })) {
|
||||
$self->{host}->{$host_name}->{paths_global}->{ $_->{state} }++;
|
||||
} else {
|
||||
$self->{host}->{$host_name}->{paths_global}->{unknown}++;
|
||||
}
|
||||
|
||||
$self->{host}->{$host_name}->{paths}->{ $_->{name} } = {
|
||||
name => $_->{name},
|
||||
host => $host_name,
|
||||
status => $_->{state}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
__END__
|
||||
|
||||
=head1 MODE
|
||||
|
||||
Check ESX storage infos.
|
||||
|
||||
=over 8
|
||||
|
||||
=item B<--esx-hostname>
|
||||
|
||||
ESX hostname to check.
|
||||
If not set, we check all ESX.
|
||||
|
||||
=item B<--filter>
|
||||
|
||||
ESX hostname is a regexp.
|
||||
|
||||
=item B<--scope-datacenter>
|
||||
|
||||
Search in following datacenter(s) (can be a regexp).
|
||||
|
||||
=item B<--scope-cluster>
|
||||
|
||||
Search in following cluster(s) (can be a regexp).
|
||||
|
||||
=item B<--filter-adapter-name>
|
||||
|
||||
Filter adapters by name (can be a regexp).
|
||||
|
||||
=item B<--filter-lun-name>
|
||||
|
||||
Filter luns by name (can be a regexp).
|
||||
|
||||
=item B<--filter-path-name>
|
||||
|
||||
Filter paths by name (can be a regexp).
|
||||
|
||||
=item B<--unknown-status>
|
||||
|
||||
Set warning threshold for status (Default: '%{status} !~ /^connected$/i && %{maintenance} =~ /false/i').
|
||||
Can used special variables like: %{status}, %{maintenance}
|
||||
|
||||
=item B<--warning-status>
|
||||
|
||||
Set warning threshold for status.
|
||||
Can used special variables like: %{status}, %{maintenance}
|
||||
|
||||
=item B<--critical-status>
|
||||
|
||||
Set critical threshold for status.
|
||||
Can used special variables like: %{status}, %{maintenance}
|
||||
|
||||
=item B<--warning-adapter-status>
|
||||
|
||||
Set warning threshold for adapter status.
|
||||
Can used special variables like: %{name}, %{host}, %{status}
|
||||
|
||||
=item B<--critical-adapter-status>
|
||||
|
||||
Set critical threshold for adapter status (Default: '%{status} =~ /fault/').
|
||||
Can used special variables like: %{name}, %{host}, %{status}
|
||||
|
||||
=item B<--warning-lun-status>
|
||||
|
||||
Set warning threshold for lun status (Default: '%{status} =~ /degraded|quiesced/').
|
||||
Can used special variables like: %{name}, %{host}, %{status}
|
||||
|
||||
=item B<--critical-lun-status>
|
||||
|
||||
Set critical threshold for lun status (Default: '%{status} =~ /lostcommunication|error/').
|
||||
Can used special variables like: %{name}, %{host}, %{status}
|
||||
|
||||
=item B<--warning-path-status>
|
||||
|
||||
Set warning threshold for path status.
|
||||
Can used special variables like: %{name}, %{host}, %{status}
|
||||
|
||||
=item B<--critical-path-status>
|
||||
|
||||
Set critical threshold for path status (Default: '%{status} =~ /dead/').
|
||||
Can used special variables like: %{name}, %{host}, %{status}
|
||||
|
||||
=item B<--warning-*> B<--critical-*>
|
||||
|
||||
Thresholds.
|
||||
Can be: 'adapters-total', 'adapters-online', 'adapters-offline', 'adapters-fault', 'adapters-unknown',
|
||||
|
||||
|
||||
=back
|
||||
|
||||
=cut
|
|
@ -31,20 +31,21 @@ sub new {
|
|||
bless $self, $class;
|
||||
|
||||
$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' },
|
||||
"filter-os:s" => { name => 'filter_os' },
|
||||
"filter-uuid:s" => { name => 'filter_uuid' },
|
||||
"display-description" => { name => 'display_description' },
|
||||
"disconnect-status:s" => { name => 'disconnect_status', default => 'unknown' },
|
||||
"tools-notinstalled-status:s" => { name => 'tools_notinstalled_status', default => 'critical' },
|
||||
"tools-notrunning-status:s" => { name => 'tools_notrunning_status', default => 'critical' },
|
||||
"tools-notup2date-status:s" => { name => 'tools_notupd2date_status', default => 'warning' },
|
||||
"nopoweredon-skip" => { name => 'nopoweredon_skip' },
|
||||
'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' },
|
||||
'filter-os:s' => { name => 'filter_os' },
|
||||
'filter-uuid:s' => { name => 'filter_uuid' },
|
||||
'display-description' => { name => 'display_description' },
|
||||
'disconnect-status:s' => { name => 'disconnect_status', default => 'unknown' },
|
||||
'tools-notinstalled-status:s' => { name => 'tools_notinstalled_status', default => 'critical' },
|
||||
'tools-notrunning-status:s' => { name => 'tools_notrunning_status', default => 'critical' },
|
||||
'tools-notup2date-status:s' => { name => 'tools_notupd2date_status', default => 'warning' },
|
||||
'nopoweredon-skip' => { name => 'nopoweredon_skip' },
|
||||
'empty-continue' => { name => 'empty_continue' }
|
||||
});
|
||||
|
||||
return $self;
|
||||
|
@ -88,21 +89,27 @@ sub display_verbose {
|
|||
sub run {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
my $response = $options{custom}->execute(params => $self->{option_results},
|
||||
command => 'toolsvm');
|
||||
my $response = $options{custom}->execute(
|
||||
params => $self->{option_results},
|
||||
command => 'toolsvm'
|
||||
);
|
||||
|
||||
my $multiple = 0;
|
||||
if (scalar(keys %{$response->{data}}) > 1) {
|
||||
$multiple = 1;
|
||||
}
|
||||
if ($multiple == 1) {
|
||||
$self->{output}->output_add(severity => 'OK',
|
||||
short_msg => 'All VMTools are OK');
|
||||
$self->{output}->output_add(
|
||||
severity => 'OK',
|
||||
short_msg => 'All VMTools are OK'
|
||||
);
|
||||
} else {
|
||||
$self->{output}->output_add(severity => 'OK',
|
||||
short_msg => 'VMTools are OK');
|
||||
$self->{output}->output_add(
|
||||
severity => 'OK',
|
||||
short_msg => 'VMTools are OK'
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
my %not_installed = ();
|
||||
my %not_running = ();
|
||||
my %not_up2date = ();
|
||||
|
@ -113,14 +120,16 @@ sub run {
|
|||
my $output = "VM '" . $vm_name . "' not connected. Current Connection State: '$response->{data}->{$vm_id}->{connection_state}'.";
|
||||
if ($multiple == 0 ||
|
||||
!$self->{output}->is_status(value => $self->{option_results}->{disconnect_status}, compare => 'ok', litteral => 1)) {
|
||||
$self->{output}->output_add(severity => $self->{option_results}->{disconnect_status},
|
||||
short_msg => $output);
|
||||
$self->{output}->output_add(
|
||||
severity => $self->{option_results}->{disconnect_status},
|
||||
short_msg => $output
|
||||
);
|
||||
}
|
||||
next;
|
||||
}
|
||||
|
||||
next if (defined($self->{option_results}->{nopoweredon_skip}) &&
|
||||
$options{custom}->vm_is_running(power => $response->{data}->{$vm_id}->{power_state}) == 0);
|
||||
$options{custom}->vm_is_running(power => $response->{data}->{$vm_id}->{power_state}) == 0);
|
||||
|
||||
next if (!defined($response->{data}->{$vm_id}->{tools_status}));
|
||||
|
||||
|
@ -133,26 +142,32 @@ sub run {
|
|||
$not_up2date{$vm_name} = defined($response->{data}->{$vm_id}->{'config.annotation'}) ? $response->{data}->{$vm_id}->{'config.annotation'} : '';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (scalar(keys %not_up2date) > 0 &&
|
||||
!$self->{output}->is_status(value => $self->{option_results}->{tools_notupd2date_status}, compare => 'ok', litteral => 1)) {
|
||||
$self->{output}->output_add(severity => $self->{option_results}->{tools_notupd2date_status},
|
||||
short_msg => sprintf('%d VM with VMTools not up-to-date', scalar(keys %not_up2date)));
|
||||
$self->{output}->output_add(
|
||||
severity => $self->{option_results}->{tools_notupd2date_status},
|
||||
short_msg => sprintf('%d VM with VMTools not up-to-date', scalar(keys %not_up2date))
|
||||
);
|
||||
$self->display_verbose(label => 'vmtools not up-to-date:', vms => \%not_up2date, custom => $options{custom});
|
||||
}
|
||||
if (scalar(keys %not_running) > 0 &&
|
||||
!$self->{output}->is_status(value => $self->{option_results}->{tools_notrunning_status}, compare => 'ok', litteral => 1)) {
|
||||
$self->{output}->output_add(severity => $self->{option_results}->{tools_notrunning_status},
|
||||
short_msg => sprintf('%d VM with VMTools not running', scalar(keys %not_running)));
|
||||
$self->{output}->output_add(
|
||||
severity => $self->{option_results}->{tools_notrunning_status},
|
||||
short_msg => sprintf('%d VM with VMTools not running', scalar(keys %not_running))
|
||||
);
|
||||
$self->display_verbose(label => 'vmtools not running:', vms => \%not_running, custom => $options{custom});
|
||||
}
|
||||
if (scalar(keys %not_installed) > 0 &&
|
||||
!$self->{output}->is_status(value => $self->{option_results}->{tools_notinstalled_status}, compare => 'ok', litteral => 1)) {
|
||||
$self->{output}->output_add(severity => $self->{option_results}->{tools_notinstalled_status},
|
||||
short_msg => sprintf('%d VM with VMTools not installed', scalar(keys %not_installed)));
|
||||
$self->{output}->output_add(
|
||||
severity => $self->{option_results}->{tools_notinstalled_status},
|
||||
short_msg => sprintf('%d VM with VMTools not installed', scalar(keys %not_installed))
|
||||
);
|
||||
$self->display_verbose(label => 'vmtools not installed:', vms => \%not_installed, custom => $options{custom});
|
||||
}
|
||||
|
||||
|
||||
if ($multiple == 1) {
|
||||
my $total = scalar(keys %not_up2date) + scalar(keys %not_running) + scalar(keys %not_installed);
|
||||
$self->{output}->perfdata_add(
|
||||
|
@ -174,7 +189,7 @@ sub run {
|
|||
min => 0, max => $total
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
$self->{output}->display();
|
||||
$self->{output}->exit();
|
||||
}
|
||||
|
@ -226,6 +241,10 @@ Status if VM disconnected (default: 'unknown').
|
|||
|
||||
Skip check if VM is not poweredOn.
|
||||
|
||||
=item B<--empty-continue>
|
||||
|
||||
Ask to the connector that an empty response is ok.
|
||||
|
||||
=item B<--display-description>
|
||||
|
||||
Display virtual machine description.
|
||||
|
|
|
@ -33,8 +33,9 @@ sub new {
|
|||
$self->{modes} = {
|
||||
'alarm-datacenter' => 'apps::vmware::connector::mode::alarmdatacenter',
|
||||
'alarm-host' => 'apps::vmware::connector::mode::alarmhost',
|
||||
'countvm-host' => 'apps::vmware::connector::mode::countvmhost',
|
||||
'cpu-host' => 'apps::vmware::connector::mode::cpuhost',
|
||||
'countvm-host' => 'apps::vmware::connector::mode::countvmhost',
|
||||
'cpu-cluster' => 'apps::vmware::connector::mode::cpucluster',
|
||||
'cpu-host' => 'apps::vmware::connector::mode::cpuhost',
|
||||
'cpu-vm' => 'apps::vmware::connector::mode::cpuvm',
|
||||
'datastore-countvm' => 'apps::vmware::connector::mode::datastorecountvm',
|
||||
'datastore-host' => 'apps::vmware::connector::mode::datastorehost',
|
||||
|
@ -47,6 +48,7 @@ sub new {
|
|||
'discovery' => 'apps::vmware::connector::mode::discovery',
|
||||
'getmap' => 'apps::vmware::connector::mode::getmap',
|
||||
'health-host' => 'apps::vmware::connector::mode::healthhost',
|
||||
'licenses' => 'apps::vmware::connector::mode::licenses',
|
||||
'limit-vm' => 'apps::vmware::connector::mode::limitvm',
|
||||
'list-clusters' => 'apps::vmware::connector::mode::listclusters',
|
||||
'list-datacenters' => 'apps::vmware::connector::mode::listdatacenters',
|
||||
|
@ -63,6 +65,7 @@ sub new {
|
|||
'status-cluster' => 'apps::vmware::connector::mode::statuscluster',
|
||||
'status-host' => 'apps::vmware::connector::mode::statushost',
|
||||
'status-vm' => 'apps::vmware::connector::mode::statusvm',
|
||||
'storage-host' => 'apps::vmware::connector::mode::storagehost',
|
||||
'swap-host' => 'apps::vmware::connector::mode::swaphost',
|
||||
'swap-vm' => 'apps::vmware::connector::mode::swapvm',
|
||||
'thinprovisioning-vm' => 'apps::vmware::connector::mode::thinprovisioningvm',
|
||||
|
|
Loading…
Reference in New Issue