Ref #5490 : in progress

git-svn-id: http://svn.merethis.net/centreon-esxd/trunk@57 a5eaa968-4c79-4d68-970d-af6011b5b055
This commit is contained in:
Quentin Garnier 2013-06-28 16:04:49 +00:00
parent cd59d4ae57
commit 83880bce85
6 changed files with 814 additions and 759 deletions

View File

@ -1,504 +1,37 @@
#!/usr/bin/perl -w
#!/usr/bin/perl
use warnings;
use centreon::script::centreonesxd;
BEGIN {
#$ENV{PERL_NET_HTTPS_SSL_SOCKET_CLASS} = "Net::SSL";
$ENV{PERL_LWP_SSL_VERIFY_HOSTNAME} = 0;
$ENV{ESX_SYSLOGD_LOAD} = 0;
eval 'require Unix::Syslog;';
if (!$@) {
$ENV{ESX_SYSLOGD_LOAD} = 1;
require Unix::Syslog;
Unix::Syslog->import(qw(:subs :macros));
}
}
centreon::script::centreonesxd->new()->run();
use strict;
use VMware::VIRuntime;
use VMware::VILib;
use IO::Socket;
use File::Basename;
use IO::Select;
use POSIX ":sys_wait_h";
use Data::Dumper;
__END__
our $module_date_parse_loaded = 0;
eval 'require DateTime::Format::ISO8601';
if (!$@) {
$module_date_parse_loaded = 1;
require DateTime::Format::ISO8601;
}
=head1 NAME
use vars qw($libpath $port %vsphere_server $TIMEOUT_VSPHERE $TIMEOUT $TIMEOUT_KILL $REFRESH_KEEPER_SESSION);
use vars qw($credstore_use $credstore_file);
use vars qw($LOG $log_mode $log_crit $log_facility);
use vars qw($openlog_option $syslog_err_priority $syslog_info_priority);
centreon_esxd - a daemon to handle VMWare checks.
use constant {
LOG_ESXD_ERROR => 1,
LOG_ESXD_INFO => 2
};
=head1 SYNOPSIS
require '/etc/centreon/centreon_esxd.pm';
require $libpath . '/esxd-common.pm';
require $libpath . '/command-cpuhost.pm';
require $libpath . '/command-cpuvm.pm';
require $libpath . '/command-countvmhost.pm';
require $libpath . '/command-datastoreio.pm';
require $libpath . '/command-datastoreshost.pm';
require $libpath . '/command-datastoresvm.pm';
require $libpath . '/command-datastoreusage.pm';
require $libpath . '/command-getmap.pm';
require $libpath . '/command-healthhost.pm';
require $libpath . '/command-listdatastore.pm';
require $libpath . '/command-listhost.pm';
require $libpath . '/command-listnichost.pm';
require $libpath . '/command-maintenancehost.pm';
require $libpath . '/command-memhost.pm';
require $libpath . '/command-memvm.pm';
require $libpath . '/command-nethost.pm';
require $libpath . '/command-snapshotvm.pm';
require $libpath . '/command-statushost.pm';
require $libpath . '/command-swaphost.pm';
require $libpath . '/command-swapvm.pm';
require $libpath . '/command-toolsvm.pm';
require $libpath . '/command-uptimehost.pm';
centreon_esxd [options]
our $VERSION = "1.3.1";
our $session_id;
our %sockets = ();
our %child_proc;
our %return_child;
our $vsphere_connected = 0;
our $last_time_vsphere;
our $keeper_session_time;
our $last_time_check;
our $perfmanager_view;
our %perfcounter_cache;
our %perfcounter_cache_reverse;
our $perfcounter_refreshrate = 20;
our $perfcounter_speriod = -1;
our $stop = 0;
our $counter_request_id = 0;
our $child_vpshere_pid;
our $read_select;
our $session1;
our $counter = 0;
our $global_id;
our $whoaim; # to know which vsphere to connect
our %filenos;
=head1 OPTIONS
our $openlog_option;
our $syslog_err_priority;
our $syslog_info_priority;
=over 8
if ($ENV{ESX_SYSLOGD_LOAD} == 1) {
require $libpath . '/esxd-syslog.pm';
}
=item B<--config-extra>
##### credstore check #####
if (defined($credstore_use) && defined($credstore_file) &&
$credstore_use == 1 && -e "$credstore_file") {
eval 'require VMware::VICredStore';
if ($@) {
writeLogFile(LOG_ESXD_ERROR, "Could not load module VMware::VICredStore\n");
exit(1);
}
require VMware::VICredStore;
Specify the path to the centreonesxd configuration file (default: /etc/centreon/centreon_esxd.pm).
if (VMware::VICredStore::init(filename => $credstore_file) == 0) {
writeLogFile(LOG_ESXD_ERROR, "Credstore init failed: $@\n");
exit(1);
}
=item B<--help>
###
# Get password
###
foreach (keys %vsphere_server) {
my $lpassword = VMware::VICredStore::get_password(server => $_, username => $vsphere_server{$_}->{'username'});
if (!defined($lpassword)) {
writeLogFile(LOG_ESXD_ERROR, "Can't get password for couple host='" . $_ . "', username='" . $vsphere_server{$_}->{'username'} . "' : $@\n");
exit(1);
}
$vsphere_server{$_}->{'password'} = $lpassword;
}
}
Print a brief help message and exits.
our %ERRORS = ( "OK" => 0, "WARNING" => 1, "CRITICAL" => 2, "UNKNOWN" => 3, "PENDING" => 4);
our %MYERRORS = (0 => "OK", 1 => "WARNING", 3 => "CRITICAL", 7 => "UNKNOWN");
our %MYERRORS_MASK = ("CRITICAL" => 3, "WARNING" => 1, "UNKNOWN" => 7, "OK" => 0);
our %checks_descr = (
"healthhost" => {'arg' => \&healthhost_check_args, 'compute' => \&healthhost_compute_args, 'exec' => \&healthhost_do},
"datastoreusage" => {'arg' => \&datastoreusage_check_args, 'compute' => \&datastoreusage_compute_args, 'exec' => \&datastoreusage_do},
"datastoreio" => {'arg' => \&datastoreio_check_args, 'compute' => \&datastoreio_compute_args, 'exec' => \&datastoreio_do},
"maintenancehost" => {'arg' => \&maintenancehost_check_args, 'compute' => \&maintenancehost_compute_args, 'exec' => \&maintenancehost_do},
"statushost" => {'arg' => \&statushost_check_args, 'compute' => \&statushost_compute_args, 'exec' => \&statushost_do},
"cpuhost" => {'arg' => \&cpuhost_check_args, 'compute' => \&cpuhost_compute_args, 'exec' => \&cpuhost_do},
"nethost" => {'arg' => \&nethost_check_args, 'compute' => \&nethost_compute_args, 'exec' => \&nethost_do},
"datastoreshost" => {'arg' => \&datastoreshost_check_args, 'compute' => \&datastoreshost_compute_args, 'exec' => \&datastoreshost_do},
"memhost" => {'arg' => \&memhost_check_args, 'compute' => \&memhost_compute_args, 'exec' => \&memhost_do},
"swaphost" => {'arg' => \&swaphost_check_args, 'compute' => \&swaphost_compute_args, 'exec' => \&swaphost_do},
"countvmhost" => {'arg' => \&countvmhost_check_args, 'compute' => \&countvmhost_compute_args, 'exec' => \&countvmhost_do},
"uptimehost" => {'arg' => \&uptimehost_check_args, 'compute' => \&uptimehost_compute_args, 'exec' => \&uptimehost_do},
"cpuvm" => {'arg' => \&cpuvm_check_args, 'compute' => \&cpuvm_compute_args, 'exec' => \&cpuvm_do},
"toolsvm" => {'arg' => \&toolsvm_check_args, 'compute' => \&toolsvm_compute_args, 'exec' => \&toolsvm_do},
"snapshotvm" => {'arg' => \&snapshotvm_check_args, 'compute' => \&snapshotvm_compute_args, 'exec' => \&snapshotvm_do},
"datastoresvm" => {'arg' => \&datastoresvm_check_args, 'compute' => \&datastoresvm_compute_args, 'exec' => \&datastoresvm_do},
"memvm" => {'arg' => \&memvm_check_args, 'compute' => \&memvm_compute_args, 'exec' => \&memvm_do},
"swapvm" => {'arg' => \&swapvm_check_args, 'compute' => \&swapvm_compute_args, 'exec' => \&swapvm_do},
"listhost" => {'arg' => \&listhost_check_args, 'compute' => \&listhost_compute_args, 'exec' => \&listhost_do},
"listdatastore" => {'arg' => \&listdatastore_check_args, 'compute' => \&listdatastore_compute_args, 'exec' => \&listdatastore_do},
"listnichost" => {'arg' => \&listnichost_check_args, 'compute' => \&listnichost_compute_args, 'exec' => \&listnichost_do},
"getmap" => {'arg' => \&getmap_check_args, 'compute' => \&getmap_compute_args, 'exec' => \&getmap_do}
);
=back
sub catch_zap_term {
writeLogFile(LOG_ESXD_INFO, "$$ Receiving order to stop...\n");
$stop = 1;
}
=head1 DESCRIPTION
sub REAPER {
my $child_pid;
B<centreon_esxd> will connect to ESX and/or VirtualCenter. Use the script 'centreon_esx_client.pl'
to do checks through the daemon.
while (($child_pid = waitpid(-1, &WNOHANG)) > 0) {
$return_child{$child_pid} = {'status' => 1, 'rtime' => time()};
}
$SIG{CHLD} = \&REAPER;
}
sub verify_child {
my $progress = 0;
my $handle_writer_pipe = ${$vsphere_server{$whoaim}->{'writer_one'}};
# Verify process
foreach (keys %child_proc) {
# Check ctime
if (time() - $child_proc{$_}->{'ctime'} > $TIMEOUT) {
my $handle = ${$child_proc{$_}->{'reading'}};
print $handle_writer_pipe "$_|-1|Timeout Process.\n";
kill('INT', $child_proc{$_}->{'pid'});
$read_select->remove($handle);
close $handle;
delete $child_proc{$_};
} else {
$progress++;
}
}
# Clean old hash CHILD (security)
foreach (keys %return_child) {
if (time() - $return_child{$_}->{'rtime'} > 600) {
writeLogFile(LOG_ESXD_INFO, "Clean Old return_child list = " . $_ . "\n");
delete $return_child{$_};
}
}
return $progress;
}
sub vsphere_handler {
my $timeout_process;
my $handle_reader_pipe = ${$vsphere_server{$whoaim}->{'reader_two'}};
my $fileno_reader = fileno($handle_reader_pipe);
my $handle_writer_pipe = ${$vsphere_server{$whoaim}->{'writer_one'}};
$read_select = new IO::Select();
$read_select->add($handle_reader_pipe);
while (1) {
my $progress = verify_child();
#####
# Manage ending
#####
if ($stop && $timeout_process > $TIMEOUT_KILL) {
writeLogFile(LOG_ESXD_ERROR, "'$whoaim' Kill child not gently.\n");
foreach (keys %child_proc) {
kill('INT', $child_proc{$_}->{'pid'});
}
$progress = 0;
}
if ($stop && !$progress) {
if ($vsphere_connected) {
eval {
$session1->logout();
};
}
print $handle_writer_pipe "STOPPED|$whoaim\n";
exit (0);
}
###
# Manage vpshere connection
###
if (defined($last_time_vsphere) && defined($last_time_check) && $last_time_vsphere < $last_time_check) {
writeLogFile(LOG_ESXD_ERROR, "'$whoaim' Deconnect\n");
$vsphere_connected = 0;
eval {
$session1->logout();
};
}
if ($vsphere_connected == 0) {
if (!connect_vsphere($vsphere_server{$whoaim}->{'url'}, $vsphere_server{$whoaim}->{'username'}, $vsphere_server{$whoaim}->{'password'})) {
writeLogFile(LOG_ESXD_INFO, "'$whoaim' Vsphere connection ok\n");
writeLogFile(LOG_ESXD_INFO, "'$whoaim' Create perf counters cache in progress\n");
if (!cache_perf_counters()) {
$last_time_vsphere = time();
$keeper_session_time = time();
$vsphere_connected = 1;
writeLogFile(LOG_ESXD_INFO, "'$whoaim' Create perf counters cache done\n");
}
}
}
###
# Manage session time
###
if (defined($keeper_session_time) && (time() - $keeper_session_time) > ($REFRESH_KEEPER_SESSION * 60)) {
my $stime;
eval {
$stime = $session1->get_service_instance()->CurrentTime();
$keeper_session_time = time();
};
if ($@) {
writeLogFile(LOG_ESXD_ERROR, "$@");
writeLogFile(LOG_ESXD_ERROR, "'$whoaim' Ask a new connection\n");
# Ask a new connection
$last_time_check = time();
} else {
writeLogFile(LOG_ESXD_INFO, "'$whoaim' Get current time = " . Data::Dumper::Dumper($stime));
}
}
my $data_element;
my @rh_set;
if ($vsphere_connected == 0) {
sleep(5);
}
if ($stop == 0) {
@rh_set = $read_select->can_read(30);
} else {
sleep(1);
$timeout_process++;
@rh_set = $read_select->can_read(0);
}
foreach my $rh (@rh_set) {
if (fileno($rh) == $fileno_reader && !$stop) {
$data_element = <$rh>;
chomp $data_element;
if ($data_element =~ /^STOP$/) {
$stop = 1;
$timeout_process = 0;
next;
}
my ($id) = split(/\|/, $data_element);
if ($vsphere_connected) {
writeLogFile(LOG_ESXD_INFO, "vpshere '$whoaim' handler asking: $data_element\n");
$child_proc{$id} = {'ctime' => time()};
my $reader;
my $writer;
pipe($reader, $writer);
$writer->autoflush(1);
$read_select->add($reader);
$child_proc{$id}->{'reading'} = \*$reader;
$child_proc{$id}->{'pid'} = fork;
if (!$child_proc{$id}->{'pid'}) {
# Child
close $reader;
open STDOUT, '>&', $writer;
# Can't print on stdout
$log_mode = 1 if ($log_mode == 0);
my ($id, $name, @args) = split /\|/, $data_element;
$global_id = $id;
$checks_descr{$name}->{'exec'}($checks_descr{$name}->{'compute'}(@args));
exit(0);
} else {
# Parent
close $writer;
}
} else {
print $handle_writer_pipe "$id|-1|Vsphere connection error.\n";
}
} else {
# Read pipe
my $output = <$rh>;
$read_select->remove($rh);
close $rh;
$output =~ s/^(.*?)\|//;
my $lid = $1;
if ($output =~ /^-1/) {
$last_time_check = $child_proc{$lid}->{'ctime'};
}
chomp $output;
print $handle_writer_pipe "$lid|$output\n";
delete $return_child{$child_proc{$lid}->{'pid'}};
delete $child_proc{$lid};
}
}
}
}
$SIG{TERM} = \&catch_zap_term;
$SIG{CHLD} = \&REAPER;
if ($log_mode == 1) {
open my $centesx_fh, '>>', $LOG;
open STDOUT, '>&', $centesx_fh;
open STDERR, '>&', $centesx_fh;
}
if ($log_mode == 2) {
openlog($0, $openlog_option, $log_facility);
}
my $server = IO::Socket::INET->new( Proto => "tcp",
LocalPort => $port,
Listen => SOMAXCONN,
Reuse => 1);
if (!$server) {
writeLogFile(LOG_ESXD_ERROR, "Can't setup server: $!\n");
exit(1);
}
##
# Create childs
##
foreach (keys %vsphere_server) {
my ($reader_pipe_one, $writer_pipe_one);
my ($reader_pipe_two, $writer_pipe_two);
$whoaim = $_;
pipe($reader_pipe_one, $writer_pipe_one);
pipe($reader_pipe_two, $writer_pipe_two);
$writer_pipe_one->autoflush(1);
$writer_pipe_two->autoflush(1);
$vsphere_server{$whoaim}->{'reader_one'} = \*$reader_pipe_one;
$vsphere_server{$whoaim}->{'writer_one'} = \*$writer_pipe_one;
$vsphere_server{$whoaim}->{'reader_two'} = \*$reader_pipe_two;
$vsphere_server{$whoaim}->{'writer_two'} = \*$writer_pipe_two;
$child_vpshere_pid = fork();
if (!$child_vpshere_pid) {
close $vsphere_server{$whoaim}->{'reader_one'};
close $vsphere_server{$whoaim}->{'writer_two'};
vsphere_handler();
exit(0);
}
$vsphere_server{$whoaim}->{'running'} = 1;
close $vsphere_server{$whoaim}->{'writer_one'};
close $vsphere_server{$whoaim}->{'reader_two'};
}
$read_select = new IO::Select();
$read_select->add($server);
foreach (keys %vsphere_server) {
$filenos{fileno(${$vsphere_server{$_}->{'reader_one'}})} = 1;
$read_select->add(${$vsphere_server{$_}->{'reader_one'}});
}
my $socket_fileno = fileno($server);
writeLogFile(LOG_ESXD_INFO, "[Server accepting clients]\n");
while (1) {
my @rh_set = $read_select->can_read(15);
if ($stop == 1) {
foreach (keys %vsphere_server) {
writeLogFile(LOG_ESXD_INFO, "Send STOP command to '$_' child.\n");
my $writer_handle = $vsphere_server{$_}->{'writer_two'};
print $writer_handle "STOP\n";
}
$stop = 2;
}
foreach my $rh (@rh_set) {
my $current_fileno = fileno($rh);
if (!$stop && $current_fileno == $socket_fileno) {
my $client;
# Connect to accept
$client = $rh->accept();
$client->autoflush(1);
$counter++;
$sockets{fileno($client)} = {"obj" => \$client, "ctime" => time(), "counter" => $counter};
$read_select->add($client);
next;
} elsif (defined($filenos{$current_fileno})) {
# Return to read
my $data_element = <$rh>;
chomp $data_element;
if ($data_element =~ /^STOPPED/) {
# We have to wait all childs
my ($name, $which_one) = split(/\|/, $data_element);
writeLogFile(LOG_ESXD_INFO, "Thread vsphere '$which_one' has stopped\n");
$vsphere_server{$which_one}->{'running'} = 0;
my $to_stop_or_not = 1;
foreach (keys %vsphere_server) {
$to_stop_or_not = 0 if ($vsphere_server{$_}->{'running'} == 1);
}
if ($to_stop_or_not == 1) {
# We quit
writeLogFile(LOG_ESXD_INFO, "Quit main process\n");
exit(0);
}
next;
}
my @results = split(/\|/, $data_element);
my ($id, $counter) = split(/\./, $results[0]);
if (!defined($sockets{$id}) || $counter != $sockets{$id}->{'counter'}) {
writeLogFile(LOG_ESXD_INFO, "Too much time to get response.\n");
next;
}
writeLogFile(LOG_ESXD_INFO, "response = $data_element\n");
$data_element =~ s/^.*?\|//;
${$sockets{$id}->{'obj'}}->send($data_element . "\n");
$read_select->remove(${$sockets{$id}->{"obj"}});
close ${$sockets{$id}->{"obj"}};
delete $sockets{$id};
} else {
# Socket
my $line = <$rh>;
if (defined($line) && $line ne "") {
chomp $line;
my ($name, $vsphere_name, @args) = split /\|/, $line;
if ($name eq 'stats') {
stats_info($rh, $current_fileno, \@args);
next;
}
if (!defined($checks_descr{$name})) {
response_client1($rh, $current_fileno, "3|Unknown method name '$name'\n");
next;
}
if ($checks_descr{$name}->{'arg'}(@args)) {
response_client1($rh, $current_fileno, "3|Params error '$name'\n");
next;
}
$vsphere_name = 'default' if (!defined($vsphere_name) || $vsphere_name eq '');
if (!defined($vsphere_server{$vsphere_name})) {
response_client1($rh, $current_fileno, "3|Vsphere name unknown\n");
next;
}
my $tmp_handle = ${$vsphere_server{$vsphere_name}->{'writer_two'}};
print $tmp_handle $current_fileno . "." . $sockets{$current_fileno}->{'counter'} . "|$name|" . join('|', @args) . "\n";
} else {
response_client1($rh, $current_fileno, "3|Need arguments\n");
}
}
}
# Verify socket
foreach (keys %sockets) {
if (time() - $sockets{$_}->{'ctime'} > $TIMEOUT) {
writeLogFile(LOG_ESXD_INFO, "Timeout returns.\n");
${$sockets{$_}->{'obj'}}->send("3|TIMEOUT\n");
$read_select->remove(${$sockets{$_}->{"obj"}});
close ${$sockets{$_}->{"obj"}};
delete $sockets{$_};
}
}
}
exit(0);
=cut

