centreon-plugins/connectors/vmware/lib/common.pm

403 lines
13 KiB
Perl

package centreon::esxd::common;
use warnings;
use strict;
use Data::Dumper;
use VMware::VIRuntime;
use VMware::VILib;
my %ERRORS = ( "OK" => 0, "WARNING" => 1, "CRITICAL" => 2, "UNKNOWN" => 3, "PENDING" => 4);
my %MYERRORS = (0 => "OK", 1 => "WARNING", 3 => "CRITICAL", 7 => "UNKNOWN");
my %MYERRORS_MASK = ("CRITICAL" => 3, "WARNING" => 1, "UNKNOWN" => 7, "OK" => 0);
sub errors_mask {
my ($status, $state) = @_;
$status |= $MYERRORS_MASK{$state};
return $status;
}
sub get_status {
my ($state) = @_;
return $ERRORS{$MYERRORS{$state}};
}
sub response_client1 {
my ($obj_esxd, $rh, $current_fileno, $msg) = @_;
$rh->send($msg);
delete $obj_esxd->{sockets}->{$current_fileno};
$obj_esxd->{read_select}->remove($rh);
close $rh;
}
sub vmware_error {
my ($obj_esxd, $lerror) = @_;
$obj_esxd->{logger}->writeLogError("'" . $obj_esxd->{whoaim} . "' $lerror");
$lerror =~ s/\n/ /g;
if ($lerror =~ /NoPermissionFault/i) {
$obj_esxd->print_response("-2|Error: Not enough permissions\n");
} else {
$obj_esxd->print_response("-1|Error: " . $lerror . "\n");
}
return undef;
}
sub connect_vsphere {
my ($logger, $whoaim, $timeout_vsphere, $session1, $service_url, $username, $password) = @_;
$logger->writeLogInfo("'$whoaim' Vsphere connection in progress");
eval {
$SIG{ALRM} = sub { die('TIMEOUT'); };
alarm($timeout_vsphere);
$$session1 = Vim->new(service_url => $service_url);
$$session1->login(
user_name => $username,
password => $password);
alarm(0);
};
if($@) {
$logger->writeLogError("'$whoaim' No response from VirtualCenter server") if($@ =~ /TIMEOUT/);
$logger->writeLogError("'$whoaim' You need to upgrade HTTP::Message!") if($@ =~ /HTTP::Message/);
$logger->writeLogError("'$whoaim' Login to VirtualCenter server failed: $@");
return 1;
}
# eval {
# $session_id = Vim::get_session_id();
# };
# if($@) {
# writeLogFile("Can't get session_id: $@\n");
# return 1;
# }
return 0;
}
sub output_add($$$$) {
my ($output_str, $output_append, $delim, $str) = (shift, shift, shift, shift);
$$output_str .= $$output_append . $str;
$$output_append = $delim;
}
sub simplify_number {
my ($number, $cnt) = @_;
$cnt = 2 if (!defined($cnt));
return sprintf("%.${cnt}f", "$number");
}
sub convert_number {
my ($number) = shift(@_);
$number =~ s/\,/\./;
return $number;
}
sub get_views {
my $obj_esxd = shift;
my $results;
eval {
$results = $obj_esxd->{session1}->get_views(mo_ref_array => $_[0], properties => $_[1]);
};
if ($@) {
vmware_error($obj_esxd, $@);
return undef;
}
return $results;
}
sub get_view {
my $obj_esxd = shift;
my $results;
eval {
$results = $obj_esxd->{session1}->get_view(mo_ref => $_[0], properties => $_[1]);
};
if ($@) {
vmware_error($obj_esxd, $@);
return undef;
}
return $results;
}
sub search_in_datastore {
my $obj_esxd = shift;
my ($ds_browse, $ds_name, $query, $return) = @_;
my $result;
my $files = FileQueryFlags->new(fileSize => 1,
fileType => 1,
modification => 1,
fileOwner => 1
);
my $hostdb_search_spec = HostDatastoreBrowserSearchSpec->new(details => $files,
query => $query);
eval {
$result = $ds_browse->SearchDatastoreSubFolders(datastorePath=> $ds_name,
searchSpec=>$hostdb_search_spec);
};
if ($@) {
return (undef, $@) if (defined($return) && $return == 1);
vmware_error($obj_esxd, $@);
return undef;
}
return $result;
}
sub get_perf_metric_ids {
my $obj_esxd = shift;
my $perf_names = $_[0];
my $filtered_list = [];
foreach (@$perf_names) {
if (defined($obj_esxd->{perfcounter_cache}->{$_->{'label'}})) {
foreach my $instance (@{$_->{'instances'}}) {
my $metric = PerfMetricId->new(counterId => $obj_esxd->{perfcounter_cache}->{$_->{'label'}}{'key'},
instance => $instance);
push @$filtered_list, $metric;
}
} else {
$obj_esxd->{logger}->writeLogError("Metric '" . $_->{'label'} . "' unavailable.");
$obj_esxd->print_response("-3|Error: Counter doesn't exist. VMware version can be too old.\n");
return undef;
}
}
return $filtered_list;
}
sub generic_performance_values_historic {
my ($obj_esxd, $views, $perfs, $interval, $skip_undef_counter, $multiples) = @_;
my $counter = 0;
my %results;
eval {
my $perf_metric_ids = get_perf_metric_ids($obj_esxd, $perfs);
return undef if (!defined($perf_metric_ids));
my @perf_query_spec;
my $tstamp = time();
my (@t) = gmtime($tstamp - $interval);
my $startTime = sprintf("%04d-%02d-%02dT%02d:%02d:%02dZ",
(1900+$t[5]),(1+$t[4]),$t[3],$t[2],$t[1],$t[0]);
(@t) = gmtime($tstamp);
my $endTime = sprintf("%04d-%02d-%02dT%02d:%02d:%02dZ",
(1900+$t[5]),(1+$t[4]),$t[3],$t[2],$t[1],$t[0]);
foreach (@$views) {
if ($interval == 20) {
push @perf_query_spec, PerfQuerySpec->new(entity => $_,
metricId => $perf_metric_ids,
format => 'normal',
intervalId => 20,
startTime => $startTime,
endTime => $endTime,
maxSample => 1);
} else {
push @perf_query_spec, PerfQuerySpec->new(entity => $_,
metricId => $perf_metric_ids,
format => 'normal',
intervalId => $interval,
startTime => $startTime,
endTime => $endTime
);
#maxSample => 1);
}
}
my $perfdata = $obj_esxd->{perfmanager_view}->QueryPerf(querySpec => \@perf_query_spec);
if (!$$perfdata[0] || !defined($$perfdata[0]->value)) {
$obj_esxd->print_response("-3|Error: Cannot get value for counters. Maybe you have call a wrong instance.\n");
return undef;
}
foreach my $val (@$perfdata) {
foreach (@{$val->{value}}) {
if (defined($skip_undef_counter) && $skip_undef_counter == 1 && !defined($_->value)) {
$results{$_->id->counterId . ":" . (defined($_->id->instance) ? $_->id->instance : "")} = undef;
next;
} elsif (!defined($_->value)) {
$obj_esxd->print_response("-3|Error: Cannot get value for counters. Maybe there is time sync problem (check the esxd server and the target also).\n");
return undef;
}
if (defined($multiples) && $multiples == 1) {
$results{$val->{entity}->{value} . ":" . $_->id->counterId . ":" . (defined($_->id->instance) ? $_->id->instance : "")} = $_->value;
} else {
$results{$_->id->counterId . ":" . (defined($_->id->instance) ? $_->id->instance : "")} = $_->value;
}
}
}
};
if ($@) {
$obj_esxd->{logger}->writeLogError("'" . $obj_esxd->{whoaim} . "' $@");
return undef;
}
return \%results;
}
sub cache_perf_counters {
my $obj_esxd = shift;
eval {
$obj_esxd->{perfmanager_view} = $obj_esxd->{session1}->get_view(mo_ref => $obj_esxd->{session1}->get_service_content()->perfManager, properties => ['perfCounter', 'historicalInterval']);
foreach (@{$obj_esxd->{perfmanager_view}->perfCounter}) {
my $label = $_->groupInfo->key . "." . $_->nameInfo->key . "." . $_->rollupType->val;
$obj_esxd->{perfcounter_cache}->{$label} = {'key' => $_->key, 'unitkey' => $_->unitInfo->key};
$obj_esxd->{perfcounter_cache_reverse}->{$_->key} = $label;
}
my $historical_intervals = $obj_esxd->{perfmanager_view}->historicalInterval;
foreach (@$historical_intervals) {
if ($obj_esxd->{perfcounter_speriod} == -1 || $obj_esxd->{perfcounter_speriod} > $_->samplingPeriod) {
$obj_esxd->{perfcounter_speriod} = $_->samplingPeriod;
}
}
# Put refresh = 20 (for ESX check)
if ($obj_esxd->{perfcounter_speriod} == -1) {
$obj_esxd->{perfcounter_speriod} = 20;
}
};
if ($@) {
$obj_esxd->{logger}->writeLogError("'" . $obj_esxd->{whoaim} . "' $@");
return 1;
}
return 0;
}
sub get_entities_host {
my ($obj_esxd, $view_type, $filters, $properties) = @_;
my $entity_views;
eval {
$entity_views = $obj_esxd->{session1}->find_entity_views(view_type => $view_type, properties => $properties, filter => $filters);
};
if ($@) {
$obj_esxd->{logger}->writeLogError("'" . $obj_esxd->{whoaim} . "' $@");
eval {
$entity_views = $obj_esxd->{session1}->find_entity_views(view_type => $view_type, properties => $properties, filter => $filters);
};
if ($@) {
vmware_error($obj_esxd, $@);
return undef;
}
}
if (!@$entity_views) {
my $status = 0;
$status = errors_mask($status, 'UNKNOWN');
$obj_esxd->print_response(get_status($status) . "|Object $view_type does not exist.\n");
return undef;
}
#eval {
# $$entity_views[0]->update_view_data(properties => $properties);
#};
#if ($@) {
# writeLogFile("$@");
# my $lerror = $@;
# $lerror =~ s/\n/ /g;
# print "-1|Error: " . $lerror . "\n";
# return undef;
#}
return $entity_views;
}
sub performance_errors {
my ($obj_esxd, $values) = @_;
# Error counter not available or other from function
return 1 if (!defined($values) || scalar(keys(%$values)) <= 0);
return 0;
}
sub is_accessible {
my ($accessible) = @_;
if ($accessible !~ /^true|1$/) {
return 0;
}
return 1;
}
sub is_connected {
my ($connection_state) = @_;
if ($connection_state !~ /^connected$/i) {
return 0;
}
return 1;
}
sub is_running {
my ($power_state) = @_;
if ($power_state !~ /^poweredOn$/i) {
return 0;
}
return 1;
}
sub datastore_state {
my ($obj_esxd, $ds, $accessible) = @_;
if ($accessible !~ /^true|1$/) {
my $output = "Datastore '" . $ds . "' not accessible. Can be disconnected.";
my $status = errors_mask(0, $obj_esxd->{centreonesxd_config}->{datastore_state_error});
$obj_esxd->print_response(get_status($status) . "|$output\n");
return 0;
}
return 1;
}
sub vm_state {
my ($obj_esxd, $vm, $connection_state, $power_state, $nocheck_ps) = @_;
if ($connection_state !~ /^connected$/i) {
my $output = "VM '" . $vm . "' not connected. Current Connection State: '$connection_state'.";
my $status = errors_mask(0, $obj_esxd->{centreonesxd_config}->{vm_state_error});
$obj_esxd->print_response(get_status($status) . "|$output\n");
return 0;
}
if (!defined($nocheck_ps) && $power_state !~ /^poweredOn$/i) {
my $output = "VM '" . $vm . "' not running. Current Power State: '$power_state'.";
my $status = errors_mask(0, $obj_esxd->{centreonesxd_config}->{vm_state_error});
$obj_esxd->print_response(get_status($status) . "|$output\n");
return 0;
}
return 1;
}
sub host_state {
my ($obj_esxd, $host, $connection_state) = @_;
if ($connection_state !~ /^connected$/i) {
my $output = "Host '" . $host . "' not connected. Current Connection State: '$connection_state'.";
my $status = errors_mask(0, $obj_esxd->{centreonesxd_config}->{host_state_error});
$obj_esxd->print_response(get_status($status) . "|$output\n");
return 0;
}
return 1;
}
sub stats_info {
my ($obj_esxd, $rh, $current_fileno, $args) = @_;
my $output;
my $status = 0;
$$args[0] ='' if (!defined($$args[0]));
$$args[1] = '' if (!defined($$args[1]));
my $num_connection = scalar(keys(%{$obj_esxd->{sockets}}));
$output = "'$num_connection' total client connections | connection=$num_connection;$$args[0];$$args[1];0; requests=" . $obj_esxd->{counter};
if ($$args[1] ne '' and $num_connection >= $$args[1]) {
$status = errors_mask($status, 'CRITICAL');
} elsif ($$args[0] ne '' and $num_connection >= $$args[0]) {
$status = errors_mask($status, 'WARNING');
}
response_client1($obj_esxd, $rh, $current_fileno, get_status($status) . "|$output\n");
}
1;