From 83880bce85a72d4a0220e81f4b874d6991e21647 Mon Sep 17 00:00:00 2001 From: Quentin Garnier Date: Fri, 28 Jun 2013 16:04:49 +0000 Subject: [PATCH] Ref #5490 : in progress git-svn-id: http://svn.merethis.net/centreon-esxd/trunk@57 a5eaa968-4c79-4d68-970d-af6011b5b055 --- connectors/vmware/centreon_esxd | 507 +--------------------- connectors/vmware/centreon_esxd-conf.pm | 29 +- connectors/vmware/centreonesxd.pm | 536 ++++++++++++++++++++++++ connectors/vmware/lib/common.pm | 252 +++++++++++ connectors/vmware/lib/esxd-common.pm | 243 ----------- connectors/vmware/lib/esxd-syslog.pm | 6 - 6 files changed, 814 insertions(+), 759 deletions(-) create mode 100644 connectors/vmware/centreonesxd.pm create mode 100644 connectors/vmware/lib/common.pm delete mode 100644 connectors/vmware/lib/esxd-common.pm delete mode 100644 connectors/vmware/lib/esxd-syslog.pm diff --git a/connectors/vmware/centreon_esxd b/connectors/vmware/centreon_esxd index 5492a2bde..c63f3f893 100644 --- a/connectors/vmware/centreon_esxd +++ b/connectors/vmware/centreon_esxd @@ -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 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 diff --git a/connectors/vmware/centreon_esxd-conf.pm b/connectors/vmware/centreon_esxd-conf.pm index 033771b84..f8c0d57da 100644 --- a/connectors/vmware/centreon_esxd-conf.pm +++ b/connectors/vmware/centreon_esxd-conf.pm @@ -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; diff --git a/connectors/vmware/centreonesxd.pm b/connectors/vmware/centreonesxd.pm new file mode 100644 index 000000000..021abf2da --- /dev/null +++ b/connectors/vmware/centreonesxd.pm @@ -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__ \ No newline at end of file diff --git a/connectors/vmware/lib/common.pm b/connectors/vmware/lib/common.pm new file mode 100644 index 000000000..016446fc7 --- /dev/null +++ b/connectors/vmware/lib/common.pm @@ -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; diff --git a/connectors/vmware/lib/esxd-common.pm b/connectors/vmware/lib/esxd-common.pm deleted file mode 100644 index 9f8e19a8d..000000000 --- a/connectors/vmware/lib/esxd-common.pm +++ /dev/null @@ -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; diff --git a/connectors/vmware/lib/esxd-syslog.pm b/connectors/vmware/lib/esxd-syslog.pm deleted file mode 100644 index 29960b217..000000000 --- a/connectors/vmware/lib/esxd-syslog.pm +++ /dev/null @@ -1,6 +0,0 @@ - -$openlog_option = LOG_PID; -$syslog_err_priority = LOG_ERR; -$syslog_info_priority = LOG_INFO; - -1;