View File

@ -1,27 +1,10 @@
our $libpath = '/usr/share/centreon/lib/centreon-esxd';
our $port = 5700;
our %vsphere_server = ('default' => {'url' => 'https://XXXXXX/sdk',
'username' => 'XXXXX',
'password' => 'XXXXX'},
'testvc' => {'url' => 'https://XXXXXX/sdk',
'username' => 'XXXXX',
$centreonesxd_config = {
vsphere_server => {
'default' => {'url' => 'https://vcenter/sdk',
'username' => 'qgarnier@merethis.net',
'password' => 'XXXXXX'}
);
# Set to '1' if you use credstore file. Don't have to specify password.
our $credstore_use = 0;
our $credstore_file = "/root/.vmware/credstore/vicredentials.xml";
our $TIMEOUT_VSPHERE = 60;
our $TIMEOUT = 60;
our $TIMEOUT_KILL = 30;
our $REFRESH_KEEPER_SESSION = 15;
# Log Mode: 0 = stdout, 1 = file, 2 = syslog
our $log_mode = 1;
# Criticity: 0 = nothing, 1 = critical, 3 = info
our $log_crit = 1;
# Specify if $log_mode = 2 and CPAN Module Unix::Syslog is installed
our $log_facility;
#our $log_facility = LOG_DAEMON;
our $LOG = "/tmp/centreon_esxd.log";
}
};
1;

View File

@ -0,0 +1,536 @@
#!/usr/bin/perl -w
package centreon::script::centreonesxd;
use strict;
use VMware::VIRuntime;
use VMware::VILib;
use IO::Socket;
use File::Basename;
use IO::Select;
use POSIX ":sys_wait_h";
use Data::Dumper;
use centreon::script;
use centreon::esxd::common;
BEGIN {
$ENV{PERL_LWP_SSL_VERIFY_HOSTNAME} = 0;
}
use base qw(centreon::script);
use vars qw(%centreonesxd_config);
my %handlers = ('TERM' => {}, 'HUP' => {}, 'CHLD' => {});
sub new {
my $class = shift;
my $self = $class->SUPER::new("centreonesxd",
centreon_db_conn => 0,
centstorage_db_conn => 0,
noconfig => 1
);
bless $self, $class;
$self->add_options(
"config-extra" => \$self->{opt_extra},
);
%{$self->{centreonesxd_default_config}} =
(
credstore_use => 0,
credstore_file => '/root/.vmware/credstore/vicredentials.xml',
timeout_vsphere => 60,
timeout => 60,
timeout_kill => 30,
refresh_keeper_session => 15,
port => 5700,
vsphere_server => {
#'default' => {'url' => 'https://XXXXXX/sdk',
# 'username' => 'XXXXX',
# 'password' => 'XXXXX'},
#'testvc' => {'url' => 'https://XXXXXX/sdk',
# 'username' => 'XXXXX',
# 'password' => 'XXXXXX'}
}
);
$self->{session_id} = undef;
$self->{sockets} = {};
$self->{child_proc} = {};
$self->{return_child} = {};
$self->{vsphere_connected} = 0;
$self->{last_time_vsphere} = undef;
$self->{keeper_session_time} = undef;
$self->{last_time_check} = undef;
$self->{perfmanager_view} = undef;
$self->{perfcounter_cache} = {};
$self->{perfcounter_cache_reverse} = {};
$self->{perfcounter_refreshrate} = 20;
$self->{perfcounter_speriod} = -1;
$self->{stop} = 0;
$self->{counter_request_id} = 0;
$self->{child_vpshere_pid} = undef;
$self->{read_select} = undef;
$self->{session1} = undef;
$self->{counter} = 0;
$self->{global_id} = undef;
$self->{whoaim} = undef; # to know which vsphere to connect
$self->{filenos} = {};
$self->{module_date_parse_loaded} = 0;
return $self;
}
sub init {
my $self = shift;
$self->SUPER::init();
# redefine to avoid out when we try modules
$SIG{__DIE__} = undef;
if (!defined($self->{opt_extra})) {
$self->{opt_extra} = "/etc/centreon/centreon_esxd.pm";
}
if (-f $self->{opt_extra}) {
require $self->{opt_extra};
} else {
$self->{logger}->writeLogInfo("Can't find extra config file $self->{opt_extra}");
}
$self->{centreonesxd_config} = {%{$self->{centreonesxd_default_config}}, %centreonesxd_config};
##### credstore check #####
if (defined($self->{credstore_use}) && defined($self->{credstore_file}) &&
$self->{credstore_use} == 1 && -e "$self->{credstore_file}") {
eval 'require VMware::VICredStore';
if ($@) {
$self->{logger}->writeLogError("Could not load module VMware::VICredStore");
exit(1);
}
require VMware::VICredStore;
if (VMware::VICredStore::init(filename => $self->{credstore_file}) == 0) {
$self->{logger}->writeLogError("Credstore init failed: $@");
exit(1);
}
###
# Get password
###
foreach (keys %{$self->{centreonesxd_config}->{vsphere_server}}) {
my $lpassword = VMware::VICredStore::get_password(server => $_, username => $self->{centreonesxd_config}->{vsphere_server}->{$_}->{username});
if (!defined($lpassword)) {
$self->{logger}->writeLogError("Can't get password for couple host='" . $_ . "', username='" . $self->{centreonesxd_config}->{vsphere_server}->{$_}->{username} . "' : $@");
exit(1);
}
$self->{centreonesxd_config}->{vsphere_server}->{$_}->{password} = $lpassword;
}
}
eval 'require DateTime::Format::ISO8601';
if (!$@) {
$self->{module_date_parse_loaded} = 1;
require DateTime::Format::ISO8601;
}
$self->set_signal_handlers;
}
sub set_signal_handlers {
my $self = shift;
$SIG{TERM} = \&class_handle_TERM;
$handlers{TERM}->{$self} = sub { $self->handle_TERM() };
$SIG{HUP} = \&class_handle_HUP;
$handlers{HUP}->{$self} = sub { $self->handle_HUP() };
$SIG{CHLD} = \&class_handle_CHLD;
$handlers{CHLD}->{$self} = sub { $self->handle_CHLD() };
}
sub class_handle_TERM {
foreach (keys %{$handlers{TERM}}) {
&{$handlers{TERM}->{$_}}();
}
}
sub class_handle_HUP {
foreach (keys %{$handlers{HUP}}) {
&{$handlers{HUP}->{$_}}();
}
}
sub class_handle_CHLD {
foreach (keys %{$handlers{CHLD}}) {
&{$handlers{CHLD}->{$_}}();
}
}
sub handle_TERM {
my $self = shift;
$self->{logger}->writeLogInfo("$$ Receiving order to stop...");
$self->{stop} = 1;
}
sub handle_HUP {
my $self = shift;
$self->{logger}->writeLogInfo("$$ Receiving order to reload...");
# TODO
}
sub handle_CHLD {
my $self = shift;
my $child_pid;
while (($child_pid = waitpid(-1, &WNOHANG)) > 0) {
$self->{return_child}{$child_pid} = {'status' => 1, 'rtime' => time()};
}
$SIG{CHLD} = \&class_handle_CHLD;
}
sub print_response {
my $self = shift;
print $self->{global_id} . "|" . $_[0];
}
sub verify_child {
my $self = shift;
my $progress = 0;
my $handle_writer_pipe = ${$self->{centreonesxd_config}->{vsphere_server}->{$self->{whoaim}}->{'writer_one'}};
# Verify process
foreach (keys %{$self->{child_proc}}) {
# Check ctime
if (time() - $self->{child_proc}->{$_}->{'ctime'} > $self->{centreonesxd_config}->{timeout}) {
my $handle = ${$self->{child_proc}->{$_}->{'reading'}};
print $handle_writer_pipe "$_|-1|Timeout Process.\n";
kill('INT', $self->{child_proc}->{$_}->{'pid'});
$self->{read_select}->remove($handle);
close $handle;
delete $self->{child_proc}->{$_};
} else {
$progress++;
}
}
# Clean old hash CHILD (security)
foreach (keys %{$self->{return_child}}) {
if (time() - $self->{return_child}->{$_}->{'rtime'} > 600) {
$self->{logger}->writeLogInfo("Clean Old return_child list = " . $_);
delete $self->{return_child}->{$_};
}
}
return $progress;
}
sub vsphere_handler {
my $self = shift;
my $timeout_process;
my $handle_reader_pipe = ${$self->{centreonesxd_config}->{vsphere_server}->{$self->{whoaim}}->{'reader_two'}};
my $fileno_reader = fileno($handle_reader_pipe);
my $handle_writer_pipe = ${$self->{centreonesxd_config}->{vsphere_server}->{$self->{whoaim}}->{'writer_one'}};
$self->{read_select} = new IO::Select();
$self->{read_select}->add($handle_reader_pipe);
while (1) {
my $progress = $self->verify_child();
#####
# Manage ending
#####
if ($self->{stop} && $timeout_process > $self->{centreonesxd_config}->{timeout_kill}) {
$self->{logger}->writeLogError("'" . $self->{whoaim} . "' Kill child not gently.");
foreach (keys %{$self->{child_proc}}) {
kill('INT', $self->{child_proc}->{$_}->{'pid'});
}
$progress = 0;
}
if ($self->{stop} && !$progress) {
if ($self->{vsphere_connected}) {
eval {
$self->{session1}->logout();
};
}
print $handle_writer_pipe "STOPPED|$self->{whoaim}\n";
exit (0);
}
###
# Manage vpshere connection
###
if (defined($self->{last_time_vsphere}) && defined($self->{last_time_check}) && $self->{last_time_vsphere} < $self->{last_time_check}) {
$self->{logger}->writeLogError("'" . $self->{whoaim} . "' Disconnect");
$self->{vsphere_connected} = 0;
eval {
$self->{session1}->logout();
};
}
if ($self->{vsphere_connected} == 0) {
if (!centreon::esxd::common::connect_vsphere($self->{logger},
$self->{whoaim},
$self->{centreonesxd_config}->{timeout_vsphere},
\$self->{session1},
$self->{centreonesxd_config}->{vsphere_server}->{$self->{whoaim}}->{'url'},
$self->{centreonesxd_config}->{vsphere_server}->{$self->{whoaim}}->{'username'},
$self->{centreonesxd_config}->{vsphere_server}->{$self->{whoaim}}->{'password'})) {
$self->{logger}->writeLogInfo("'" . $self->{whoaim} . "' Vsphere connection ok");
$self->{logger}->writeLogInfo("'" . $self->{whoaim} . "' Create perf counters cache in progress");
if (!centreon::esxd::common::cache_perf_counters($self)) {
$self->{last_time_vsphere} = time();
$self->{keeper_session_time} = time();
$self->{vsphere_connected} = 1;
$self->{logger}->writeLogInfo("'" . $self->{whoaim} . "' Create perf counters cache done");
}
}
}
###
# Manage session time
###
if (defined($self->{keeper_session_time}) && (time() - $self->{keeper_session_time}) > ($self->{centreonesxd_config}->{refresh_keeper_session} * 60)) {
my $stime;
eval {
$stime = $self->{session1}->get_service_instance()->CurrentTime();
$self->{keeper_session_time} = time();
};
if ($@) {
$self->{logger}->writeLogError("$@");
$self->{logger}->writeLogError("'" . $self->{whoaim} . "' Ask a new connection");
# Ask a new connection
$self->{last_time_check} = time();
} else {
$self->{logger}->writeLogInfo("'" . $self->{whoaim} . "' Get current time = " . Data::Dumper::Dumper($stime));
}
}
my $data_element;
my @rh_set;
if ($self->{vsphere_connected} == 0) {
sleep(5);
}
if ($self->{stop} == 0) {
@rh_set = $self->{read_select}->can_read(30);
} else {
sleep(1);
$timeout_process++;
@rh_set = $self->{read_select}->can_read(0);
}
foreach my $rh (@rh_set) {
if (fileno($rh) == $fileno_reader && !$self->{stop}) {
$data_element = <$rh>;
chomp $data_element;
if ($data_element =~ /^STOP$/) {
$self->{stop} = 1;
$timeout_process = 0;
next;
}
my ($id) = split(/\|/, $data_element);
if ($self->{vsphere_connected}) {
$self->{logger}->writeLogInfo("vpshere '" . $self->{whoaim} . "' handler asking: $data_element");
$self->{child_proc}->{$id} = {'ctime' => time()};
my $reader;
my $writer;
pipe($reader, $writer);
$writer->autoflush(1);
$self->{read_select}->add($reader);
$self->{child_proc}->{$id}->{'reading'} = \*$reader;
$self->{child_proc}->{$id}->{'pid'} = fork;
if (!$self->{child_proc}->{$id}->{'pid'}) {
# Child
close $reader;
open STDOUT, '>&', $writer;
# Can't print on stdout
$self->{logger}->{log_mode} = 1 if ($self->{logger}->{log_mode} == 0);
my ($id, $name, @args) = split /\|/, $data_element;
$self->{global_id} = $id;
#####$checks_descr{$name}->{'exec'}($checks_descr{$name}->{'compute'}(@args));
exit(0);
} else {
# Parent
close $writer;
}
} else {
print $handle_writer_pipe "$id|-1|Vsphere connection error.\n";
}
} else {
# Read pipe
my $output = <$rh>;
$self->{read_select}->remove($rh);
close $rh;
$output =~ s/^(.*?)\|//;
my $lid = $1;
if ($output =~ /^-1/) {
$self->{last_time_check} = $self->{child_proc}->{$lid}->{'ctime'};
}
chomp $output;
print $handle_writer_pipe "$lid|$output\n";
delete $self->{return_child}->{$self->{child_proc}->{$lid}->{'pid'}};
delete $self->{child_proc}->{$lid};
}
}
}
}
sub run {
my $self = shift;
$self->SUPER::run();
$self->{logger}->redirect_output();
$self->{logger}->writeLogDebug("centreonesxd launched....");
$self->{logger}->writeLogDebug("PID: $$");
my $server = IO::Socket::INET->new( Proto => "tcp",
LocalPort => $self->{centreonesxd_config}->{port},
Listen => SOMAXCONN,
Reuse => 1);
if (!$server) {
$self->{logger}->writeLogError("Can't setup server: $!");
exit(1);
}
##
# Create childs
##
foreach (keys %{$self->{centreonesxd_config}->{vsphere_server}}) {
my ($reader_pipe_one, $writer_pipe_one);
my ($reader_pipe_two, $writer_pipe_two);
$self->{whoaim} = $_;
pipe($reader_pipe_one, $writer_pipe_one);
pipe($reader_pipe_two, $writer_pipe_two);
$writer_pipe_one->autoflush(1);
$writer_pipe_two->autoflush(1);
$self->{centreonesxd_config}->{vsphere_server}->{$self->{whoaim}}->{'reader_one'} = \*$reader_pipe_one;
$self->{centreonesxd_config}->{vsphere_server}->{$self->{whoaim}}->{'writer_one'} = \*$writer_pipe_one;
$self->{centreonesxd_config}->{vsphere_server}->{$self->{whoaim}}->{'reader_two'} = \*$reader_pipe_two;
$self->{centreonesxd_config}->{vsphere_server}->{$self->{whoaim}}->{'writer_two'} = \*$writer_pipe_two;
$self->{child_vpshere_pid} = fork();
if (!$self->{child_vpshere_pid}) {
close $self->{centreonesxd_config}->{vsphere_server}->{$self->{whoaim}}->{'reader_one'};
close $self->{centreonesxd_config}->{vsphere_server}->{$self->{whoaim}}->{'writer_two'};
$self->vsphere_handler();
exit(0);
}
$self->{centreonesxd_config}->{vsphere_server}->{$self->{whoaim}}->{'running'} = 1;
close $self->{centreonesxd_config}->{vsphere_server}->{$self->{whoaim}}->{'writer_one'};
close $self->{centreonesxd_config}->{vsphere_server}->{$self->{whoaim}}->{'reader_two'};
}
$self->{read_select} = new IO::Select();
$self->{read_select}->add($server);
foreach (keys %{$self->{centreonesxd_config}->{vsphere_server}}) {
$self->{filenos}->{fileno(${$self->{centreonesxd_config}->{vsphere_server}->{$_}->{'reader_one'}})} = 1;
$self->{read_select}->add(${$self->{centreonesxd_config}->{vsphere_server}->{$_}->{'reader_one'}});
}
my $socket_fileno = fileno($server);
$self->{logger}->writeLogInfo("[Server accepting clients]");
while (1) {
my @rh_set = $self->{read_select}->can_read(15);
if ($self->{stop} == 1) {
foreach (keys %{$self->{centreonesxd_config}->{vsphere_server}}) {
$self->{logger}->writeLogInfo("Send STOP command to '$_' child.");
my $writer_handle = $self->{centreonesxd_config}->{vsphere_server}->{$_}->{'writer_two'};
print $writer_handle "STOP\n";
}
$self->{stop} = 2;
}
foreach my $rh (@rh_set) {
my $current_fileno = fileno($rh);
if (!$self->{stop} && $current_fileno == $socket_fileno) {
my $client;
# Connect to accept
$client = $rh->accept();
$client->autoflush(1);
$self->{counter}++;
$self->{sockets}->{fileno($client)} = {"obj" => \$client, "ctime" => time(), "counter" => $self->{counter}};
$self->{read_select}->add($client);
next;
} elsif (defined($self->{filenos}->{$current_fileno})) {
# Return to read
my $data_element = <$rh>;
chomp $data_element;
if ($data_element =~ /^STOPPED/) {
# We have to wait all childs
my ($name, $which_one) = split(/\|/, $data_element);
$self->{logger}->writeLogInfo("Thread vsphere '$which_one' has stopped");
$self->{centreonesxd_config}->{vsphere_server}->{$which_one}->{'running'} = 0;
my $to_stop_or_not = 1;
foreach (keys %{$self->{centreonesxd_config}->{vsphere_server}}) {
$to_stop_or_not = 0 if ($self->{centreonesxd_config}->{vsphere_server}->{$_}->{'running'} == 1);
}
if ($to_stop_or_not == 1) {
# We quit
$self->{logger}->writeLogInfo("Quit main process");
exit(0);
}
next;
}
my @results = split(/\|/, $data_element);
my ($id, $counter) = split(/\./, $results[0]);
if (!defined($self->{sockets}->{$id}) || $self->{counter} != $self->{sockets}->{$id}->{'counter'}) {
$self->{logger}->writeLogInfo("Too much time to get response.");
next;
}
$self->{logger}->writeLogInfo("response = $data_element");
$data_element =~ s/^.*?\|//;
${$self->{sockets}->{$id}->{'obj'}}->send($data_element . "\n");
$self->{read_select}->remove(${$self->{sockets}->{$id}->{"obj"}});
close ${$self->{sockets}->{$id}->{"obj"}};
delete $self->{sockets}->{$id};
} else {
# Socket
my $line = <$rh>;
if (defined($line) && $line ne "") {
chomp $line;
my ($name, $vsphere_name, @args) = split /\|/, $line;
if ($name eq 'stats') {
centreon::esxd::common::stats_info($rh, $current_fileno, \@args);
next;
}
#if (!defined($checks_descr{$name})) {
# centreon::esxd::common::response_client1($self, $rh, $current_fileno, "3|Unknown method name '$name'\n");
# next;
#}
#if ($checks_descr{$name}->{'arg'}(@args)) {
# centreon::esxd::common::response_client1($self, $rh, $current_fileno, "3|Params error '$name'\n");
# next;
#}
$vsphere_name = 'default' if (!defined($vsphere_name) || $vsphere_name eq '');
if (!defined($self->{centreonesxd_config}->{vsphere_server}->{$vsphere_name})) {
centreon::esxd::common::response_client1($self, $rh, $current_fileno, "3|Vsphere name unknown\n");
next;
}
my $tmp_handle = ${$self->{centreonesxd_config}->{vsphere_server}->{$vsphere_name}->{'writer_two'}};
print $tmp_handle $current_fileno . "." . $self->{sockets}->{$current_fileno}->{'counter'} . "|$name|" . join('|', @args) . "\n";
} else {
centreon::esxd::common::response_client1($self, $rh, $current_fileno, "3|Need arguments\n");
}
}
}
# Verify socket
foreach (keys %{$self->{sockets}}) {
if (time() - $self->{sockets}->{$_}->{'ctime'} > $self->{centreonesxd_config}->{timeout}) {
$self->{logger}->writeLogInfo("Timeout returns.");
${$self->{sockets}->{$_}->{'obj'}}->send("3|TIMEOUT\n");
$self->{read_select}->remove(${$self->{sockets}->{$_}->{"obj"}});
close ${$self->{sockets}->{$_}->{"obj"}};
delete $self->{sockets}->{$_};
}
}
}
}
1;
__END__

View File

@ -0,0 +1,252 @@
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 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 VirtualCentre server") if($@ =~ /TIMEOUT/);
$logger->writeLogError("'$whoaim' You need to upgrade HTTP::Message!") if($@ =~ /HTTP::Message/);
$logger->writeLogError("'$whoaim' Login to VirtualCentre 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 ($@) {
$obj_esxd->{logger}->writeLogError("'" . $obj_esxd->{whoaim} . "' $@");
my $lerror = $@;
$lerror =~ s/\n/ /g;
$obj_esxd->print_response("-1|Error: " . $lerror . "\n");
return undef;
}
return $results;
}
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.");
}
}
return \@filtered_list;
}
sub generic_performance_values_historic {
my ($obj_esxd, $view, $perfs, $interval) = @_;
my $counter = 0;
my %results;
eval {
my @perf_metric_ids = get_perf_metric_ids($obj_esxd, $perfs);
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]);
if ($interval == 20) {
$perf_query_spec = PerfQuerySpec->new(entity => $view,
metricId => @perf_metric_ids,
format => 'normal',
intervalId => 20,
startTime => $startTime,
endTime => $endTime,
maxSample => 1);
} else {
$perf_query_spec = PerfQuerySpec->new(entity => $view,
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);
foreach (@{$$perfdata[0]->value}) {
$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 ($@) {
$obj_esxd->{logger}->writeLogError("'" . $obj_esxd->{whoaim} . "' $@");
my $lerror = $@;
$lerror =~ s/\n/ /g;
$obj_esxd->print_response("-1|Error: " . Data::Dumper::Dumper($lerror) . "\n");
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 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] 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;

View File

@ -1,243 +0,0 @@
sub writeLogFile($$) {
if (($log_crit & $_[0]) == 0) {
return ;
}
if ($log_mode == 0) {
print $_[1];
} elsif ($log_mode == 1) {
my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time());
open (LOG, ">> ".$LOG) || print "can't write $LOG: $!";
printf LOG "%04d-%02d-%02d %02d:%02d:%02d - %s", $year+1900, $mon+1, $mday, $hour, $min, $sec, $_[1];
close LOG;
} elsif ($log_mode == 2) {
syslog($syslog_err_priority, $_[1]) if ($_[0] == LOG_ESXD_ERROR);
syslog($syslog_info_priority, $_[1]) if ($_[0] == LOG_ESXD_INFO);
}
}
sub response_client1 {
my ($rh, $current_fileno, $msg) = @_;
$rh->send($msg);
delete $sockets{$current_fileno};
$read_select->remove($rh);
close $rh;
}
sub connect_vsphere {
my ($service_url, $username, $password) = @_;
writeLogFile(LOG_ESXD_INFO, "'$whoaim' Vsphere connection in progress\n");
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($@) {
writeLogFile(LOG_ESXD_ERROR, "'$whoaim' No response from VirtualCentre server\n") if($@ =~ /TIMEOUT/);
writeLogFile(LOG_ESXD_ERROR, "'$whoaim' You need to upgrade HTTP::Message!\n") if($@ =~ /HTTP::Message/);
writeLogFile(LOG_ESXD_ERROR, "'$whoaim' Login to VirtualCentre server failed: $@");
return 1;
}
# eval {
# $session_id = Vim::get_session_id();
# };
# if($@) {
# writeLogFile("Can't get session_id: $@\n");
# return 1;
# }
return 0;
}
sub print_response {
print "$global_id|" . $_[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 $results;
eval {
$results = $session1->get_views(mo_ref_array => $_[0], properties => $_[1]);
};
if ($@) {
writeLogFile(LOG_ESXD_ERROR, "'$whoaim' $@");
my $lerror = $@;
$lerror =~ s/\n/ /g;
print_response("-1|Error: " . $lerror . "\n");
return undef;
}
return $results;
}
sub get_perf_metric_ids {
my $perf_names = $_[0];
my @filtered_list;
foreach (@$perf_names) {
if (defined($perfcounter_cache{$_->{'label'}})) {
foreach my $instance (@{$_->{'instances'}}) {
my $metric = PerfMetricId->new(counterId => $perfcounter_cache{$_->{'label'}}{'key'},
instance => $instance);
push @filtered_list, $metric;
}
} else {
writeLogFile(LOG_ESXD_ERROR, "Metric '" . $_->{'label'} . "' unavailable.\n");
}
}
return \@filtered_list;
}
sub generic_performance_values_historic {
my ($view, $perfs, $interval) = @_;
my $counter = 0;
my %results;
eval {
my @perf_metric_ids = get_perf_metric_ids($perfs);
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]);
if ($interval == 20) {
$perf_query_spec = PerfQuerySpec->new(entity => $view,
metricId => @perf_metric_ids,
format => 'normal',
intervalId => 20,
startTime => $startTime,
endTime => $endTime,
maxSample => 1);
} else {
$perf_query_spec = PerfQuerySpec->new(entity => $view,
metricId => @perf_metric_ids,
format => 'normal',
intervalId => $interval,
startTime => $startTime,
endTime => $endTime
);
#maxSample => 1);
}
my $perfdata = $perfmanager_view->QueryPerf(querySpec => $perf_query_spec);
foreach (@{$$perfdata[0]->value}) {
$results{$_->id->counterId . ":" . (defined($_->id->instance) ? $_->id->instance : "")} = $_->value;
}
};
if ($@) {
writeLogFile(LOG_ESXD_ERROR, "'$whoaim' $@");
return undef;
}
return \%results;
}
sub cache_perf_counters {
eval {
$perfmanager_view = $session1->get_view(mo_ref => $session1->get_service_content()->perfManager, properties => ['perfCounter', 'historicalInterval']);
foreach (@{$perfmanager_view->perfCounter}) {
my $label = $_->groupInfo->key . "." . $_->nameInfo->key . "." . $_->rollupType->val;
$perfcounter_cache{$label} = {'key' => $_->key, 'unitkey' => $_->unitInfo->key};
$perfcounter_cache_reverse{$_->key} = $label;
}
my $historical_intervals = $perfmanager_view->historicalInterval;
foreach (@$historical_intervals) {
if ($perfcounter_speriod == -1 || $perfcounter_speriod > $_->samplingPeriod) {
$perfcounter_speriod = $_->samplingPeriod;
}
}
# Put refresh = 20 (for ESX check)
if ($perfcounter_speriod == -1) {
$perfcounter_speriod = 20;
}
};
if ($@) {
writeLogFile(LOG_ESXD_ERROR, "'$whoaim' $@");
return 1;
}
return 0;
}
sub get_entities_host {
my ($view_type, $filters, $properties) = @_;
my $entity_views;
eval {
$entity_views = $session1->find_entity_views(view_type => $view_type, properties => $properties, filter => $filters);
};
if ($@) {
writeLogFile(LOG_ESXD_ERROR, "'$whoaim' $@");
eval {
$entity_views = $session1->find_entity_views(view_type => $view_type, properties => $properties, filter => $filters);
};
if ($@) {
writeLogFile(LOG_ESXD_ERROR, "'$whoaim' $@");
my $lerror = $@;
$lerror =~ s/\n/ /g;
print_response("-1|Error: " . Data::Dumper::Dumper($lerror) . "\n");
return undef;
}
}
if (!@$entity_views) {
my $status |= $MYERRORS_MASK{'UNKNOWN'};
print_response($ERRORS{$MYERRORS{$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 stats_info {
my ($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(%sockets));
$output = "'$num_connection' total client connections | connection=$num_connection;$$args[0];$$args[1] requests=$counter";
if ($$args[1] ne '' and $num_connection >= $$args[1]) {
$status |= $MYERRORS_MASK{'CRITICAL'};
} elsif ($$args[0] ne '' and $num_connection >= $$args[0]) {
$status |= $MYERRORS_MASK{'WARNING'};
}
response_client1($rh, $current_fileno, $ERRORS{$MYERRORS{$status}}. "|$output\n");
}
1;

View File

@ -1,6 +0,0 @@
$openlog_option = LOG_PID;
$syslog_err_priority = LOG_ERR;
$syslog_info_priority = LOG_INFO;
1;